]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
*) Fixed mod_usertrack to not get false positive matches on the
authorJim Jagielski <jim@apache.org>
Thu, 16 Oct 2003 17:23:26 +0000 (17:23 +0000)
committerJim Jagielski <jim@apache.org>
Thu, 16 Oct 2003 17:23:26 +0000 (17:23 +0000)
     user-tracking cookie's name.  PR 16661.
     [Manni Wood <manniwood@planet-save.com>]

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

STATUS
src/CHANGES
src/modules/standard/mod_usertrack.c

diff --git a/STATUS b/STATUS
index d7e52964237d313de744a027de3720409719e7c0..051900cd0dc99381fe3aff0270f0377e7cc8afb8 100644 (file)
--- 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: <Pine.GSO.4.58.0310151648120.17890@cobra.cs.Virginia.EDU>
-        +1: cliff, jeff, jim
-
 
 RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP:
 
index e4aafd98bb2ad0e2f7c779a41451ca765f8f4d19..84676f4968255e32c3082468704f7cec7eeae837 100644 (file)
@@ -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 <manniwood@planet-save.com>]
+
   *) 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
index aaab2e765917463d12b0928e5faf59fb21b471f3..2de49ed2a9125f640fce12f8df3e473fc6ccad9c 100644 (file)
@@ -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;
 }