From: Jim Jagielski Date: Thu, 16 Oct 2003 17:23:26 +0000 (+0000) Subject: *) Fixed mod_usertrack to not get false positive matches on the X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22fbb5d55c975eed88e0d47e493993ae3dd9d606;p=thirdparty%2Fapache%2Fhttpd.git *) Fixed mod_usertrack to not get false positive matches on the user-tracking cookie's name. PR 16661. [Manni Wood ] PR: 16661 (2.x) Obtained from: Submitted by: Reviewed by: cliff, jeff, jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@101471 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/STATUS b/STATUS index d7e52964237..051900cd0dc 100644 --- a/STATUS +++ b/STATUS @@ -1,5 +1,5 @@ APACHE 1.3 STATUS: -*-text-*- - Last modified at [$Date: 2003/10/16 17:18:43 $] + Last modified at [$Date: 2003/10/16 17:23:26 $] Release: @@ -56,10 +56,6 @@ RELEASE SHOWSTOPPERS: Message-Id: <3F8C56E3.8050501@attglobal.net> +1: jeff, jim - * [PATCH] mod_usertrack cookie matching - Message-Id: - +1: cliff, jeff, jim - RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP: diff --git a/src/CHANGES b/src/CHANGES index e4aafd98bb2..84676f49682 100644 --- a/src/CHANGES +++ b/src/CHANGES @@ -1,5 +1,9 @@ Changes with Apache 1.3.29 + *) Fixed mod_usertrack to not get false positive matches on the + user-tracking cookie's name. PR 16661. + [Manni Wood ] + *) Enabled RFC1413 ident functionality for both Win32 and NetWare platforms. This also included an alternate thread safe implementation of the socket timout functionality when querying diff --git a/src/modules/standard/mod_usertrack.c b/src/modules/standard/mod_usertrack.c index aaab2e76591..2de49ed2a91 100644 --- a/src/modules/standard/mod_usertrack.c +++ b/src/modules/standard/mod_usertrack.c @@ -126,6 +126,8 @@ typedef struct { char *cookie_name; char *cookie_domain; char *prefix_string; + char *regexp_string; /* used to compile regexp; save for debugging */ + regex_t *regexp; /* used to find usertrack cookie in cookie header */ } cookie_dir_rec; /* Define this to allow post-2000 cookies. Cookies use two-digit dates, @@ -284,35 +286,48 @@ static void make_cookie(request_rec *r) return; } +/* dcfg->regexp is "^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)", + * which has three subexpressions, $0..$2 */ +#define NUM_SUBS 3 + static int spot_cookie(request_rec *r) { cookie_dir_rec *dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module); - const char *cookie; - char *value; + const char *cookie_header; + regmatch_t regm[NUM_SUBS]; + int i; if (!dcfg->enabled) { return DECLINED; } - if ((cookie = ap_table_get(r->headers_in, - (dcfg->style == CT_COOKIE2 - ? "Cookie2" - : "Cookie")))) - if ((value = strstr(cookie, dcfg->cookie_name))) { - char *cookiebuf, *cookieend; - - value += strlen(dcfg->cookie_name) + 1; /* Skip over the '=' */ - cookiebuf = ap_pstrdup(r->pool, value); - cookieend = strchr(cookiebuf, ';'); - if (cookieend) - *cookieend = '\0'; /* Ignore anything after a ; */ - - /* Set the cookie in a note, for logging */ - ap_table_setn(r->notes, "cookie", cookiebuf); - - return DECLINED; /* There's already a cookie, no new one */ - } + if ((cookie_header = ap_table_get(r->headers_in, + (dcfg->style == CT_COOKIE2 + ? "Cookie2" + : "Cookie")))) { + if (!ap_regexec(dcfg->regexp, cookie_header, NUM_SUBS, regm, 0)) { + char *cookieval = NULL; + /* Our regexp, + * ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+) + * only allows for $1 or $2 to be available. ($0 is always + * filled with the entire matched expression, not just + * the part in parentheses.) So just check for either one + * and assign to cookieval if present. */ + if (regm[1].rm_so != -1) { + cookieval = ap_pregsub(r->pool, "$1", cookie_header, + NUM_SUBS, regm); + } + if (regm[2].rm_so != -1) { + cookieval = ap_pregsub(r->pool, "$2", cookie_header, + NUM_SUBS, regm); + } + /* Set the cookie in a note, for logging */ + ap_table_setn(r->notes, "cookie", cookieval); + + return DECLINED; /* There's already a cookie, no new one */ + } + } make_cookie(r); return OK; /* We set our cookie */ } @@ -422,7 +437,26 @@ static const char *set_cookie_name(cmd_parms *cmd, void *mconfig, char *name) { cookie_dir_rec *dcfg = (cookie_dir_rec *) mconfig; + /* The goal is to end up with this regexp, + * ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+) + * with cookie_name + * obviously substituted with the real cookie name set by the + * user in httpd.conf. */ + dcfg->regexp_string = ap_pstrcat(cmd->pool, "^", name, + "=([^;]+)|;[ \t]+", name, + "=([^;]+)", NULL); + dcfg->cookie_name = ap_pstrdup(cmd->pool, name); + + dcfg->regexp = ap_pregcomp(cmd->pool, dcfg->regexp_string, REG_EXTENDED); + if (dcfg->regexp == NULL) { + return "Regular expression could not be compiled."; + } + if (dcfg->regexp->re_nsub + 1 != NUM_SUBS) { + return ap_pstrcat(cmd->pool, "Invalid cookie name \"", + name, "\"", NULL); + } + return NULL; }