diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-03-06 19:26:47 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2007-03-06 19:26:47 +0000 |
commit | 41830b96c1b5144beab9858f74e2881634f915d2 (patch) | |
tree | 5abf219d5b6d1539f2f63be3d6281e9991a678dc /usr.sbin/relayd | |
parent | 0cb27c3402077630224ff3f8ea8968e2e2c8f985 (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.y | 13 | ||||
-rw-r--r-- | usr.sbin/relayd/relay.c | 75 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.conf.5 | 9 |
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" } } |