summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/relayd/http.h8
-rw-r--r--usr.sbin/relayd/relay.c10
-rw-r--r--usr.sbin/relayd/relay_http.c57
-rw-r--r--usr.sbin/relayd/relayd.c44
-rw-r--r--usr.sbin/relayd/relayd.h4
5 files changed, 65 insertions, 58 deletions
diff --git a/usr.sbin/relayd/http.h b/usr.sbin/relayd/http.h
index 0fae818c87c..e7688165275 100644
--- a/usr.sbin/relayd/http.h
+++ b/usr.sbin/relayd/http.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: http.h,v 1.10 2019/03/04 21:25:03 benno Exp $ */
+/* $OpenBSD: http.h,v 1.11 2019/05/08 23:22:19 reyk Exp $ */
/*
* Copyright (c) 2012 - 2015 Reyk Floeter <reyk@openbsd.org>
@@ -251,10 +251,4 @@ struct http_descriptor {
struct kvtree http_headers;
};
-struct relay_http_priv {
-#define HTTP_CONNECTION_UPGRADE 0x01
-#define HTTP_UPGRADE_WEBSOCKET 0x02
- int http_upgrade_req;
-};
-
#endif /* HTTP_H */
diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c
index 4e8f3f24f78..41bb8936caf 100644
--- a/usr.sbin/relayd/relay.c
+++ b/usr.sbin/relayd/relay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relay.c,v 1.242 2019/03/04 21:25:03 benno Exp $ */
+/* $OpenBSD: relay.c,v 1.243 2019/05/08 23:22:19 reyk Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -1410,13 +1410,7 @@ relay_session(struct rsession *con)
return;
}
- if (rlay->rl_proto->type == RELAY_PROTO_HTTP) {
- if (relay_http_priv_init(con) == -1) {
- relay_close(con,
- "failed to allocate http session data", 1);
- return;
- }
- } else {
+ if (rlay->rl_proto->type != RELAY_PROTO_HTTP) {
if (rlay->rl_conf.fwdmode == FWD_TRANS)
relay_bindanyreq(con, 0, IPPROTO_TCP);
else if (relay_connect(con) == -1) {
diff --git a/usr.sbin/relayd/relay_http.c b/usr.sbin/relayd/relay_http.c
index 9b83eb5ba8a..f31c7e6e183 100644
--- a/usr.sbin/relayd/relay_http.c
+++ b/usr.sbin/relayd/relay_http.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relay_http.c,v 1.72 2019/03/04 21:25:03 benno Exp $ */
+/* $OpenBSD: relay_http.c,v 1.73 2019/05/08 23:22:19 reyk Exp $ */
/*
* Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org>
@@ -110,17 +110,6 @@ relay_http_init(struct relay *rlay)
}
int
-relay_http_priv_init(struct rsession *con)
-{
- struct relay_http_priv *p;
- if ((p = calloc(1, sizeof(struct relay_http_priv))) == NULL)
- return (-1);
-
- con->se_priv = p;
- return (0);
-}
-
-int
relay_httpdesc_init(struct ctl_relay_event *cre)
{
struct http_descriptor *desc;
@@ -163,13 +152,13 @@ relay_read_http(struct bufferevent *bev, void *arg)
struct relay *rlay = con->se_relay;
struct protocol *proto = rlay->rl_proto;
struct evbuffer *src = EVBUFFER_INPUT(bev);
- struct relay_http_priv *priv = con->se_priv;
char *line = NULL, *key, *value;
char *urlproto, *host, *path;
int action, unique, ret;
const char *errstr;
size_t size, linelen;
struct kv *hdr = NULL;
+ struct kv *upgrade = NULL, *upgrade_ws = NULL;
getmonotime(&con->se_tv_last);
cre->timedout = 0;
@@ -398,17 +387,6 @@ relay_read_http(struct bufferevent *bev, void *arg)
unique = 0;
if (cre->line != 1) {
- if (cre->dir == RELAY_DIR_REQUEST) {
- if (strcasecmp("Connection", key) == 0 &&
- strcasecmp("Upgrade", value) == 0)
- priv->http_upgrade_req |=
- HTTP_CONNECTION_UPGRADE;
- if (strcasecmp("Upgrade", key) == 0 &&
- strcasecmp("websocket", value) == 0)
- priv->http_upgrade_req |=
- HTTP_UPGRADE_WEBSOCKET;
- }
-
if ((hdr = kv_add(&desc->http_headers, key,
value, unique)) == NULL) {
relay_abort_http(con, 400,
@@ -445,37 +423,34 @@ relay_read_http(struct bufferevent *bev, void *arg)
return;
}
- /* HTTP 101 Switching Protocols */
- if (cre->dir == RELAY_DIR_REQUEST) {
- if ((priv->http_upgrade_req & HTTP_UPGRADE_WEBSOCKET) &&
- !(proto->httpflags & HTTPFLAG_WEBSOCKETS)) {
+ /*
+ * HTTP 101 Switching Protocols
+ */
+ upgrade = kv_find_value(&desc->http_headers,
+ "Connection", "upgrade", ",");
+ upgrade_ws = kv_find_value(&desc->http_headers,
+ "Upgrade", "websocket", ",");
+ if (cre->dir == RELAY_DIR_REQUEST && upgrade_ws != NULL) {
+ if ((proto->httpflags & HTTPFLAG_WEBSOCKETS) == 0) {
relay_abort_http(con, 403,
"Websocket Forbidden", 0);
return;
- }
- if ((priv->http_upgrade_req & HTTP_UPGRADE_WEBSOCKET) &&
- !(priv->http_upgrade_req & HTTP_CONNECTION_UPGRADE))
- {
+ } else if (upgrade == NULL) {
relay_abort_http(con, 400,
"Bad Websocket Request", 0);
return;
- }
- if ((priv->http_upgrade_req & HTTP_UPGRADE_WEBSOCKET) &&
- (desc->http_method != HTTP_METHOD_GET)) {
+ } else if (desc->http_method != HTTP_METHOD_GET) {
relay_abort_http(con, 405,
"Websocket Method Not Allowed", 0);
return;
}
} else if (cre->dir == RELAY_DIR_RESPONSE &&
desc->http_status == 101) {
- if (((priv->http_upgrade_req &
- (HTTP_CONNECTION_UPGRADE | HTTP_UPGRADE_WEBSOCKET))
- ==
- (HTTP_CONNECTION_UPGRADE | HTTP_UPGRADE_WEBSOCKET))
- && proto->httpflags & HTTPFLAG_WEBSOCKETS) {
+ if (upgrade_ws != NULL && upgrade != NULL &&
+ (proto->httpflags & HTTPFLAG_WEBSOCKETS)) {
cre->dst->toread = TOREAD_UNLIMITED;
cre->dst->bev->readcb = relay_read;
- } else {
+ } else {
relay_abort_http(con, 502,
"Bad Websocket Gateway", 0);
return;
diff --git a/usr.sbin/relayd/relayd.c b/usr.sbin/relayd/relayd.c
index 9e80bed2d09..6cbb734757f 100644
--- a/usr.sbin/relayd/relayd.c
+++ b/usr.sbin/relayd/relayd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.c,v 1.175 2019/04/24 19:13:49 mestre Exp $ */
+/* $OpenBSD: relayd.c,v 1.176 2019/05/08 23:22:19 reyk Exp $ */
/*
* Copyright (c) 2007 - 2016 Reyk Floeter <reyk@openbsd.org>
@@ -812,6 +812,48 @@ kv_find(struct kvtree *keys, struct kv *kv)
return (match);
}
+struct kv *
+kv_find_value(struct kvtree *keys, char *key, const char *value,
+ const char *delim)
+{
+ struct kv *match, kv;
+ char *val = NULL, *next, *ptr;
+ size_t len;
+
+ kv.kv_key = key;
+ if ((match = RB_FIND(kvtree, keys, &kv)) == NULL)
+ return (NULL);
+
+ if (match->kv_value == NULL)
+ return (NULL);
+
+ if (delim == NULL) {
+ if (strcasecmp(match->kv_value, value) == 0)
+ goto done;
+ } else {
+ if ((val = strdup(match->kv_value)) == NULL)
+ return (NULL);
+ for (next = ptr = val; ptr != NULL;
+ ptr = strsep(&next, delim)) {
+ /* strip whitespace */
+ ptr += strspn(ptr, " \t");
+ len = strcspn(ptr, " \t");
+ if (strncasecmp(ptr, value, len) == 0)
+ goto done;
+ }
+ }
+
+ /* not matched */
+ match = NULL;
+ done:
+#ifdef DEBUG
+ if (match != NULL)
+ DPRINTF("%s: matched %s: %s", __func__, key, value);
+#endif
+ free(val);
+ return (match);
+}
+
int
kv_cmp(struct kv *a, struct kv *b)
{
diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h
index b05b2ad7603..65ffe714aba 100644
--- a/usr.sbin/relayd/relayd.h
+++ b/usr.sbin/relayd/relayd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.h,v 1.252 2019/03/04 21:25:03 benno Exp $ */
+/* $OpenBSD: relayd.h,v 1.253 2019/05/08 23:22:19 reyk Exp $ */
/*
* Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org>
@@ -1324,6 +1324,8 @@ void relay_log(struct rsession *, char *);
int kv_log(struct rsession *, struct kv *, u_int16_t,
enum direction);
struct kv *kv_find(struct kvtree *, struct kv *);
+struct kv *kv_find_value(struct kvtree *, char *, const char *,
+ const char *);
int kv_cmp(struct kv *, struct kv *);
int rule_add(struct protocol *, struct relay_rule *, const char
*);