[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Add some functions to escape values from the network before...
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);