[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] check [X-]Forwarded-For headers in HTTP requests when gener...



Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv19155/src/or

Modified Files:
	directory.c 
Log Message:
check [X-]Forwarded-For headers in HTTP requests when generating log messages.  Implements feature for bug 181.  Arma--please review?

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/directory.c,v
retrieving revision 1.243
retrieving revision 1.244
diff -u -d -r1.243 -r1.244
--- directory.c	12 Aug 2005 15:05:05 -0000	1.243
+++ directory.c	23 Aug 2005 22:27:17 -0000	1.244
@@ -49,6 +49,8 @@
 static int directory_handle_command(connection_t *conn);
 static int body_is_plausible(const char *body, size_t body_len, int purpose);
 static int purpose_is_private(uint8_t purpose);
+static char *http_get_header(const char *headers, const char *which);
+static char *http_get_origin(const char *headers, connection_t *conn);
 
 /********* START VARIABLES **********/
 
@@ -508,6 +510,56 @@
   return 0;
 }
 
+/** Return a copy of the first HTTP header in <b>headers</b> whose key is
+ * <b>which</b>.  The key should be given with a terminating colon and space;
+ * this function copies everything after, up to but not including the
+ * following newline. */
+static char *
+http_get_header(const char *headers, const char *which)
+{
+  const char *cp = headers;
+  while (cp) {
+    if (!strcmpstart(cp, which)) {
+      char *eos;
+      cp += strlen(which);
+      if ((eos = strchr(cp,'\n')))
+        return tor_strndup(cp, eos-cp);
+      else
+        return tor_strdup(cp);
+    }
+    cp = strchr(headers, '\n');
+    if (cp)
+      ++cp;
+  }
+  return NULL;
+}
+
+/** Allocate and return a string describing the source of an HTTP request with
+ * headers <b>headers</b> received on <b>conn</b>.  The format is either
+ * "'1.2.3.4'", or "'1.2.3.4' (forwarded for '5.6.7.8')".
+ */
+static char *
+http_get_origin(const char *headers, connection_t *conn)
+{
+  char *fwd;
+
+  fwd = http_get_header(headers, "Forwarded-For: ");
+  if (!fwd)
+    fwd = http_get_header(headers, "X-Forwarded-For: ");
+  if (fwd) {
+    size_t len = strlen(fwd)+strlen(conn->address)+32;
+    char *result = tor_malloc(len);
+    tor_snprintf(result, len, "'%s' (forwarded for '%s')", conn->address, fwd);
+    tor_free(fwd);
+    return result;
+  } else {
+    size_t len = strlen(conn->address)+3;
+    char *result = tor_malloc(len);
+    tor_snprintf(result, len, "'%s'", conn->address);
+    return result;
+  }
+}
+
 /** Parse an HTTP response string <b>headers</b> of the form
  * \verbatim
  * "HTTP/1.\%d \%d\%s\r\n...".
@@ -942,7 +994,7 @@
 {
   size_t dlen;
   const char *cp;
-  char *url;
+  char *url = NULL;
   char tmp[8192];
   char date[RFC1123_TIME_LEN+1];
 
@@ -1060,7 +1112,8 @@
                               char *body, size_t body_len)
 {
   const char *cp;
-  char *url;
+  char *origin = NULL;
+  char *url = NULL;
 
   log_fn(LOG_DEBUG,"Received POST command.");
 
@@ -1078,6 +1131,7 @@
     return 0;
   }
   log_fn(LOG_INFO,"rewritten url as '%s'.", url);
+  origin = http_get_origin(headers, conn);
 
   if (!strcmp(url,"/tor/")) { /* server descriptor post */
     const char *msg;
@@ -1087,7 +1141,7 @@
       case -1:
         /* malformed descriptor, or something wrong */
         write_http_status_line(conn, 400, msg?msg:"Malformed or unacceptable server descriptor");
-        log_fn(LOG_NOTICE,"Rejected descriptor published by '%s'.", conn->address);
+        log_fn(LOG_NOTICE,"Rejected descriptor published by %s.", origin);
         break;
       case 0:
         /* descriptor was well-formed but server has not been approved */
@@ -1098,8 +1152,7 @@
         write_http_status_line(conn, 200, msg?msg:"Verified server descriptor accepted");
         break;
     }
-    tor_free(url);
-    return 0;
+    goto done;
   }
 
   if (!strcmpstart(url,"/tor/rendezvous/publish")) {
@@ -1108,14 +1161,17 @@
       write_http_status_line(conn, 400, "Invalid service descriptor rejected");
     else
       write_http_status_line(conn, 200, "Service descriptor stored");
-    tor_free(url);
-    return 0;
+    goto done;
   }
 
   /* we didn't recognize the url */
   write_http_status_line(conn, 404, "Not found");
+
+ done:
   tor_free(url);
+  tor_free(origin);
   return 0;
+
 }
 
 /** Called when a dirserver receives data on a directory connection;