summaryrefslogtreecommitdiff
path: root/usr.sbin/relayd
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2007-03-06 19:26:47 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2007-03-06 19:26:47 +0000
commit41830b96c1b5144beab9858f74e2881634f915d2 (patch)
tree5abf219d5b6d1539f2f63be3d6281e9991a678dc /usr.sbin/relayd
parent0cb27c3402077630224ff3f8ea8968e2e2c8f985 (diff)
add support for handling simple HTTP cookies (no per-path/domain
cookies yet), for example: cookie hash "JSESSIONID" tested by some people ok pyr@
Diffstat (limited to 'usr.sbin/relayd')
-rw-r--r--usr.sbin/relayd/parse.y13
-rw-r--r--usr.sbin/relayd/relay.c75
-rw-r--r--usr.sbin/relayd/relayd.conf.59
3 files changed, 80 insertions, 17 deletions
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y
index 8fa77d94e08..18cfa36c18c 100644
--- a/usr.sbin/relayd/parse.y
+++ b/usr.sbin/relayd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.33 2007/02/27 13:38:58 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.34 2007/03/06 19:26:46 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -107,7 +107,7 @@ typedef struct {
%token CHECK TCP ICMP EXTERNAL REQUEST RESPONSE
%token TIMEOUT CODE DIGEST PORT TAG INTERFACE
%token VIRTUAL INTERVAL DISABLE STICKYADDR BACKLOG
-%token SEND EXPECT NOTHING SSL LOADBALANCE ROUNDROBIN CIPHERS
+%token SEND EXPECT NOTHING SSL LOADBALANCE ROUNDROBIN CIPHERS COOKIE
%token RELAY LISTEN ON FORWARD TO NAT LOOKUP PREFORK NO MARK MARKED
%token PROTO SESSION CACHE APPEND CHANGE REMOVE FROM FILTER HASH HEADER
%token LOG UPDATES ALL DEMOTE NODELAY SACK SOCKET BUFFER URL RETRY
@@ -606,15 +606,18 @@ protoptsl : SSL sslflags
}
RB_INSERT(proto_tree, tree, pn);
- if (node.type != NODE_TYPE_HEADER) {
+ if (node.type == NODE_TYPE_COOKIE)
+ pk.key = "Cookie";
+ else
pk.key = "GET";
+ if (node.type != NODE_TYPE_HEADER) {
pk.type = NODE_TYPE_HEADER;
pn = RB_FIND(proto_tree, tree, &pk);
if (pn == NULL) {
if ((pn = (struct protonode *)
calloc(1, sizeof(*pn))) == NULL)
fatal("out of memory");
- pn->key = strdup("GET");
+ pn->key = strdup(pk.key);
if (pn->key == NULL)
fatal("out of memory");
pn->value = NULL;
@@ -783,6 +786,7 @@ marked : /* empty */
nodetype : HEADER { node.type = NODE_TYPE_HEADER; }
| URL { node.type = NODE_TYPE_URL; }
+ | COOKIE { node.type = NODE_TYPE_COOKIE; }
;
sslcache : number { $$ = $1; }
@@ -1065,6 +1069,7 @@ lookup(char *s)
{ "check", CHECK },
{ "ciphers", CIPHERS },
{ "code", CODE },
+ { "cookie", COOKIE },
{ "demote", DEMOTE },
{ "digest", DIGEST },
{ "disable", DISABLE },
diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c
index 30d8f0c5b0f..dc60fb7a2f2 100644
--- a/usr.sbin/relayd/relay.c
+++ b/usr.sbin/relayd/relay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: relay.c,v 1.16 2007/03/05 11:44:50 reyk Exp $ */
+/* $OpenBSD: relay.c,v 1.17 2007/03/06 19:26:46 reyk Exp $ */
/*
* Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org>
@@ -1020,7 +1020,7 @@ relay_read_http(struct bufferevent *bev, void *arg)
struct protocol *proto = rlay->proto;
struct evbuffer *src = EVBUFFER_INPUT(bev);
struct protonode *pn, pk, *pnv, pkv;
- char *line, buf[READ_BUF_SIZE], *ptr, *url, *method;
+ char *line, buf[READ_BUF_SIZE], *ptr, *val, *method;
int header = 0, ret;
const char *errstr;
size_t size;
@@ -1125,15 +1125,19 @@ relay_read_http(struct bufferevent *bev, void *arg)
if ((pn = RB_FIND(proto_tree, cre->tree, &pk)) == NULL)
goto next;
- /* Decode the URL */
- if (pn->flags & PNFLAG_LOOKUP_URL &&
- cre->dir == RELAY_DIR_REQUEST) {
- url = strdup(pk.value);
- if (url == NULL)
+ if (cre->dir == RELAY_DIR_RESPONSE)
+ goto handle;
+
+ if (pn->flags & PNFLAG_LOOKUP_URL) {
+ /*
+ * Decode the URL
+ */
+ val = strdup(pk.value);
+ if (val == NULL)
goto next;
- if ((ptr = strchr(url, '?')) == NULL ||
+ if ((ptr = strchr(val, '?')) == NULL ||
strlen(ptr) < 2) {
- free(url);
+ free(val);
goto next;
}
*ptr++ = '\0';
@@ -1150,6 +1154,52 @@ relay_read_http(struct bufferevent *bev, void *arg)
strlen(pkv.value) < 1)
continue;
*pkv.value++ = '\0';
+
+ if ((pnv = RB_FIND(proto_tree,
+ cre->tree, &pkv)) == NULL)
+ continue;
+ ret = relay_handle_http(cre, pnv, &pkv, 0);
+ if (ret == PN_PASS)
+ continue;
+ else if (ret == PN_FAIL) {
+ free(val);
+ free(line);
+ return;
+ }
+ }
+ free(val);
+ } else if (pn->flags & PNFLAG_LOOKUP_COOKIE) {
+ /*
+ * Decode the HTTP cookies
+ */
+ val = strdup(pk.value);
+ if (val == NULL)
+ goto next;
+
+ for (ptr = val; ptr != NULL && strlen(ptr);) {
+ if (*ptr == ' ')
+ *ptr++ = '\0';
+ pkv.key = ptr;
+ pkv.type = NODE_TYPE_COOKIE;
+ if ((ptr = strchr(ptr, ';')) != NULL)
+ *ptr++ = '\0';
+ /*
+ * XXX We do not handle attributes
+ * ($Path, $Domain, or $Port)
+ */
+ if (*pkv.key == '$')
+ continue;
+
+ if ((pkv.value =
+ strchr(pkv.key, '=')) == NULL ||
+ strlen(pkv.value) < 1)
+ continue;
+ *pkv.value++ = '\0';
+ if (*pkv.value == '"')
+ *pkv.value++ = '\0';
+ if (pkv.value[strlen(pkv.value) - 1] == '"')
+ pkv.value[strlen(pkv.value) - 1] = '\0';
+
if ((pnv = RB_FIND(proto_tree,
cre->tree, &pkv)) == NULL)
continue;
@@ -1157,14 +1207,15 @@ relay_read_http(struct bufferevent *bev, void *arg)
if (ret == PN_PASS)
continue;
else if (ret == PN_FAIL) {
- free(url);
+ free(val);
free(line);
return;
}
}
- free(url);
+ free(val);
}
+ handle:
ret = relay_handle_http(cre, pn, &pk, header);
if (ret == PN_PASS)
goto next;
@@ -1173,7 +1224,7 @@ relay_read_http(struct bufferevent *bev, void *arg)
return;
continue;
-next:
+ next:
if (relay_bufferevent_print(cre->dst, pk.key) == -1 ||
relay_bufferevent_print(cre->dst,
header ? ": " : " ") == -1 ||
diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5
index d75c60d1b93..f7f179ae47c 100644
--- a/usr.sbin/relayd/relayd.conf.5
+++ b/usr.sbin/relayd/relayd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: relayd.conf.5,v 1.36 2007/02/27 18:04:51 jmc Exp $
+.\" $OpenBSD: relayd.conf.5,v 1.37 2007/03/06 19:26:46 reyk Exp $
.\"
.\" Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
.\"
@@ -451,6 +451,12 @@ Look up the entity as a GET variable in the URL when using the
protocol.
This type is only available with the direction
.Ic request .
+.It Ic cookie
+Look up the entity as a value in the Cookie header when using the
+.Ic http
+protocol.
+This type is only available with the direction
+.Ic request .
.El
.Pp
The following actions are available:
@@ -667,6 +673,7 @@ protocol http_ssl {
header append "$SERVER_ADDR:$SERVER_PORT" to "X-Forwarded-By"
header change "Keep-Alive" to "$TIMEOUT"
url hash "sessid"
+ cookie hash "sessid"
ssl { sslv2, ciphers "MEDIUM:HIGH" }
}