diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuitbuild.c | 3 | ||||
-rw-r--r-- | src/or/command.c | 42 | ||||
-rw-r--r-- | src/or/config.c | 9 | ||||
-rw-r--r-- | src/or/connection.c | 2 | ||||
-rw-r--r-- | src/or/connection_or.c | 6 | ||||
-rw-r--r-- | src/or/control.c | 33 | ||||
-rw-r--r-- | src/or/dirserv.c | 12 | ||||
-rw-r--r-- | src/or/eventdns.c | 21 | ||||
-rw-r--r-- | src/or/relay.c | 6 | ||||
-rw-r--r-- | src/or/relay.h | 5 | ||||
-rw-r--r-- | src/or/rendclient.c | 24 | ||||
-rw-r--r-- | src/or/rendservice.c | 9 | ||||
-rw-r--r-- | src/or/router.c | 2 | ||||
-rw-r--r-- | src/or/routerparse.c | 5 |
14 files changed, 135 insertions, 44 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index c4b697c9a6..b04bd10120 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4997,7 +4997,6 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge) DIR_PURPOSE_FETCH_SERVERDESC)) return; /* it's already on the way */ - address = tor_dup_addr(&bridge->addr); if (routerset_contains_bridge(options->ExcludeNodes, bridge)) { download_status_mark_impossible(&bridge->fetch_status); log_warn(LD_APP, "Not using bridge at %s: it is in ExcludeNodes.", @@ -5005,6 +5004,8 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge) return; } + address = tor_dup_addr(&bridge->addr); + directory_initiate_command(address, &bridge->addr, bridge->port, 0, 0, /* does not matter */ diff --git a/src/or/command.c b/src/or/command.c index e68b6bfc6a..023f2bead5 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -985,15 +985,24 @@ command_process_certs_cell(var_cell_t *cell, or_connection_t *conn) } if (conn->handshake_state->started_here) { + int severity; if (! (id_cert && link_cert)) ERR("The certs we wanted were missing"); /* Okay. We should be able to check the certificates now. */ if (! tor_tls_cert_matches_key(conn->tls, link_cert)) { ERR("The link certificate didn't match the TLS public key"); } - if (! tor_tls_cert_is_valid(link_cert, id_cert, 0)) + /* Note that this warns more loudly about time and validity if we were + * _trying_ to connect to an authority, not necessarily if we _did_ connect + * to one. */ + if (router_digest_is_trusted_dir(conn->identity_digest)) + severity = LOG_WARN; + else + severity = LOG_PROTOCOL_WARN; + + if (! tor_tls_cert_is_valid(severity, link_cert, id_cert, 0)) ERR("The link certificate was not valid"); - if (! tor_tls_cert_is_valid(id_cert, id_cert, 1)) + if (! tor_tls_cert_is_valid(severity, id_cert, id_cert, 1)) ERR("The ID certificate was not valid"); conn->handshake_state->authenticated = 1; @@ -1026,9 +1035,9 @@ command_process_certs_cell(var_cell_t *cell, or_connection_t *conn) ERR("The certs we wanted were missing"); /* Remember these certificates so we can check an AUTHENTICATE cell */ - if (! tor_tls_cert_is_valid(auth_cert, id_cert, 1)) + if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, auth_cert, id_cert, 1)) ERR("The authentication certificate was not valid"); - if (! tor_tls_cert_is_valid(id_cert, id_cert, 1)) + if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, id_cert, id_cert, 1)) ERR("The ID certificate was not valid"); log_info(LD_OR, "Got some good certificates from %s:%d: " @@ -1100,7 +1109,14 @@ command_process_auth_challenge_cell(var_cell_t *cell, or_connection_t *conn) conn->handshake_state->received_auth_challenge = 1; - if (use_type && public_server_mode(get_options())) { + if (! public_server_mode(get_options())) { + /* If we're not a public server then we don't want to authenticate on a + connection we originated, and we already sent a NETINFO cell when we + got the CERTS cell. We have nothing more to do. */ + return; + } + + if (use_type >= 0) { log_info(LD_OR, "Got an AUTH_CHALLENGE cell from %s:%d: Sending " "authentication", safe_str(conn->_base.address), conn->_base.port); @@ -1110,16 +1126,18 @@ command_process_auth_challenge_cell(var_cell_t *cell, or_connection_t *conn) connection_mark_for_close(TO_CONN(conn)); return; } - if (connection_or_send_netinfo(conn) < 0) { - log_warn(LD_OR, "Couldn't send netinfo cell"); - connection_mark_for_close(TO_CONN(conn)); - return; - } } else { - log_info(LD_OR, "Got an AUTH_CHALLENGE cell from %s:%d: Not " - "authenticating", + log_info(LD_OR, "Got an AUTH_CHALLENGE cell from %s:%d, but we don't " + "know any of its authentication types. Not authenticating.", safe_str(conn->_base.address), conn->_base.port); } + + if (connection_or_send_netinfo(conn) < 0) { + log_warn(LD_OR, "Couldn't send netinfo cell"); + connection_mark_for_close(TO_CONN(conn)); + return; + } + #undef ERR } diff --git a/src/or/config.c b/src/or/config.c index 1b9f9fb475..afccf2e84e 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1541,6 +1541,15 @@ options_act(const or_options_t *old_options) options->BridgeAuthoritativeDir) { time_t now = time(NULL); int print_notice = 0; + + /* If we aren't acting as a server, we can't collect stats anyway. */ + if (!server_mode(options)) { + options->CellStatistics = 0; + options->DirReqStatistics = 0; + options->EntryStatistics = 0; + options->ExitPortStatistics = 0; + } + if ((!old_options || !old_options->CellStatistics) && options->CellStatistics) { rep_hist_buffer_stats_init(now); diff --git a/src/or/connection.c b/src/or/connection.c index bf39a5cb9c..a52bf48078 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -996,6 +996,8 @@ connection_create_listener(const struct sockaddr *listensockaddr, tor_close_socket(s); goto err; } +#else + (void)options; #endif /* HAVE_SYS_UN_H */ } else { log_err(LD_BUG,"Got unexpected address family %d.", diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 684d3abd23..cce99e4d65 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -1923,7 +1923,11 @@ connection_or_send_netinfo(or_connection_t *conn) /* Their address. */ out = cell.payload + 4; - len = append_address_to_payload(out, &conn->_base.addr); + /* We use &conn->real_addr below, unless it hasn't yet been set. If it + * hasn't yet been set, we know that _base.addr hasn't been tampered with + * yet either. */ + len = append_address_to_payload(out, !tor_addr_is_null(&conn->real_addr) + ? &conn->real_addr : &conn->_base.addr); if (len<0) return -1; out += len; diff --git a/src/or/control.c b/src/or/control.c index 1fdbac281c..109eb8857b 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1055,7 +1055,10 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len, int bad_cookie=0, bad_password=0; smartlist_t *sl = NULL; - if (TOR_ISXDIGIT(body[0])) { + if (!len) { + password = tor_strdup(""); + password_len = 0; + } else if (TOR_ISXDIGIT(body[0])) { cp = body; while (TOR_ISXDIGIT(*cp)) ++cp; @@ -1072,9 +1075,6 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len, tor_free(password); return 0; } - } else if (TOR_ISSPACE(body[0])) { - password = tor_strdup(""); - password_len = 0; } else { if (!decode_escaped_string(body, len, &password, &password_len)) { connection_write_str_to_buf("551 Invalid quoted string. You need " @@ -1597,6 +1597,8 @@ getinfo_helper_dir(control_connection_t *control_conn, *answer = tor_strndup(body, ri->cache_info.signed_descriptor_len); } } else if (!strcmpstart(question, "desc/name/")) { + /* XXX023 Setting 'warn_if_unnamed' here is a bit silly -- the + * warning goes to the user, not to the controller. */ ri = router_get_by_nickname(question+strlen("desc/name/"),1); if (ri) { const char *body = signed_descriptor_get_body(&ri->cache_info); @@ -1640,6 +1642,25 @@ getinfo_helper_dir(control_connection_t *control_conn, *answer = smartlist_join_strings(sl, "", 0, NULL); SMARTLIST_FOREACH(sl, char *, c, tor_free(c)); smartlist_free(sl); + } else if (!strcmpstart(question, "md/id/")) { + const node_t *node = node_get_by_hex_id(question+strlen("md/id/")); + const microdesc_t *md = NULL; + if (node) md = node->md; + if (md) { + tor_assert(md->body); + *answer = tor_strndup(md->body, md->bodylen); + } + } else if (!strcmpstart(question, "md/name/")) { + /* XXX023 Setting 'warn_if_unnamed' here is a bit silly -- the + * warning goes to the user, not to the controller. */ + const node_t *node = node_get_by_nickname(question+strlen("md/name/"), 1); + /* XXXX duplicated code */ + const microdesc_t *md = NULL; + if (node) md = node->md; + if (md) { + tor_assert(md->body); + *answer = tor_strndup(md->body, md->bodylen); + } } else if (!strcmpstart(question, "desc-annotations/id/")) { ri = router_get_by_hexdigest(question+ strlen("desc-annotations/id/")); @@ -2034,6 +2055,8 @@ static const getinfo_item_t getinfo_items[] = { ITEM("desc/all-recent", dir, "All non-expired, non-superseded router descriptors."), ITEM("desc/all-recent-extrainfo-hack", dir, NULL), /* Hack. */ + PREFIX("md/id/", dir, "Microdescriptors by ID"), + PREFIX("md/name/", dir, "Microdescriptors by name"), PREFIX("extra-info/digest/", dir, "Extra-info documents by digest."), PREFIX("net/listeners/", listeners, "Bound addresses by type"), ITEM("ns/all", networkstatus, @@ -3095,7 +3118,7 @@ connection_control_process_inbuf(control_connection_t *conn) args = conn->incoming_cmd+cmd_len+1; tor_assert(data_len>(size_t)cmd_len); data_len -= (cmd_len+1); /* skip the command and NUL we added after it */ - while (*args == ' ' || *args == '\t') { + while (TOR_ISSPACE(*args)) { ++args; --data_len; } diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 288fca99b8..e4cbcaaded 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2308,7 +2308,8 @@ is_router_version_good_for_possible_guard(const char *platform) tor_assert(platform); - if (strcmpstart(platform,"Tor ")) /* nonstandard Tor; be safe and say yes */ + /* nonstandard Tor; be safe and say yes */ + if (strcmpstart(platform,"Tor ")) return 1; start = (char *)eat_whitespace(platform+3); @@ -2887,7 +2888,7 @@ generate_v2_networkstatus_opinion(void) goto done; } - contact = get_options()->ContactInfo; + contact = options->ContactInfo; if (!contact) contact = "(none)"; @@ -2970,7 +2971,7 @@ generate_v2_networkstatus_opinion(void) }); if (tor_snprintf(outp, endp-outp, "directory-signature %s\n", - get_options()->Nickname)<0) { + options->Nickname)<0) { log_warn(LD_BUG, "Unable to write signature line."); goto done; } @@ -3590,8 +3591,9 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn) if (options->BridgeAuthoritativeDir && by_fp) { const routerinfo_t *router = router_get_by_id_digest(sd->identity_digest); - tor_assert(router); - if (router->purpose == ROUTER_PURPOSE_BRIDGE) + /* router can be NULL here when the bridge auth is asked for its own + * descriptor. */ + if (router && router->purpose == ROUTER_PURPOSE_BRIDGE) rep_hist_note_desc_served(sd->identity_digest); } body = signed_descriptor_get_body(sd); diff --git a/src/or/eventdns.c b/src/or/eventdns.c index 7fe376baff..7cd5d80afb 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -1,12 +1,18 @@ -/* The original version of this module was written by Adam Langley; for - * a history of modifications, check out the subversion logs. +/* READ THIS COMMENT BEFORE HACKING THIS FILE. * - * When editing this module, try to keep it re-mergeable by Adam. Don't - * reformat the whitespace, add Tor dependencies, or so on. + * This eventdns.c copy has diverged a bit from Libevent's version, and it's + * no longer easy to resynchronize them. Once Tor requires Libevent 2.0, we + * will just dump this file and use Libevent's evdns code. * - * TODO: - * - Replace all externally visible magic numbers with #defined constants. - * - Write documentation for APIs of all external functions. + * Therefore, you probably shouldn't make any change here without making it to + * Libevent as well: it's not good for the implementation to diverge even + * more. Also, we can't shouldn't wantonly the API here (since Libevent APIs + * can't change in ways that break user behavior). Also, we shouldn't bother + * with cosmetic changes: the whole module is slated for demolition, so + * there's no point dusting the linebreaks or re-painting the parser. + * + * (We can't just drop the Libevent 2.0 evdns implementation in here instead, + * since it depends pretty heavily on parts of Libevent 2.0.) */ /* Async DNS Library @@ -75,7 +81,6 @@ #include <stdint.h> #endif #include <stdlib.h> -#include <string.h> #include <errno.h> #include <assert.h> #ifdef HAVE_UNISTD_H diff --git a/src/or/relay.c b/src/or/relay.c index 51a29a20ee..ac3114bda5 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -11,6 +11,7 @@ **/ #include <math.h> +#define RELAY_PRIVATE #include "or.h" #include "buffers.h" #include "circuitbuild.h" @@ -33,9 +34,6 @@ #include "routerlist.h" #include "routerparse.h" -static int relay_crypt(circuit_t *circ, cell_t *cell, - cell_direction_t cell_direction, - crypt_path_t **layer_hint, char *recognized); static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t *layer_hint); @@ -297,7 +295,7 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, * Return -1 to indicate that we should mark the circuit for close, * else return 0. */ -static int +int relay_crypt(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t **layer_hint, char *recognized) { diff --git a/src/or/relay.h b/src/or/relay.h index 7fce8edcaf..1cd4008bb9 100644 --- a/src/or/relay.h +++ b/src/or/relay.h @@ -66,5 +66,10 @@ void circuit_clear_cell_queue(circuit_t *circ, or_connection_t *orconn); void tor_gettimeofday_cache_clear(void); +#ifdef RELAY_PRIVATE +int relay_crypt(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, + crypt_path_t **layer_hint, char *recognized); +#endif + #endif diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 1038378de1..6a45207e29 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -1048,6 +1048,7 @@ rend_client_get_random_intro_impl(const rend_cache_entry_t *entry, /* Do we need to look up the router or is the extend info complete? */ if (!intro->extend_info->onion_key) { const node_t *node; + extend_info_t *new_extend_info; if (tor_digest_is_zero(intro->extend_info->identity_digest)) node = node_get_by_hex_id(intro->extend_info->nickname); else @@ -1058,8 +1059,18 @@ rend_client_get_random_intro_impl(const rend_cache_entry_t *entry, smartlist_del(usable_nodes, i); goto again; } - extend_info_free(intro->extend_info); - intro->extend_info = extend_info_from_node(node); + new_extend_info = extend_info_from_node(node); + if (!new_extend_info) { + log_info(LD_REND, "We don't have a descriptor for the intro-point relay " + "'%s'; trying another.", + extend_info_describe(intro->extend_info)); + smartlist_del(usable_nodes, i); + goto again; + } else { + extend_info_free(intro->extend_info); + intro->extend_info = new_extend_info; + } + tor_assert(intro->extend_info != NULL); } /* Check if we should refuse to talk to this router. */ if (strict && @@ -1079,8 +1090,13 @@ rend_client_get_random_intro_impl(const rend_cache_entry_t *entry, int rend_client_any_intro_points_usable(const rend_cache_entry_t *entry) { - return rend_client_get_random_intro_impl( - entry, get_options()->StrictNodes, 0) != NULL; + extend_info_t *extend_info = + rend_client_get_random_intro_impl(entry, get_options()->StrictNodes, 0); + + int rv = (extend_info != NULL); + + extend_info_free(extend_info); + return rv; } /** Client-side authorizations for hidden services; map of onion address to diff --git a/src/or/rendservice.c b/src/or/rendservice.c index d582d71f6c..e0c1a8c87a 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -172,14 +172,17 @@ rend_add_service(rend_service_t *service) if (service->auth_type != REND_NO_AUTH && smartlist_len(service->clients) == 0) { - log_warn(LD_CONFIG, "Hidden service with client authorization but no " - "clients; ignoring."); + log_warn(LD_CONFIG, "Hidden service (%s) with client authorization but no " + "clients; ignoring.", + escaped(service->directory)); rend_service_free(service); return; } if (!smartlist_len(service->ports)) { - log_warn(LD_CONFIG, "Hidden service with no ports configured; ignoring."); + log_warn(LD_CONFIG, "Hidden service (%s) with no ports configured; " + "ignoring.", + escaped(service->directory)); rend_service_free(service); } else { int dupe = 0; diff --git a/src/or/router.c b/src/or/router.c index c9f141b7f0..b6b96a5fff 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1024,7 +1024,7 @@ authdir_mode_any_nonhidserv(const or_options_t *options) } /** Return true iff we are an authoritative directory server that is * authoritative about receiving and serving descriptors of type - * <b>purpose</b> its dirport. Use -1 for "any purpose". */ + * <b>purpose</b> on its dirport. Use -1 for "any purpose". */ int authdir_mode_handles_descs(const or_options_t *options, int purpose) { diff --git a/src/or/routerparse.c b/src/or/routerparse.c index e8b2dd7d2b..4ea7b964cf 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -4886,6 +4886,11 @@ rend_decrypt_introduction_points(char **ipos_decrypted, crypto_cipher_env_t *cipher; char *dec; int declen; + if (ipos_encrypted_size < CIPHER_IV_LEN + 2) { + log_warn(LD_REND, "Size of encrypted introduction points is too " + "small."); + return -1; + } dec = tor_malloc_zero(ipos_encrypted_size - CIPHER_IV_LEN - 1); cipher = crypto_create_init_cipher(descriptor_cookie, 0); declen = crypto_cipher_decrypt_with_iv(cipher, dec, |