[or-cvs] Add some functions to escape values from the network before...

Nick Mathewson nickm at seul.org
Sun Mar 5 09:50:27 UTC 2006


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

Modified Files:
	tortls.c util.c util.h 
Log Message:
Add some functions to escape values from the network before sending them to the log.  Use them everywhere except for routerinfo->plaftorm, routerinfo->contact_info, and rend*.c.  (need sleep now)

Index: tortls.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/common/tortls.c,v
retrieving revision 1.117
retrieving revision 1.118
diff -u -p -d -r1.117 -r1.118
--- tortls.c	13 Feb 2006 08:01:59 -0000	1.117
+++ tortls.c	5 Mar 2006 09:50:25 -0000	1.118
@@ -672,7 +672,8 @@ tor_tls_get_peer_cert_nickname(tor_tls_t
     goto error;
   if (((int)strspn(buf, LEGAL_NICKNAME_CHARACTERS)) < lenout) {
     log_warn(LD_PROTOCOL,
-             "Peer certificate nickname \"%s\" has illegal characters.", buf);
+             "Peer certificate nickname %s has illegal characters.",
+             escaped(buf));
     if (strchr(buf, '.'))
       log_warn(LD_PROTOCOL, "  (Maybe it is not really running Tor at its "
                "advertised OR port.)");

Index: util.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/common/util.c,v
retrieving revision 1.248
retrieving revision 1.249
diff -u -p -d -r1.248 -r1.249
--- util.c	5 Mar 2006 05:27:58 -0000	1.248
+++ util.c	5 Mar 2006 09:50:25 -0000	1.249
@@ -329,6 +329,16 @@ tor_strupper(char *s)
   }
 }
 
+int
+tor_strisprint(const char *s)
+{
+  while (*s) {
+    if (!TOR_ISPRINT(*s))
+      return 0;
+  }
+  return 1;
+}
+
 /* Compares the first strlen(s2) characters of s1 with s2.  Returns as for
  * strcmp.
  */
@@ -564,6 +574,100 @@ base16_decode(char *dest, size_t destlen
   return 0;
 }
 
+/** Allocate and return a new string representing the contents of <b>s</b>,
+ * surrounded by quotes and using standard C escapes.
+ *
+ * Generally, we use this for logging values that come in over the network
+ * to keep them from tricking users.
+ *
+ * We trust values from the resolver, OS, configuration file, and command line
+ * to not be maliciously ill-formed.  We validate incoming routerdescs and
+ * SOCKS requests and addresses from BEGIN cells as they're parsed;
+ * afterwards, we trust them as non-malicious.
+ */
+char *
+esc_for_log(const char *s)
+{
+  const char *cp;
+  char *result, *outp;
+  size_t len = 3;
+  for (cp = s; *cp; ++cp) {
+    switch (*cp) {
+      case '\\':
+      case '\"':
+      case '\'':
+        len += 2;
+        break;
+      default:
+        if (TOR_ISPRINT(*cp))
+          ++len;
+        else
+          len += 4;
+        break;
+    }
+  }
+
+  result = outp = tor_malloc(len);
+  *outp++ = '\"';
+  for (cp = s; *cp; ++cp) {
+    switch (*cp) {
+      case '\\':
+      case '\"':
+      case '\'':
+        *outp++ = '\\';
+        *outp++ = *cp;
+        break;
+      case '\n':
+        *outp++ = '\\';
+        *outp++ = 'n';
+        break;
+      case '\t':
+        *outp++ = '\\';
+        *outp++ = 't';
+        break;
+      case '\r':
+        *outp++ = '\\';
+        *outp++ = 'r';
+        break;
+      default:
+        if (TOR_ISPRINT(*cp)) {
+          *outp++ = *cp;
+        } else {
+          tor_snprintf(outp, 5, "\\%03o", (uint8_t) *cp);
+          outp += 4;
+        }
+        break;
+    }
+  }
+
+  *outp++ = '\"';
+  *outp++ = 0;
+
+  return result;
+}
+
+/** Allocate and return a new string representing the contents of <b>s</b>,
+ * surrounded by quotes and using standard C escapes.
+ *
+ * THIS FUNCTION IS NOT REENTRANT.  Don't call it from outside the main
+ * thread.  Also, each call invalidates the last-returned value, so don't
+ * try log_warn(LD_GENERAL, "%s %s", escaped(a), escaped(b));
+ */
+const char *
+escaped(const char *s)
+{
+  static char *_escaped_val = NULL;
+  if (_escaped_val)
+    tor_free(_escaped_val);
+
+  if (s)
+    _escaped_val = esc_for_log(s);
+  else
+    _escaped_val = NULL;
+
+  return _escaped_val;
+}
+
 /* =====
  * Time
  * ===== */
@@ -700,7 +804,9 @@ parse_rfc1123_time(const char *buf, time
   if (sscanf(buf, "%3s, %d %3s %d %d:%d:%d GMT", weekday,
              &tm.tm_mday, month, &tm.tm_year, &tm.tm_hour,
              &tm.tm_min, &tm.tm_sec) < 7) {
-    log_warn(LD_GENERAL, "Got invalid RFC1123 time \"%s\"", buf);
+    char *esc = esc_for_log(buf);
+    log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
+    tor_free(esc);
     return -1;
   }
 
@@ -712,14 +818,18 @@ parse_rfc1123_time(const char *buf, time
     }
   }
   if (m<0) {
-    log_warn(LD_GENERAL, "Got invalid RFC1123 time \"%s\"", buf);
+    char *esc = esc_for_log(buf);
+    log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
+    tor_free(esc);
     return -1;
   }
   tm.tm_mon = m;
 
   if (tm.tm_year < 1970) {
+    char *esc = esc_for_log(buf);
     log_warn(LD_GENERAL,
-             "Got invalid RFC1123 time \"%s\". (Before 1970)", buf);
+             "Got invalid RFC1123 time %s. (Before 1970)", esc);
+    tor_free(esc);
     return -1;
   }
   tm.tm_year -= 1900;
@@ -768,7 +878,9 @@ parse_iso_time(const char *cp, time_t *t
   st_tm.tm_sec = second;
 #endif
   if (st_tm.tm_year < 70) {
-    log_warn(LD_GENERAL, "Got invalid ISO time \"%s\". (Before 1970)", cp);
+    char *esc = esc_for_log(cp);
+    log_warn(LD_GENERAL, "Got invalid ISO time %s. (Before 1970)", esc);
+    tor_free(esc);
     return -1;
   }
   *t = tor_timegm(&st_tm);
@@ -1222,7 +1334,7 @@ expand_filename(const char *filename)
       home = getenv("HOME");
       if (!home) {
         log_warn(LD_CONFIG, "Couldn't find $HOME environment variable while "
-                 "expanding %s", filename);
+                 "expanding \"%s\"", filename);
         return NULL;
       }
       home = tor_strdup(home);
@@ -1385,13 +1497,15 @@ parse_addr_port(const char *addrport, ch
     _address = tor_strndup(addrport, colon-addrport);
     _port = (int) tor_parse_long(colon+1,10,1,65535,NULL,NULL);
     if (!_port) {
-      log_warn(LD_GENERAL, "Port '%s' out of range", colon+1);
+      log_warn(LD_GENERAL, "Port %s out of range", escaped(colon+1));
       ok = 0;
     }
     if (!port_out) {
+      char *esc_addrport = esc_for_log(addrport);
       log_warn(LD_GENERAL,
-               "Port '%s' given on '%s' when not required",
-               colon+1, addrport);
+               "Port %s given on %s when not required",
+               escaped(colon+1), esc_addrport);
+      tor_free(esc_addrport);
       ok = 0;
     }
   } else {
@@ -1402,7 +1516,7 @@ parse_addr_port(const char *addrport, ch
   if (addr) {
     /* There's an addr pointer, so we need to resolve the hostname. */
     if (tor_lookup_hostname(_address,addr)) {
-      log_warn(LD_NET, "Couldn't look up '%s'", _address);
+      log_warn(LD_NET, "Couldn't look up %s", escaped(_address));
       ok = 0;
       *addr = 0;
     }
@@ -1464,13 +1578,13 @@ parse_port_range(const char *port, uint1
                                                 &endptr);
       if (*endptr || !*port_max_out) {
         log_warn(LD_GENERAL,
-                 "Malformed port \"%s\" on address range rejecting.",
-                 port);
+                 "Malformed port %s on address range rejecting.",
+                 escaped(port));
       }
     } else if (*endptr || !*port_min_out) {
       log_warn(LD_GENERAL,
-               "Malformed port \"%s\" on address range; rejecting.",
-               port);
+               "Malformed port %s on address range; rejecting.",
+               escaped(port));
       return -1;
     } else {
       *port_max_out = *port_min_out;
@@ -1523,8 +1637,8 @@ parse_addr_and_port_range(const char *s,
   } else if (tor_inet_aton(address, &in) != 0) {
     *addr_out = ntohl(in.s_addr);
   } else {
-    log_warn(LD_GENERAL, "Malformed IP \"%s\" in address pattern; rejecting.",
-             address);
+    log_warn(LD_GENERAL, "Malformed IP %s in address pattern; rejecting.",
+             escaped(address));
     goto err;
   }
 
@@ -1548,8 +1662,8 @@ parse_addr_and_port_range(const char *s,
       *mask_out = ntohl(in.s_addr);
     } else {
       log_warn(LD_GENERAL,
-               "Malformed mask \"%s\" on address range; rejecting.",
-               mask);
+               "Malformed mask %s on address range; rejecting.",
+               escaped(mask));
       goto err;
     }
   }

Index: util.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/common/util.h,v
retrieving revision 1.154
retrieving revision 1.155
diff -u -p -d -r1.154 -r1.155
--- util.h	5 Mar 2006 05:27:59 -0000	1.154
+++ util.h	5 Mar 2006 09:50:25 -0000	1.155
@@ -90,6 +90,7 @@ extern int dmalloc_free(const char *file
 #define HEX_CHARACTERS "0123456789ABCDEFabcdef"
 void tor_strlower(char *s);
 void tor_strupper(char *s);
+int tor_strisprint(const char *s);
 int strcmpstart(const char *s1, const char *s2);
 int strcasecmpstart(const char *s1, const char *s2);
 int strcmpend(const char *s1, const char *s2);
@@ -112,6 +113,8 @@ const char *eat_whitespace(const char *s
 const char *eat_whitespace_no_nl(const char *s);
 const char *find_whitespace(const char *s);
 int tor_digest_is_zero(const char *digest);
+char *esc_for_log(const char *string);
+const char *escaped(const char *string);
 
 void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen);
 int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);



More information about the tor-commits mailing list