From f25864743368e7962bfffc0e57763b13157429e3 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Mon, 28 Sep 2009 15:08:32 +0200 Subject: [PATCH] Allow SafeLogging to exclude client related information --- ChangeLog | 2 ++ doc/tor.1.in | 13 ++++++--- src/or/buffers.c | 3 +- src/or/circuitbuild.c | 3 +- src/or/command.c | 10 ++++--- src/or/config.c | 47 ++++++++++++++++++++++++++++--- src/or/connection.c | 9 ++++-- src/or/connection_edge.c | 35 +++++++++++++++-------- src/or/connection_or.c | 6 ++-- src/or/control.c | 3 +- src/or/directory.c | 4 +-- src/or/dns.c | 60 +++++++++++++++++++++------------------- src/or/main.c | 7 +++-- src/or/or.h | 5 ++-- src/or/relay.c | 8 +++--- src/or/rendclient.c | 3 +- src/or/rendcommon.c | 24 +++++++++------- src/or/rendmid.c | 8 +++--- src/or/rendservice.c | 6 ++-- 19 files changed, 167 insertions(+), 89 deletions(-) diff --git a/ChangeLog b/ChangeLog index 77d6f16ec4..165862db0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ Changes in version 0.2.2.7-alpha - 2009-??-?? timeout schedule for how many seconds until we detach a stream from a circuit and try a new circuit. If your network is particularly slow, you might want to set this to a number like 60. + - New options for SafeLogging to allow scrubbing only log messages + generated while acting as a relay. o Minor bugfixes: - Fix compilation on OSX 10.3, which has a stub mlockall() but diff --git a/doc/tor.1.in b/doc/tor.1.in index 4bcab6d04d..b5f529a3fb 100644 --- a/doc/tor.1.in +++ b/doc/tor.1.in @@ -377,11 +377,16 @@ no effect on Windows; instead you should use the --service command-line option. (Default: 0) .LP .TP -\fBSafeLogging \fR\fB0\fR|\fB1\fP -If 1, Tor replaces potentially sensitive strings in the logs -(e.g. addresses) with the string [scrubbed]. This way logs can still be +\fBSafeLogging \fR\fB0\fR|\fB1\fR|\fBrelay\fP +Tor can scrub potentially sensitive strings from log messages (e.g. addresses) +by replacing them with the string [scrubbed]. This way logs can still be useful, but they don't leave behind personally identifying information -about what sites a user might have visited. (Default: 1) +about what sites a user might have visited. + +If this option is set to 0, Tor will not perform any scrubbing, if it is set +to 1, all potentially sensitive strings are replaced. If it is set to +relay, all log messages generated when acting as a relay are sanitized, but all +messages generated when acting as a client are not. (Default: 1) .LP .TP \fBUser \fR\fIUID\fP diff --git a/src/or/buffers.c b/src/or/buffers.c index 1a1b2077cc..4448eaa345 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -1490,7 +1490,8 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req, return -1; } log_debug(LD_APP, - "socks4: successfully read destip (%s)", safe_str(tmpbuf)); + "socks4: successfully read destip (%s)", + safe_str(tmpbuf)); socks4_prot = socks4; } diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 91fa9d8db5..34d9ba6f20 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1229,7 +1229,8 @@ circuit_handle_first_hop(origin_circuit_t *circ) /* not currently connected in a useful way. */ const char *name = strlen(firsthop->extend_info->nickname) ? firsthop->extend_info->nickname : fmt_addr(&firsthop->extend_info->addr); - log_info(LD_CIRC, "Next router is %s: %s ", safe_str(name), msg?msg:"???"); + log_info(LD_CIRC, "Next router is %s: %s ", + safe_str(name), msg?msg:"???"); circ->_base.n_hop = extend_info_dup(firsthop->extend_info); if (should_launch) { diff --git a/src/or/command.c b/src/or/command.c index 8ed5a96019..2e8c97f1f5 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -405,7 +405,8 @@ command_process_relay_cell(cell_t *cell, or_connection_t *conn) log_fn(LOG_PROTOCOL_WARN, LD_OR, "Received too many RELAY_EARLY cells on circ %d from %s:%d." " Closing circuit.", - cell->circ_id, safe_str(conn->_base.address), conn->_base.port); + cell->circ_id, safe_str_relay(conn->_base.address), + conn->_base.port); circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); return; } @@ -513,7 +514,8 @@ command_process_versions_cell(var_cell_t *cell, or_connection_t *conn) conn->handshake_state->received_versions = 1; log_info(LD_OR, "Negotiated version %d with %s:%d; sending NETINFO.", - highest_supported_version, safe_str(conn->_base.address), + highest_supported_version, + safe_str(conn->_base.address), conn->_base.port); tor_assert(conn->link_proto >= 2); @@ -627,8 +629,8 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn) else log_info(LD_OR, "Got good NETINFO cell from %s:%d; OR connection is now " "open, using protocol version %d", - safe_str(conn->_base.address), conn->_base.port, - (int)conn->link_proto); + safe_str(conn->_base.address), + conn->_base.port, (int)conn->link_proto); assert_connection_ok(TO_CONN(conn),time(NULL)); } diff --git a/src/or/config.c b/src/or/config.c index 66f9d0488b..bd7fe22946 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -302,7 +302,7 @@ static config_var_t _option_vars[] = { OBSOLETE("RouterFile"), V(RunAsDaemon, BOOL, "0"), V(RunTesting, BOOL, "0"), - V(SafeLogging, BOOL, "1"), + V(SafeLogging, STRING, "1"), V(SafeSocks, BOOL, "0"), V(ServerDNSAllowBrokenConfig, BOOL, "1"), V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"), @@ -886,14 +886,28 @@ config_free_all(void) tor_free(global_dirfrontpagecontents); } -/** If options->SafeLogging is on, return a not very useful string, +/** If options->SafeLogging is "1", return a not very useful string, * else return address. */ const char * safe_str(const char *address) { tor_assert(address); - if (get_options()->SafeLogging) + if (!strcmp(get_options()->SafeLogging, "1")) + return "[scrubbed]"; + else + return address; +} + +/** If options->SafeLogging is "1" or "relay", return a not very useful + * string, else return address. + */ +const char * +safe_str_relay(const char *address) +{ + tor_assert(address); + if (!strcmp(get_options()->SafeLogging, "1") || + !strcmp(get_options()->SafeLogging, "relay")) return "[scrubbed]"; else return address; @@ -905,7 +919,20 @@ safe_str(const char *address) const char * escaped_safe_str(const char *address) { - if (get_options()->SafeLogging) + if (!strcmp(get_options()->SafeLogging, "1")) + return "[scrubbed]"; + else + return escaped(address); +} + +/** Equivalent to escaped(safe_str_relay(address)). See reentrancy note on + * escaped(): don't use this outside the main thread, or twice in the same + * log statement. */ +const char * +escaped_safe_str_relay(const char *address) +{ + if (!strcasecmp(get_options()->SafeLogging, "1") || + !strcasecmp(get_options()->SafeLogging, "relay")) return "[scrubbed]"; else return escaped(address); @@ -3355,6 +3382,18 @@ options_validate(or_options_t *old_options, or_options_t *options, }); } + if (options->SafeLogging && + !(!strcasecmp(options->SafeLogging, "relay") || + !strcasecmp(options->SafeLogging, "1") || + !strcasecmp(options->SafeLogging, "0"))) + { + r = tor_snprintf(buf, sizeof(buf), + "Unrecognized value '%s' in SafeLogging", + options->SafeLogging); + *msg = tor_strdup(r >= 0 ? buf : "internal error"); + return -1; + } + if (compute_publishserverdescriptor(options) < 0) { r = tor_snprintf(buf, sizeof(buf), "Unrecognized value in PublishServerDescriptor"); diff --git a/src/or/connection.c b/src/or/connection.c index 0600d9711f..74d2bf26ab 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1262,7 +1262,8 @@ connection_connect(connection_t *conn, const char *address, dest_addr_len = tor_addr_to_sockaddr(addr, port, dest_addr, sizeof(addrbuf)); tor_assert(dest_addr_len > 0); - log_debug(LD_NET,"Connecting to %s:%u.",escaped_safe_str(address),port); + log_debug(LD_NET, "Connecting to %s:%u.", + escaped_safe_str(address), port); if (connect(s, dest_addr, dest_addr_len) < 0) { int e = tor_socket_errno(s); @@ -1270,7 +1271,8 @@ connection_connect(connection_t *conn, const char *address, /* yuck. kill it. */ *socket_error = e; log_info(LD_NET, - "connect() to %s:%u failed: %s",escaped_safe_str(address), + "connect() to %s:%u failed: %s", + escaped_safe_str(address), port, tor_socket_strerror(e)); tor_close_socket(s); return -1; @@ -1284,7 +1286,8 @@ connection_connect(connection_t *conn, const char *address, /* it succeeded. we're connected. */ log_fn(inprogress?LOG_DEBUG:LOG_INFO, LD_NET, - "Connection to %s:%u %s (sock %d).",escaped_safe_str(address), + "Connection to %s:%u %s (sock %d).", + escaped_safe_str(address), port, inprogress?"in progress":"established", s); conn->s = s; if (connection_add(conn) < 0) /* no space, forget it */ diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 75a57fedd5..0b7db32f44 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -330,8 +330,8 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn) tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING); log_info(LD_EXIT,"Exit connection to %s:%u (%s) established.", - escaped_safe_str(conn->address),conn->port, - safe_str(fmt_addr(&conn->addr))); + escaped_safe_str_relay(conn->address), conn->port, + safe_str_relay(fmt_addr(&conn->addr))); rep_hist_note_exit_stream_opened(conn->port); @@ -428,7 +428,8 @@ connection_ap_expire_beginning(void) log_fn(severity, LD_APP, "Tried for %d seconds to get a connection to %s:%d. " "Giving up. (%s)", - seconds_since_born, safe_str(conn->socks_request->address), + seconds_since_born, + safe_str(conn->socks_request->address), conn->socks_request->port, conn_state_to_string(CONN_TYPE_AP, conn->_base.state)); connection_mark_unattached_ap(conn, END_STREAM_REASON_TIMEOUT); @@ -465,7 +466,8 @@ connection_ap_expire_beginning(void) log_fn(cutoff < 15 ? LOG_INFO : severity, LD_APP, "We tried for %d seconds to connect to '%s' using exit '%s'." " Retrying on a new circuit.", - seconds_idle, safe_str(conn->socks_request->address), + seconds_idle, + safe_str(conn->socks_request->address), conn->cpath_layer ? conn->cpath_layer->extend_info->nickname : "*unnamed*"); /* send an end down the circuit */ @@ -917,7 +919,9 @@ addressmap_register(const char *address, char *new_address, time_t expires, if (expires > 1) { log_info(LD_APP,"Temporary addressmap ('%s' to '%s') not performed, " "since it's already mapped to '%s'", - safe_str(address), safe_str(new_address), safe_str(ent->new_address)); + safe_str(address), + safe_str(new_address), + safe_str(ent->new_address)); tor_free(new_address); return; } @@ -936,7 +940,8 @@ addressmap_register(const char *address, char *new_address, time_t expires, ent->source = source; log_info(LD_CONFIG, "Addressmap: (re)mapped '%s' to '%s'", - safe_str(address), safe_str(ent->new_address)); + safe_str(address), + safe_str(ent->new_address)); control_event_address_mapped(address, ent->new_address, expires, NULL); } @@ -956,7 +961,8 @@ client_dns_incr_failures(const char *address) if (ent->num_resolve_failures < SHORT_MAX) ++ent->num_resolve_failures; /* don't overflow */ log_info(LD_APP, "Address %s now has %d resolve failures.", - safe_str(address), ent->num_resolve_failures); + safe_str(address), + ent->num_resolve_failures); return ent->num_resolve_failures; } @@ -1235,7 +1241,9 @@ addressmap_register_virtual_address(int type, char *new_address) log_warn(LD_BUG, "Internal confusion: I thought that '%s' was mapped to by " "'%s', but '%s' really maps to '%s'. This is a harmless bug.", - safe_str(new_address), safe_str(*addrp), safe_str(*addrp), + safe_str(new_address), + safe_str(*addrp), + safe_str(*addrp), ent?safe_str(ent->new_address):"(nothing)"); } @@ -1257,7 +1265,8 @@ addressmap_register_virtual_address(int type, char *new_address) (type == RESOLVED_TYPE_IPV4) ? vent->ipv4_address : vent->hostname_address)); log_info(LD_APP, "Map from %s to %s okay.", - safe_str(*addrp),safe_str(new_address)); + safe_str(*addrp), + safe_str(new_address)); } #endif @@ -1422,7 +1431,8 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, RESOLVED_TYPE_IPV4, tor_strdup(socks->address)); tor_assert(new_addr); log_info(LD_APP, "Automapping %s to %s", - escaped_safe_str(socks->address), safe_str(new_addr)); + escaped_safe_str(socks->address), + safe_str(new_addr)); strlcpy(socks->address, new_addr, sizeof(socks->address)); } } @@ -1478,7 +1488,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, * information. */ log_warn(LD_APP,"Missing mapping for virtual address '%s'. Refusing.", - socks->address); /* don't safe_str() this yet. */ + socks->address); /* don't safe_str() this yet. XXX When? -Seb */ connection_mark_unattached_ap(conn, END_STREAM_REASON_INTERNAL); return -1; } @@ -2178,7 +2188,8 @@ connection_ap_make_link(char *address, uint16_t port, edge_connection_t *conn; log_info(LD_APP,"Making internal %s tunnel to %s:%d ...", - want_onehop ? "direct" : "anonymized" , safe_str(address),port); + want_onehop ? "direct" : "anonymized", + safe_str(address), port); conn = edge_connection_new(CONN_TYPE_AP, AF_INET); conn->_base.linked = 1; /* so that we can add it safely below. */ diff --git a/src/or/connection_or.c b/src/or/connection_or.c index bbd64393c3..ba962f69de 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -774,7 +774,8 @@ connection_tls_start_handshake(or_connection_t *conn, int receiving) { conn->_base.state = OR_CONN_STATE_TLS_HANDSHAKING; conn->tls = tor_tls_new(conn->_base.s, receiving); - tor_tls_set_logged_address(conn->tls, escaped_safe_str(conn->_base.address)); + tor_tls_set_logged_address(conn->tls, // XXX client and relay? + escaped_safe_str_relay(conn->_base.address)); if (!conn->tls) { log_warn(LD_BUG,"tor_tls_new failed. Closing."); return -1; @@ -914,7 +915,8 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn, or_options_t *options = get_options(); int severity = server_mode(options) ? LOG_PROTOCOL_WARN : LOG_WARN; const char *safe_address = - started_here ? conn->_base.address : safe_str(conn->_base.address); + started_here ? conn->_base.address : + safe_str(conn->_base.address); const char *conn_type = started_here ? "outgoing" : "incoming"; int has_cert = 0, has_identity=0; diff --git a/src/or/control.c b/src/or/control.c index 009994302e..101b1a58af 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1265,7 +1265,8 @@ handle_control_mapaddress(control_connection_t *conn, uint32_t len, "not of expected form 'foo=bar'.", line); smartlist_add(reply, ans); log_info(LD_CONTROL, "Skipping MapAddress '%s': wrong " - "number of items.", safe_str(line)); + "number of items.", + safe_str(line)); } SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp)); smartlist_clear(elts); diff --git a/src/or/directory.c b/src/or/directory.c index 427f5d8c08..1c599baf75 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -2921,7 +2921,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, const char *query = url + strlen("/tor/rendezvous2/"); if (strlen(query) == REND_DESC_ID_V2_LEN_BASE32) { log_info(LD_REND, "Got a v2 rendezvous descriptor request for ID '%s'", - safe_str(query)); + safe_str_relay(query)); switch (rend_cache_lookup_v2_desc_as_dir(query, &descp)) { case 1: /* valid */ write_http_response_header(conn, strlen(descp), 0, 0); @@ -3243,7 +3243,7 @@ directory_handle_command(dir_connection_t *conn) case -1: /* overflow */ log_warn(LD_DIRSERV, "Request too large from address '%s' to DirPort. Closing.", - safe_str(conn->_base.address)); + safe_str_relay(conn->_base.address)); return -1; case 0: log_debug(LD_DIRSERV,"command not all here yet."); diff --git a/src/or/dns.c b/src/or/dns.c index ffd30c89d8..6a56748339 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -394,12 +394,12 @@ purge_expired_resolves(time_t now) log_debug(LD_EXIT, "Expiring a dns resolve %s that's still pending. Forgot to " "cull it? DNS resolve didn't tell us about the timeout?", - escaped_safe_str(resolve->address)); + escaped_safe_str_relay(resolve->address)); } else if (resolve->state == CACHE_STATE_CACHED_VALID || resolve->state == CACHE_STATE_CACHED_FAILED) { log_debug(LD_EXIT, "Forgetting old cached resolve (address %s, expires %lu)", - escaped_safe_str(resolve->address), + escaped_safe_str_relay(resolve->address), (unsigned long)resolve->expire); tor_assert(!resolve->pending_connections); } else { @@ -667,7 +667,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, if (address_is_invalid_destination(exitconn->_base.address, 0)) { log(LOG_PROTOCOL_WARN, LD_EXIT, "Rejecting invalid destination address %s", - escaped_safe_str(exitconn->_base.address)); + escaped_safe_str_relay(exitconn->_base.address)); return -1; } @@ -693,12 +693,12 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, if (!is_reverse || !is_resolve) { if (!is_reverse) log_info(LD_EXIT, "Bad .in-addr.arpa address \"%s\"; sending error.", - escaped_safe_str(exitconn->_base.address)); + escaped_safe_str_relay(exitconn->_base.address)); else if (!is_resolve) log_info(LD_EXIT, "Attempt to connect to a .in-addr.arpa address \"%s\"; " "sending error.", - escaped_safe_str(exitconn->_base.address)); + escaped_safe_str_relay(exitconn->_base.address)); return -1; } @@ -720,12 +720,12 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, resolve->pending_connections = pending_connection; log_debug(LD_EXIT,"Connection (fd %d) waiting for pending DNS " "resolve of %s", exitconn->_base.s, - escaped_safe_str(exitconn->_base.address)); + escaped_safe_str_relay(exitconn->_base.address)); return 0; case CACHE_STATE_CACHED_VALID: log_debug(LD_EXIT,"Connection (fd %d) found cached answer for %s", exitconn->_base.s, - escaped_safe_str(resolve->address)); + escaped_safe_str_relay(resolve->address)); exitconn->address_ttl = resolve->ttl; if (resolve->is_reverse) { tor_assert(is_resolve); @@ -737,7 +737,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, case CACHE_STATE_CACHED_FAILED: log_debug(LD_EXIT,"Connection (fd %d) found cached error for %s", exitconn->_base.s, - escaped_safe_str(exitconn->_base.address)); + escaped_safe_str_relay(exitconn->_base.address)); return -1; case CACHE_STATE_DONE: log_err(LD_BUG, "Found a 'DONE' dns resolve still in the cache."); @@ -763,7 +763,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, set_expiry(resolve, now + RESOLVE_MAX_TIMEOUT); log_debug(LD_EXIT,"Launching %s.", - escaped_safe_str(exitconn->_base.address)); + escaped_safe_str_relay(exitconn->_base.address)); assert_cache_ok(); return launch_resolve(exitconn); @@ -832,7 +832,7 @@ connection_dns_remove(edge_connection_t *conn) resolve = HT_FIND(cache_map, &cache_root, &search); if (!resolve) { log_notice(LD_BUG, "Address %s is not pending. Dropping.", - escaped_safe_str(conn->_base.address)); + escaped_safe_str_relay(conn->_base.address)); return; } @@ -846,7 +846,8 @@ connection_dns_remove(edge_connection_t *conn) tor_free(pend); log_debug(LD_EXIT, "First connection (fd %d) no longer waiting " "for resolve of %s", - conn->_base.s, escaped_safe_str(conn->_base.address)); + conn->_base.s, + escaped_safe_str_relay(conn->_base.address)); return; } else { for ( ; pend->next; pend = pend->next) { @@ -856,7 +857,7 @@ connection_dns_remove(edge_connection_t *conn) tor_free(victim); log_debug(LD_EXIT, "Connection (fd %d) no longer waiting for resolve of %s", - conn->_base.s, escaped_safe_str(conn->_base.address)); + conn->_base.s, escaped_safe_str_relay(conn->_base.address)); return; /* more are pending */ } } @@ -890,7 +891,7 @@ dns_cancel_pending_resolve(const char *address) if (resolve->pending_connections) { log_warn(LD_BUG, "Address %s is not pending but has pending connections!", - escaped_safe_str(address)); + escaped_safe_str_relay(address)); tor_fragile_assert(); } return; @@ -899,7 +900,7 @@ dns_cancel_pending_resolve(const char *address) if (!resolve->pending_connections) { log_warn(LD_BUG, "Address %s is pending but has no pending connections!", - escaped_safe_str(address)); + escaped_safe_str_relay(address)); tor_fragile_assert(); return; } @@ -908,7 +909,7 @@ dns_cancel_pending_resolve(const char *address) /* mark all pending connections to fail */ log_debug(LD_EXIT, "Failing all connections waiting on DNS resolve of %s", - escaped_safe_str(address)); + escaped_safe_str_relay(address)); while (resolve->pending_connections) { pend = resolve->pending_connections; pend->conn->_base.state = EXIT_CONN_STATE_RESOLVEFAILED; @@ -1016,7 +1017,7 @@ dns_found_answer(const char *address, uint8_t is_reverse, uint32_t addr, int is_test_addr = is_test_address(address); if (!is_test_addr) log_info(LD_EXIT,"Resolved unasked address %s; caching anyway.", - escaped_safe_str(address)); + escaped_safe_str_relay(address)); add_answer_to_cache(address, is_reverse, addr, hostname, outcome, ttl); return; } @@ -1029,7 +1030,7 @@ dns_found_answer(const char *address, uint8_t is_reverse, uint32_t addr, if (!is_test_addr) log_notice(LD_EXIT, "Resolved %s which was already resolved; ignoring", - escaped_safe_str(address)); + escaped_safe_str_relay(address)); tor_assert(resolve->pending_connections == NULL); return; } @@ -1296,15 +1297,15 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses, if (answer_is_wildcarded(answer_buf)) { log_debug(LD_EXIT, "eventdns said that %s resolves to ISP-hijacked " "address %s; treating as a failure.", - safe_str(escaped_address), - escaped_safe_str(answer_buf)); + safe_str_relay(escaped_address), + escaped_safe_str_relay(answer_buf)); was_wildcarded = 1; addr = 0; status = DNS_RESOLVE_FAILED_PERMANENT; } else { log_debug(LD_EXIT, "eventdns said that %s resolves to %s", - safe_str(escaped_address), - escaped_safe_str(answer_buf)); + safe_str_relay(escaped_address), + escaped_safe_str_relay(answer_buf)); } tor_free(escaped_address); } else if (type == DNS_PTR && count) { @@ -1314,15 +1315,15 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses, status = DNS_RESOLVE_SUCCEEDED; escaped_address = esc_for_log(string_address); log_debug(LD_EXIT, "eventdns said that %s resolves to %s", - safe_str(escaped_address), - escaped_safe_str(hostname)); + safe_str_relay(escaped_address), + escaped_safe_str_relay(hostname)); tor_free(escaped_address); } else if (count) { log_warn(LD_EXIT, "eventdns returned only non-IPv4 answers for %s.", - escaped_safe_str(string_address)); + escaped_safe_str_relay(string_address)); } else { log_warn(LD_BUG, "eventdns returned no addresses or error for %s!", - escaped_safe_str(string_address)); + escaped_safe_str_relay(string_address)); } } else { if (evdns_err_is_transient(result)) @@ -1365,13 +1366,13 @@ launch_resolve(edge_connection_t *exitconn) &a, exitconn->_base.address, AF_UNSPEC, 0); if (r == 0) { log_info(LD_EXIT, "Launching eventdns request for %s", - escaped_safe_str(exitconn->_base.address)); + escaped_safe_str_relay(exitconn->_base.address)); req = evdns_base_resolve_ipv4(the_evdns_base, exitconn->_base.address, options, evdns_callback, addr); } else if (r == 1) { log_info(LD_EXIT, "Launching eventdns reverse request for %s", - escaped_safe_str(exitconn->_base.address)); + escaped_safe_str_relay(exitconn->_base.address)); if (tor_addr_family(&a) == AF_INET) req = evdns_base_resolve_reverse(the_evdns_base, tor_addr_to_in(&a), DNS_QUERY_NO_SEARCH, @@ -1386,7 +1387,8 @@ launch_resolve(edge_connection_t *exitconn) r = 0; if (!req) { - log_warn(LD_EXIT, "eventdns rejected address %s.", escaped_safe_str(addr)); + log_warn(LD_EXIT, "eventdns rejected address %s.", + escaped_safe_str_relay(addr)); r = -1; tor_free(addr); /* There is no evdns request in progress; stop * addr from getting leaked. */ @@ -1569,7 +1571,7 @@ launch_test_addresses(int fd, short event, void *args) if (!req) { log_info(LD_EXIT, "eventdns rejected test address %s", - escaped_safe_str(address)); + escaped_safe_str_relay(address)); tor_free(a); } } SMARTLIST_FOREACH_END(address); diff --git a/src/or/main.c b/src/or/main.c index 537abcc832..4b51b5248c 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -616,8 +616,8 @@ conn_close_if_marked(int i) "something is wrong with theirs. " "(fd %d, type %s, state %d, marked at %s:%d).", (int)buf_datalen(conn->outbuf), - escaped_safe_str(conn->address), conn->s, - conn_type_to_string(conn->type), conn->state, + escaped_safe_str(conn->address), + conn->s, conn_type_to_string(conn->type), conn->state, conn->marked_for_close_file, conn->marked_for_close); } @@ -1678,7 +1678,8 @@ dumpstats(int severity) if (!connection_is_listener(conn)) { log(severity,LD_GENERAL, "Conn %d is to %s:%d.", i, - safe_str(conn->address), conn->port); + safe_str(conn->address), + conn->port); log(severity,LD_GENERAL, "Conn %d: %d bytes waiting on inbuf (len %d, last read %d secs ago)", i, diff --git a/src/or/or.h b/src/or/or.h index 2e575f5ef9..67919d99a7 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2561,8 +2561,7 @@ typedef struct { * or not (1)? */ int ShutdownWaitLength; /**< When we get a SIGINT and we're a server, how * long do we wait before exiting? */ - int SafeLogging; /**< Boolean: are we allowed to log sensitive strings - * such as addresses (0), or do we scrub them first (1)? */ + char *SafeLogging; /**< Contains "relay", "1", "0" (meaning no scrubbing). */ int SafeSocks; /**< Boolean: should we outright refuse application * connections that use socks4 or socks5-with-local-dns? */ #define LOG_PROTOCOL_WARN (get_options()->ProtocolWarnings ? \ @@ -3208,7 +3207,9 @@ or_options_t *get_options(void); int set_options(or_options_t *new_val, char **msg); void config_free_all(void); const char *safe_str(const char *address); +const char *safe_str_relay(const char *address); const char *escaped_safe_str(const char *address); +const char *escaped_safe_str_relay(const char *address); const char *get_version(void); int config_get_lines(const char *string, config_line_t **result); diff --git a/src/or/relay.c b/src/or/relay.c index 00e70d95c1..97c0815ce7 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -676,7 +676,7 @@ connection_ap_process_end_not_open( !connection_edge_is_rendezvous_stream(conn) /* avoid retry if rend */ ) { log_info(LD_APP,"Address '%s' refused due to '%s'. Considering retrying.", - safe_str(conn->socks_request->address), + safe_str_relay(conn->socks_request->address), stream_end_reason_to_string(reason)); exitrouter = router_get_by_digest(circ->build_state->chosen_exit->identity_digest); @@ -687,7 +687,7 @@ connection_ap_process_end_not_open( int ttl; if (!addr) { log_info(LD_APP,"Address '%s' resolved to 0.0.0.0. Closing,", - safe_str(conn->socks_request->address)); + safe_str_relay(conn->socks_request->address)); connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); return 0; } @@ -699,7 +699,7 @@ connection_ap_process_end_not_open( if (get_options()->ClientDNSRejectInternalAddresses && is_internal_IP(addr, 0)) { log_info(LD_APP,"Address '%s' resolved to internal. Closing,", - safe_str(conn->socks_request->address)); + safe_str_relay(conn->socks_request->address)); connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); return 0; } @@ -768,7 +768,7 @@ connection_ap_process_end_not_open( log_notice(LD_APP, "Have tried resolving or connecting to address '%s' " "at %d different places. Giving up.", - safe_str(conn->socks_request->address), + safe_str_relay(conn->socks_request->address), MAX_RESOLVE_FAILURES); /* clear the failures, so it will have a full try next time */ client_dns_clear_failures(conn->socks_request->address); diff --git a/src/or/rendclient.c b/src/or/rendclient.c index b7ea40eed7..1fbfec7c55 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -705,7 +705,8 @@ rend_client_desc_trynow(const char *query) } } else { /* 404, or fetch didn't get that far */ log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is " - "unavailable (try again later).", safe_str(query)); + "unavailable (try again later).", + safe_str(query)); connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED); } } SMARTLIST_FOREACH_END(_conn); diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 9055f981bb..73d1b5d85d 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -125,7 +125,8 @@ rend_compute_v2_desc_id(char *desc_id_out, const char *service_id, if (!service_id || strlen(service_id) != REND_SERVICE_ID_LEN_BASE32) { log_warn(LD_REND, "Could not compute v2 descriptor ID: " - "Illegal service ID: %s", safe_str(service_id)); + "Illegal service ID: %s", + safe_str_relay(service_id)); return -1; } if (replica >= REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS) { @@ -954,7 +955,7 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc) if (base32_decode(desc_id_digest, DIGEST_LEN, desc_id, REND_DESC_ID_V2_LEN_BASE32) < 0) { log_warn(LD_REND, "Descriptor ID contains illegal characters: %s", - safe_str(desc_id)); + safe_str_relay(desc_id)); return -1; } /* Determine if we are responsible. */ @@ -1010,13 +1011,15 @@ rend_cache_store(const char *desc, size_t desc_len, int published) now = time(NULL); if (parsed->timestamp < now-REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) { log_fn(LOG_PROTOCOL_WARN, LD_REND, - "Service descriptor %s is too old.", safe_str(query)); + "Service descriptor %s is too old.", + safe_str(query)); rend_service_descriptor_free(parsed); return -2; } if (parsed->timestamp > now+REND_CACHE_MAX_SKEW) { log_fn(LOG_PROTOCOL_WARN, LD_REND, - "Service descriptor %s is too far in the future.", safe_str(query)); + "Service descriptor %s is too far in the future.", + safe_str(query)); rend_service_descriptor_free(parsed); return -2; } @@ -1036,7 +1039,8 @@ rend_cache_store(const char *desc, size_t desc_len, int published) e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key); if (e && e->parsed->timestamp > parsed->timestamp) { log_info(LD_REND,"We already have a newer service descriptor %s with the " - "same ID and version.", safe_str(query)); + "same ID and version.", + safe_str(query)); rend_service_descriptor_free(parsed); return 0; } @@ -1122,14 +1126,14 @@ rend_cache_store_v2_desc_as_dir(const char *desc) /* Is descriptor too old? */ if (parsed->timestamp < now - REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) { log_info(LD_REND, "Service descriptor with desc ID %s is too old.", - safe_str(desc_id_base32)); + safe_str_relay(desc_id_base32)); goto skip; } /* Is descriptor too far in the future? */ if (parsed->timestamp > now + REND_CACHE_MAX_SKEW) { log_info(LD_REND, "Service descriptor with desc ID %s is too far in the " "future.", - safe_str(desc_id_base32)); + safe_str_relay(desc_id_base32)); goto skip; } /* Do we already have a newer descriptor? */ @@ -1137,13 +1141,13 @@ rend_cache_store_v2_desc_as_dir(const char *desc) if (e && e->parsed->timestamp > parsed->timestamp) { log_info(LD_REND, "We already have a newer service descriptor with the " "same desc ID %s and version.", - safe_str(desc_id_base32)); + safe_str_relay(desc_id_base32)); goto skip; } /* Do we already have this descriptor? */ if (e && !strcmp(desc, e->desc)) { log_info(LD_REND, "We already have this service descriptor with desc " - "ID %s.", safe_str(desc_id_base32)); + "ID %s.", safe_str_relay(desc_id_base32)); e->received = time(NULL); goto skip; } @@ -1161,7 +1165,7 @@ rend_cache_store_v2_desc_as_dir(const char *desc) e->len = encoded_size; log_info(LD_REND, "Successfully stored service descriptor with desc ID " "'%s' and len %d.", - safe_str(desc_id_base32), (int)encoded_size); + safe_str_relay(desc_id_base32), (int)encoded_size); number_stored++; goto advance; skip: diff --git a/src/or/rendmid.c b/src/or/rendmid.c index 57f5b6daed..b51d4e89d8 100644 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@ -89,7 +89,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const char *request, c = NULL; while ((c = circuit_get_intro_point(pk_digest))) { log_info(LD_REND, "Replacing old circuit for service %s", - safe_str(serviceid)); + safe_str_relay(serviceid)); circuit_mark_for_close(TO_CIRCUIT(c), END_CIRC_REASON_FINISHED); /* Now it's marked, and it won't be returned next time. */ } @@ -108,7 +108,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const char *request, log_info(LD_REND, "Established introduction point on circuit %d for service %s", - circ->p_circ_id, safe_str(serviceid)); + circ->p_circ_id, safe_str_relay(serviceid)); return 0; truncated: @@ -162,14 +162,14 @@ rend_mid_introduce(or_circuit_t *circ, const char *request, size_t request_len) log_info(LD_REND, "No intro circ found for INTRODUCE1 cell (%s) from circuit %d; " "responding with nack.", - safe_str(serviceid), circ->p_circ_id); + safe_str_relay(serviceid), circ->p_circ_id); goto err; } log_info(LD_REND, "Sending introduction request for service %s " "from circ %d to circ %d", - safe_str(serviceid), circ->p_circ_id, + safe_str_relay(serviceid), circ->p_circ_id, intro_circ->p_circ_id); /* Great. Now we just relay the cell down the circuit. */ diff --git a/src/or/rendservice.c b/src/or/rendservice.c index b6981d6258..faadb28b04 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1117,14 +1117,16 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, if (!launched) { /* give up */ log_warn(LD_REND, "Giving up launching first hop of circuit to rendezvous " "point %s for service %s.", - escaped_safe_str(extend_info->nickname), serviceid); + escaped_safe_str(extend_info->nickname), + serviceid); reason = END_CIRC_REASON_CONNECTFAILED; goto err; } log_info(LD_REND, "Accepted intro; launching circuit to %s " "(cookie %s) for service %s.", - escaped_safe_str(extend_info->nickname), hexcookie, serviceid); + escaped_safe_str(extend_info->nickname), + hexcookie, serviceid); tor_assert(launched->build_state); /* Fill in the circuit's state. */ launched->rend_data = tor_malloc_zero(sizeof(rend_data_t));