diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-03-05 09:50:26 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-03-05 09:50:26 +0000 |
commit | 5777ee0e1a8bf0652aff75bb2c316c5bbbb4b854 (patch) | |
tree | e410cb36f9345a0aa46b735ca2128da55a68c152 /src/common | |
parent | 6a4e304d9e613b613e208bb0f11ec44c3fc30150 (diff) | |
download | tor-5777ee0e1a8bf0652aff75bb2c316c5bbbb4b854.tar tor-5777ee0e1a8bf0652aff75bb2c316c5bbbb4b854.tar.gz |
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)
svn:r6087
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/tortls.c | 3 | ||||
-rw-r--r-- | src/common/util.c | 148 | ||||
-rw-r--r-- | src/common/util.h | 3 |
3 files changed, 136 insertions, 18 deletions
diff --git a/src/common/tortls.c b/src/common/tortls.c index 588126113..2acbcbb57 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -672,7 +672,8 @@ tor_tls_get_peer_cert_nickname(tor_tls_t *tls, char *buf, size_t buflen) 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.)"); diff --git a/src/common/util.c b/src/common/util.c index 7e4f0a145..0ae109c1d 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -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, const char *src, size_t srclen) 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_t *t) 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_t *t) } } 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, char **address, uint32_t *addr, _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, char **address, uint32_t *addr, 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, uint16_t *port_min_out, &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, uint32_t *addr_out, } 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, uint32_t *addr_out, *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; } } diff --git a/src/common/util.h b/src/common/util.h index 64aca2392..bed4f16c5 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -90,6 +90,7 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, #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); |