]> granicus.if.org Git - apache/commitdiff
Minor MMN bump:
authorAndre Malo <nd@apache.org>
Thu, 6 Mar 2003 23:53:52 +0000 (23:53 +0000)
committerAndre Malo <nd@apache.org>
Thu, 6 Mar 2003 23:53:52 +0000 (23:53 +0000)
Forward port: Escape special characters (especially control
characters) in mod_log_config to make a clear distinction between
client-supplied strings (with special characters) and server-side
strings. This was already introduced in version 1.3.25.

Obtained from: Patch in 1.3.25-dev by Martin

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@98912 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
include/ap_mmn.h
include/httpd.h
modules/loggers/mod_log_config.c
server/gen_test_char.c
server/util.c

diff --git a/CHANGES b/CHANGES
index ae1ed2fb7ad133b23a14e9ddec4ff3d16f8e387c..f3f202d67a6fb1d0032c0d469ce61cbab320dd24 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,12 @@ Changes with Apache 2.1.0-dev
 
   [Remove entries to the current 2.0 section below, when backported]
 
+  *) Forward port: Escape special characters (especially control
+     characters) in mod_log_config to make a clear distinction between
+     client-supplied strings (with special characters) and server-side
+     strings. This was already introduced in version 1.3.25.
+     [AndrĂ© Malo]
+
   *) mod_usertrack: don't set the cookie in subrequests. This works
      around the problem that cookies were set twice during fast internal
      redirects. PR 13211.  [AndrĂ© Malo]
index 84744b803574ac90b8408eba3ac6093a6982d325..9e029cfc30cbe20264209dc9b10e4aeb02b2bf2c 100644 (file)
  * 20020628 (2.0.40-dev) Added filter_init to filter registration functions
  * 20020903 (2.0.41-dev) APR's error constants changed
  * 20020903.1 (2.1.0-dev) allow_encoded_slashes added to core_dir_config
- * 20030213.1 (2.1.0-dev) changed log_writer optional fn's to return previous handler
+ * 20030213.1 (2.1.0-dev) changed log_writer optional fn's to return previous
+ *                        handler
+ * 20030213.2 (2.1.0-dev) add ap_escape_logitem
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20030213
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 1                     /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 2                     /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index b922506ca478b29d2a08abf2ca322c028c848f76..cfbbab6c13b877f3143a22d6b62495aa34bfdc7e 100644 (file)
@@ -1359,6 +1359,14 @@ AP_DECLARE(char *) ap_os_escape_path(apr_pool_t *p, const char *path, int partia
  */
 AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s);
 
+/**
+ * Escape a string for logging
+ * @param p The pool to allocate from
+ * @param s The string to escape
+ * @return The escaped string
+ */
+AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str);
+
 /**
  * Construct a full hostname
  * @param p The pool to allocate from
index 27f3e5f9d51b9c9ae55798f9bb1ee9f820be1aba..032b806d9b40e51d56dd2bba103864e94fdb64bb 100644 (file)
@@ -333,8 +333,9 @@ static const char *constant_item(request_rec *dummy, char *stuff)
 
 static const char *log_remote_host(request_rec *r, char *a)
 {
-    return ap_get_remote_host(r->connection, r->per_dir_config,
-                                    REMOTE_NAME, NULL);
+    return ap_escape_logitem(r->pool, ap_get_remote_host(r->connection,
+                                                         r->per_dir_config,
+                                                         REMOTE_NAME, NULL));
 }
 
 static const char *log_remote_address(request_rec *r, char *a)
@@ -349,7 +350,7 @@ static const char *log_local_address(request_rec *r, char *a)
 
 static const char *log_remote_logname(request_rec *r, char *a)
 {
-    return ap_get_remote_logname(r);
+    return ap_escape_logitem(r->pool, ap_get_remote_logname(r));
 }
 
 static const char *log_remote_user(request_rec *r, char *a)
@@ -362,6 +363,10 @@ static const char *log_remote_user(request_rec *r, char *a)
     else if (strlen(rvalue) == 0) {
         rvalue = "\"\"";
     }
+    else {
+        rvalue = ap_escape_logitem(r->pool, rvalue);
+    }
+
     return rvalue;
 }
 
@@ -372,33 +377,37 @@ static const char *log_request_line(request_rec *r, char *a)
      * (note the truncation before the protocol string for HTTP/0.9 requests)
      * (note also that r->the_request contains the unmodified request)
      */
-    return (r->parsed_uri.password) 
-                ? apr_pstrcat(r->pool, r->method, " ",
-                              apr_uri_unparse(r->pool, &r->parsed_uri, 0),
-                              r->assbackwards ? NULL : " ", r->protocol, NULL)
-                : r->the_request;
+    return ap_escape_logitem(r->pool,
+                             (r->parsed_uri.password)
+                               ? apr_pstrcat(r->pool, r->method, " ",
+                                             apr_uri_unparse(r->pool,
+                                                             &r->parsed_uri, 0),
+                                             r->assbackwards ? NULL : " ",
+                                             r->protocol, NULL)
+                               : r->the_request);
 }
 
 static const char *log_request_file(request_rec *r, char *a)
 {
-    return r->filename;
+    return ap_escape_logitem(r->pool, r->filename);
 }
 static const char *log_request_uri(request_rec *r, char *a)
 {
-    return r->uri;
+    return ap_escape_logitem(r->pool, r->uri);
 }
 static const char *log_request_method(request_rec *r, char *a)
 {
-    return r->method;
+    return ap_escape_logitem(r->pool, r->method);
 }
 static const char *log_request_protocol(request_rec *r, char *a)
 {
-    return r->protocol;
+    return ap_escape_logitem(r->pool, r->protocol);
 }
 static const char *log_request_query(request_rec *r, char *a)
 {
-    return (r->args != NULL) ? apr_pstrcat(r->pool, "?", r->args, NULL)
-                             : "";
+    return (r->args) ? apr_pstrcat(r->pool, "?",
+                                   ap_escape_logitem(r->pool, r->args), NULL)
+                     : "";
 }
 static const char *log_status(request_rec *r, char *a)
 {
@@ -428,7 +437,7 @@ static const char *log_bytes_sent(request_rec *r, char *a)
 
 static const char *log_header_in(request_rec *r, char *a)
 {
-    return apr_table_get(r->headers_in, a);
+    return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a));
 }
 
 static const char *log_header_out(request_rec *r, char *a)
@@ -438,18 +447,18 @@ static const char *log_header_out(request_rec *r, char *a)
         cp = ap_field_noparam(r->pool, r->content_type);
     }
     if (cp) {
-        return cp;
+        return ap_escape_logitem(r->pool, cp);
     }
-    return apr_table_get(r->err_headers_out, a);
+    return ap_escape_logitem(r->pool, apr_table_get(r->err_headers_out, a));
 }
 
 static const char *log_note(request_rec *r, char *a)
 {
-    return apr_table_get(r->notes, a);
+    return ap_escape_logitem(r->pool, apr_table_get(r->notes, a));
 }
 static const char *log_env_var(request_rec *r, char *a)
 {
-    return apr_table_get(r->subprocess_env, a);
+    return ap_escape_logitem(r->pool, apr_table_get(r->subprocess_env, a));
 }
 
 static const char *log_cookie(request_rec *r, char *a)
@@ -467,7 +476,7 @@ static const char *log_cookie(request_rec *r, char *a)
             if (end_cookie) {
                 *end_cookie = '\0';
             }
-            return cookie;
+            return ap_escape_logitem(r->pool, cookie);
         }
     }
     return NULL;
@@ -585,7 +594,7 @@ static const char *log_request_duration_microseconds(request_rec *r, char *a)
  */
 static const char *log_virtual_host(request_rec *r, char *a)
 {
-    return r->server->server_hostname;
+    return ap_escape_logitem(r->pool, r->server->server_hostname);
 }
 
 static const char *log_server_port(request_rec *r, char *a)
@@ -599,7 +608,7 @@ static const char *log_server_port(request_rec *r, char *a)
  */
 static const char *log_server_name(request_rec *r, char *a)
 {
-    return ap_get_server_name(r);
+    return ap_escape_logitem(r->pool, ap_get_server_name(r));
 }
 
 static const char *log_child_pid(request_rec *r, char *a)
index faab8126fb1893c879381ea62a2214af58fc2384..5102ca98c0b33d89518e25133a86bd42595e4ce7 100644 (file)
@@ -73,6 +73,7 @@
 #define T_ESCAPE_PATH_SEGMENT (0x02)
 #define T_OS_ESCAPE_PATH      (0x04)
 #define T_HTTP_TOKEN_STOP     (0x08)
+#define T_ESCAPE_LOGITEM      (0x10)
 
 int main(int argc, char *argv[])
 {
@@ -85,13 +86,15 @@ int main(int argc, char *argv[])
            "#define T_ESCAPE_PATH_SEGMENT  (%u)\n"
            "#define T_OS_ESCAPE_PATH       (%u)\n"
            "#define T_HTTP_TOKEN_STOP      (%u)\n"
+           "#define T_ESCAPE_LOGITEM       (%u)\n"
            "\n"
            "static const unsigned char test_char_table[256] = {\n"
            "    0,",
            T_ESCAPE_SHELL_CMD,
            T_ESCAPE_PATH_SEGMENT,
            T_OS_ESCAPE_PATH,
-           T_HTTP_TOKEN_STOP);
+           T_HTTP_TOKEN_STOP,
+           T_ESCAPE_LOGITEM);
 
     /* we explicitly dealt with NUL above
      * in case some strchr() do bogosity with it */
@@ -135,8 +138,16 @@ int main(int argc, char *argv[])
             flags |= T_HTTP_TOKEN_STOP;
         }
 
-        printf("%u%c", flags, (c < 255) ? ',' : ' ');
+        /* For logging, escape all control characters,
+         * double quotes (because they delimit the request in the log file)
+         * backslashes (because we use backslash for escaping)
+         * and 8-bit chars with the high bit set
+         */
+        if (!apr_isprint(c) || c == '"' || c == '\\' || apr_iscntrl(c)) {
+            flags |= T_ESCAPE_LOGITEM;
+        }
 
+        printf("%u%c", flags, (c < 255) ? ',' : ' ');
     }
 
     printf("\n};\n");
index 246274edf5db033cbd2e842dec7d2c3c4489e2a5..3e6c55bc2921cb459b295569ad205ed07a1a7647 100644 (file)
@@ -1784,6 +1784,58 @@ AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s)
     return x;
 }
 
+AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str)
+{
+    char *ret;
+    unsigned char *d;
+    const unsigned char *s;
+
+    if (!str) {
+        return NULL;
+    }
+
+    ret = apr_palloc(p, 4 * strlen(str) + 1); /* Be safe */
+    d = (unsigned char *)ret;
+    s = (const unsigned char *)str;
+    for (; *s; ++s) {
+
+        if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
+            *d++ = '\\';
+            switch(*s) {
+            case '\b':
+                *d++ = 'b';
+                break;
+            case '\n':
+                *d++ = 'n';
+                break;
+            case '\r':
+                *d++ = 'r';
+                break;
+            case '\t':
+                *d++ = 't';
+                break;
+            case '\v':
+                *d++ = 'v';
+                break;
+            case '\\':
+            case '"':
+                *d++ = *s;
+                break;
+            default:
+                c2x(*s, d);
+                *d = 'x';
+                d += 3;
+            }
+        }
+        else {
+            *d++ = *s;
+        }
+    }
+    *d = '\0';
+
+    return ret;
+}
+
 AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path)
 {
     apr_finfo_t finfo;