diff options
Diffstat (limited to 'src/feature/dirauth')
-rw-r--r-- | src/feature/dirauth/dirauth_config.c | 4 | ||||
-rw-r--r-- | src/feature/dirauth/dirauth_options.inc | 7 | ||||
-rw-r--r-- | src/feature/dirauth/dirvote.c | 66 | ||||
-rw-r--r-- | src/feature/dirauth/dirvote.h | 6 | ||||
-rw-r--r-- | src/feature/dirauth/process_descs.c | 45 | ||||
-rw-r--r-- | src/feature/dirauth/reachability.c | 14 | ||||
-rw-r--r-- | src/feature/dirauth/voteflags.c | 6 |
7 files changed, 83 insertions, 65 deletions
diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c index a0b6de7eca..1ffd33e5f1 100644 --- a/src/feature/dirauth/dirauth_config.c +++ b/src/feature/dirauth/dirauth_config.c @@ -77,8 +77,8 @@ options_validate_dirauth_mode(const or_options_t *old_options, return 0; /* confirm that our address isn't broken, so we can complain now */ - uint32_t tmp; - if (resolve_my_address(LOG_WARN, options, &tmp, NULL, NULL) < 0) + tor_addr_t tmp; + if (!find_my_address(options, AF_INET, LOG_WARN, &tmp, NULL, NULL)) REJECT("Failed to resolve/guess local address. See logs for details."); if (!options->ContactInfo && !options->TestingTorNetwork) diff --git a/src/feature/dirauth/dirauth_options.inc b/src/feature/dirauth/dirauth_options.inc index 21f4996c39..40ef7c3bab 100644 --- a/src/feature/dirauth/dirauth_options.inc +++ b/src/feature/dirauth/dirauth_options.inc @@ -44,6 +44,13 @@ CONF_VAR(AuthDirSharedRandomness, BOOL, 0, "1") /* NOTE: remove this option someday. */ CONF_VAR(AuthDirTestEd25519LinkKeys, BOOL, 0, "1") +/** + * Bool (default 1): As an authority, should we launch tests for + * reachability, and use those results to vote on "Running"? If 0, + * we assume that every relay is Runnning. + **/ +CONF_VAR(AuthDirTestReachability, BOOL, 0, "1") + /** Authority only: key=value pairs that we add to our networkstatus * consensus vote on the 'params' line. */ CONF_VAR(ConsensusParams, STRING, 0, NULL) diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c index 79651563b4..8676df76ab 100644 --- a/src/feature/dirauth/dirvote.c +++ b/src/feature/dirauth/dirvote.c @@ -225,7 +225,6 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key, smartlist_t *chunks = smartlist_new(); char fingerprint[FINGERPRINT_LEN+1]; char digest[DIGEST_LEN]; - uint32_t addr; char *protocols_lines = NULL; char *client_versions_line = NULL, *server_versions_line = NULL; char *shared_random_vote_str = NULL; @@ -237,8 +236,6 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key, voter = smartlist_get(v3_ns->voters, 0); - addr = voter->addr; - base16_encode(fingerprint, sizeof(fingerprint), v3_ns->cert->cache_info.identity_digest, DIGEST_LEN); @@ -322,7 +319,7 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key, tor_free(digest_algo_b64_digest_bw_file); } - const char *ip_str = fmt_addr32(addr); + const char *ip_str = fmt_addr(&voter->ipv4_addr); if (ip_str[0]) { smartlist_add_asprintf(chunks, @@ -358,7 +355,7 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key, bw_headers_line ? bw_headers_line : "", bw_file_digest ? bw_file_digest: "", voter->nickname, fingerprint, voter->address, - ip_str, voter->dir_port, voter->or_port, + ip_str, voter->ipv4_dirport, voter->ipv4_orport, voter->contact, shared_random_vote_str ? shared_random_vote_str : ""); @@ -636,9 +633,12 @@ compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b) if ((r = strcmp(b->status.nickname, a->status.nickname))) return r; - CMP_FIELD(unsigned, int, addr); - CMP_FIELD(unsigned, int, or_port); - CMP_FIELD(unsigned, int, dir_port); + if ((r = tor_addr_compare(&a->status.ipv4_addr, &b->status.ipv4_addr, + CMP_EXACT))) { + return r; + } + CMP_FIELD(unsigned, int, ipv4_orport); + CMP_FIELD(unsigned, int, ipv4_dirport); return 0; } @@ -1740,9 +1740,9 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_add_asprintf(chunks, "dir-source %s%s %s %s %s %d %d\n", voter->nickname, e->is_legacy ? "-legacy" : "", - fingerprint, voter->address, fmt_addr32(voter->addr), - voter->dir_port, - voter->or_port); + fingerprint, voter->address, fmt_addr(&voter->ipv4_addr), + voter->ipv4_dirport, + voter->ipv4_orport); if (! e->is_legacy) { smartlist_add_asprintf(chunks, "contact %s\n" @@ -2039,10 +2039,10 @@ networkstatus_compute_consensus(smartlist_t *votes, memcpy(rs_out.identity_digest, current_rsa_id, DIGEST_LEN); memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest, DIGEST_LEN); - rs_out.addr = rs->status.addr; + tor_addr_copy(&rs_out.ipv4_addr, &rs->status.ipv4_addr); rs_out.published_on = rs->status.published_on; - rs_out.dir_port = rs->status.dir_port; - rs_out.or_port = rs->status.or_port; + rs_out.ipv4_dirport = rs->status.ipv4_dirport; + rs_out.ipv4_orport = rs->status.ipv4_orport; tor_addr_copy(&rs_out.ipv6_addr, &alt_orport.addr); rs_out.ipv6_orport = alt_orport.port; rs_out.has_bandwidth = 0; @@ -3848,11 +3848,10 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method) smartlist_add_asprintf(chunks, "onion-key\n%s", key); if (ri->onion_curve25519_pkey) { - char kbuf[128]; - base64_encode(kbuf, sizeof(kbuf), - (const char*)ri->onion_curve25519_pkey->public_key, - CURVE25519_PUBKEY_LEN, BASE64_ENCODE_MULTILINE); - smartlist_add_asprintf(chunks, "ntor-onion-key %s", kbuf); + char kbuf[CURVE25519_BASE64_PADDED_LEN + 1]; + bool add_padding = (consensus_method < MIN_METHOD_FOR_UNPADDED_NTOR_KEY); + curve25519_public_to_base64(kbuf, ri->onion_curve25519_pkey, add_padding); + smartlist_add_asprintf(chunks, "ntor-onion-key %s\n", kbuf); } if (family) { @@ -3963,6 +3962,8 @@ static const struct consensus_method_range_t { {MIN_SUPPORTED_CONSENSUS_METHOD, MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS - 1}, {MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS, + MIN_METHOD_FOR_UNPADDED_NTOR_KEY - 1}, + {MIN_METHOD_FOR_UNPADDED_NTOR_KEY, MAX_SUPPORTED_CONSENSUS_METHOD}, {-1, -1} }; @@ -4219,12 +4220,14 @@ compare_routerinfo_by_ip_and_bw_(const void **a, const void **b) uint32_t bw_kb_first, bw_kb_second; const node_t *node_first, *node_second; int first_is_running, second_is_running; + uint32_t first_ipv4h = tor_addr_to_ipv4h(&first->ipv4_addr); + uint32_t second_ipv4h = tor_addr_to_ipv4h(&second->ipv4_addr); /* we return -1 if first should appear before second... that is, * if first is a better router. */ - if (first->addr < second->addr) + if (first_ipv4h < second_ipv4h) return -1; - else if (first->addr > second->addr) + else if (first_ipv4h > second_ipv4h) return 1; /* Potentially, this next bit could cause k n lg n memeq calls. But in @@ -4275,7 +4278,7 @@ get_possible_sybil_list(const smartlist_t *routers) const dirauth_options_t *options = dirauth_get_options(); digestmap_t *omit_as_sybil; smartlist_t *routers_by_ip = smartlist_new(); - uint32_t last_addr; + tor_addr_t last_addr = TOR_ADDR_NULL; int addr_count; /* Allow at most this number of Tor servers on a single IP address, ... */ int max_with_same_addr = options->AuthDirMaxServersPerAddr; @@ -4286,11 +4289,10 @@ get_possible_sybil_list(const smartlist_t *routers) smartlist_sort(routers_by_ip, compare_routerinfo_by_ip_and_bw_); omit_as_sybil = digestmap_new(); - last_addr = 0; addr_count = 0; SMARTLIST_FOREACH_BEGIN(routers_by_ip, routerinfo_t *, ri) { - if (last_addr != ri->addr) { - last_addr = ri->addr; + if (!tor_addr_eq(&last_addr, &ri->ipv4_addr)) { + tor_addr_copy(&last_addr, &ri->ipv4_addr); addr_count = 1; } else if (++addr_count > max_with_same_addr) { digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri); @@ -4463,7 +4465,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, const or_options_t *options = get_options(); const dirauth_options_t *d_options = dirauth_get_options(); networkstatus_t *v3_out = NULL; - uint32_t addr; + tor_addr_t addr; char *hostname = NULL, *client_versions = NULL, *server_versions = NULL; const char *contact; smartlist_t *routers, *routerstatuses; @@ -4492,13 +4494,13 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, log_err(LD_BUG, "Error computing identity key digest"); return NULL; } - if (resolve_my_address(LOG_WARN, options, &addr, NULL, &hostname)<0) { + if (!find_my_address(options, AF_INET, LOG_WARN, &addr, NULL, &hostname)) { log_warn(LD_NET, "Couldn't resolve my hostname"); return NULL; } if (!hostname || !strchr(hostname, '.')) { tor_free(hostname); - hostname = tor_dup_ip(addr); + hostname = tor_addr_to_str_dup(&addr); } if (!hostname) { @@ -4565,7 +4567,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, /* If it has a protover list and contains a protocol name greater than * MAX_PROTOCOL_NAME_LENGTH, skip it. */ if (ri->protocol_list && - protover_contains_long_protocol_names(ri->protocol_list)) { + protover_list_is_invalid(ri->protocol_list)) { continue; } if (ri->cache_info.published_on >= cutoff) { @@ -4722,9 +4724,9 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, memcpy(voter->identity_digest, identity_digest, DIGEST_LEN); voter->sigs = smartlist_new(); voter->address = hostname; - voter->addr = addr; - voter->dir_port = router_get_advertised_dir_port(options, 0); - voter->or_port = router_get_advertised_or_port(options); + tor_addr_copy(&voter->ipv4_addr, &addr); + voter->ipv4_dirport = routerconf_find_dir_port(options, 0); + voter->ipv4_orport = routerconf_find_or_port(options, AF_INET); voter->contact = tor_strdup(contact); if (options->V3AuthUseLegacyKey) { authority_cert_t *c = get_my_v3_legacy_cert(); diff --git a/src/feature/dirauth/dirvote.h b/src/feature/dirauth/dirvote.h index 1b1c9f2cc7..9cc87489b4 100644 --- a/src/feature/dirauth/dirvote.h +++ b/src/feature/dirauth/dirvote.h @@ -53,7 +53,7 @@ #define MIN_SUPPORTED_CONSENSUS_METHOD 28 /** The highest consensus method that we currently support. */ -#define MAX_SUPPORTED_CONSENSUS_METHOD 29 +#define MAX_SUPPORTED_CONSENSUS_METHOD 30 /** * Lowest consensus method where microdescriptor lines are put in canonical @@ -61,6 +61,10 @@ **/ #define MIN_METHOD_FOR_CANONICAL_FAMILIES_IN_MICRODESCS 29 +/** Lowest consensus method where an unpadded base64 onion-key-ntor is allowed + * See #7869 */ +#define MIN_METHOD_FOR_UNPADDED_NTOR_KEY 30 + /** Default bandwidth to clip unmeasured bandwidths to using method >= * MIN_METHOD_TO_CLIP_UNMEASURED_BW. (This is not a consensus method; do not * get confused with the above macros.) */ diff --git a/src/feature/dirauth/process_descs.c b/src/feature/dirauth/process_descs.c index 5025d0ae39..b08ffeba07 100644 --- a/src/feature/dirauth/process_descs.c +++ b/src/feature/dirauth/process_descs.c @@ -56,8 +56,9 @@ static was_router_added_t dirserv_add_extrainfo(extrainfo_t *ei, static uint32_t dirserv_get_status_impl(const char *id_digest, const ed25519_public_key_t *ed25519_public_key, - const char *nickname, uint32_t addr, uint16_t or_port, - const char *platform, const char **msg, int severity); + const char *nickname, const tor_addr_t *ipv4_addr, + uint16_t ipv4_orport, const char *platform, + const char **msg, int severity); /** Should be static; exposed for testing. */ static authdir_config_t *fingerprint_list = NULL; @@ -307,9 +308,9 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg, /* This has an ed25519 identity key. */ signing_key = &router->cache_info.signing_key_cert->signing_key; } - r = dirserv_get_status_impl(d, signing_key, router->nickname, router->addr, - router->or_port, router->platform, msg, - severity); + r = dirserv_get_status_impl(d, signing_key, router->nickname, + &router->ipv4_addr, router->ipv4_orport, + router->platform, msg, severity); if (r) return r; @@ -378,7 +379,8 @@ dirserv_would_reject_router(const routerstatus_t *rs, memcpy(&pk.pubkey, vrs->ed25519_id, ED25519_PUBKEY_LEN); res = dirserv_get_status_impl(rs->identity_digest, &pk, rs->nickname, - rs->addr, rs->or_port, NULL, NULL, LOG_DEBUG); + &rs->ipv4_addr, rs->ipv4_orport, NULL, NULL, + LOG_DEBUG); return (res & RTR_REJECT) != 0; } @@ -409,11 +411,11 @@ dirserv_rejects_tor_version(const char *platform, return true; } - /* Series between Tor 0.3.6 and 0.4.1.4-rc inclusive are unsupported. - * Reject them. 0.3.6.0-alpha-dev only existed for a short time, before - * it was renamed to 0.4.0.0-alpha-dev. */ + /* Series between Tor 0.3.6 and 0.4.1 inclusive are unsupported. Reject + * them. 0.3.6.0-alpha-dev only existed for a short time, before it was + * renamed to 0.4.0.0-alpha-dev. */ if (tor_version_as_new_as(platform,"0.3.6.0-alpha-dev") && - !tor_version_as_new_as(platform,"0.4.1.5")) { + !tor_version_as_new_as(platform,"0.4.2.1-alpha")) { if (msg) { *msg = please_upgrade_string; } @@ -433,8 +435,9 @@ dirserv_rejects_tor_version(const char *platform, static uint32_t dirserv_get_status_impl(const char *id_digest, const ed25519_public_key_t *ed25519_public_key, - const char *nickname, uint32_t addr, uint16_t or_port, - const char *platform, const char **msg, int severity) + const char *nickname, const tor_addr_t *ipv4_addr, + uint16_t ipv4_orport, const char *platform, + const char **msg, int severity) { uint32_t result = 0; rtr_flags_t *status_by_digest; @@ -485,16 +488,16 @@ dirserv_get_status_impl(const char *id_digest, *msg = "Fingerprint and/or ed25519 identity is marked invalid"; } - if (authdir_policy_badexit_address(addr, or_port)) { + if (authdir_policy_badexit_address(ipv4_addr, ipv4_orport)) { log_fn(severity, LD_DIRSERV, "Marking '%s' as bad exit because of address '%s'", - nickname, fmt_addr32(addr)); + nickname, fmt_addr(ipv4_addr)); result |= RTR_BADEXIT; } - if (!authdir_policy_permits_address(addr, or_port)) { + if (!authdir_policy_permits_address(ipv4_addr, ipv4_orport)) { log_fn(severity, LD_DIRSERV, "Rejecting '%s' because of address '%s'", - nickname, fmt_addr32(addr)); + nickname, fmt_addr(ipv4_addr)); if (msg) *msg = "Suspicious relay address range -- if you think this is a " "mistake please set a valid email address in ContactInfo and " @@ -502,10 +505,10 @@ dirserv_get_status_impl(const char *id_digest, "your address(es) and fingerprint(s)?"; return RTR_REJECT; } - if (!authdir_policy_valid_address(addr, or_port)) { + if (!authdir_policy_valid_address(ipv4_addr, ipv4_orport)) { log_fn(severity, LD_DIRSERV, "Not marking '%s' valid because of address '%s'", - nickname, fmt_addr32(addr)); + nickname, fmt_addr(ipv4_addr)); result |= RTR_INVALID; } @@ -534,13 +537,11 @@ dirserv_free_fingerprint_list(void) STATIC int dirserv_router_has_valid_address(routerinfo_t *ri) { - tor_addr_t addr; - if (get_options()->DirAllowPrivateAddresses) return 0; /* whatever it is, we're fine with it */ - tor_addr_from_ipv4h(&addr, ri->addr); - if (tor_addr_is_null(&addr) || tor_addr_is_internal(&addr, 0)) { + if (tor_addr_is_null(&ri->ipv4_addr) || + tor_addr_is_internal(&ri->ipv4_addr, 0)) { log_info(LD_DIRSERV, "Router %s published internal IPv4 address. Refusing.", router_describe(ri)); diff --git a/src/feature/dirauth/reachability.c b/src/feature/dirauth/reachability.c index 65fa27ed80..eb88b4aa07 100644 --- a/src/feature/dirauth/reachability.c +++ b/src/feature/dirauth/reachability.c @@ -84,7 +84,7 @@ dirserv_orconn_tls_done(const tor_addr_t *addr, log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.", router_describe(ri), tor_addr_to_str(addrstr, addr, sizeof(addrstr), 1), - ri->or_port); + ri->ipv4_orport); if (tor_addr_family(addr) == AF_INET) { rep_hist_note_router_reachable(digest_rcvd, addr, or_port, now); node->last_reachable = now; @@ -105,6 +105,8 @@ dirserv_should_launch_reachability_test(const routerinfo_t *ri, { if (!authdir_mode_handles_descs(get_options(), ri->purpose)) return 0; + if (! dirauth_get_options()->AuthDirTestReachability) + return 0; if (!ri_old) { /* New router: Launch an immediate reachability test, so we will have an * opinion soon in case we're generating a consensus soon */ @@ -130,7 +132,6 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router) const dirauth_options_t *dirauth_options = dirauth_get_options(); channel_t *chan = NULL; const node_t *node = NULL; - tor_addr_t router_addr; const ed25519_public_key_t *ed_id_key; (void) now; @@ -148,9 +149,9 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router) /* IPv4. */ log_debug(LD_OR,"Testing reachability of %s at %s:%u.", - router->nickname, fmt_addr32(router->addr), router->or_port); - tor_addr_from_ipv4h(&router_addr, router->addr); - chan = channel_tls_connect(&router_addr, router->or_port, + router->nickname, fmt_addr(&router->ipv4_addr), + router->ipv4_orport); + chan = channel_tls_connect(&router->ipv4_addr, router->ipv4_orport, router->cache_info.identity_digest, ed_id_key); if (chan) command_setup_channel(chan); @@ -189,6 +190,9 @@ dirserv_test_reachability(time_t now) * the testing, and directory authorities are easy to upgrade. Let's * wait til 0.2.0. -RD */ // time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH; + if (! dirauth_get_options()->AuthDirTestReachability) + return; + routerlist_t *rl = router_get_routerlist(); static char ctr = 0; int bridge_auth = authdir_mode_bridge(get_options()); diff --git a/src/feature/dirauth/voteflags.c b/src/feature/dirauth/voteflags.c index 477eb6f0b7..3938b61adb 100644 --- a/src/feature/dirauth/voteflags.c +++ b/src/feature/dirauth/voteflags.c @@ -487,7 +487,6 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now) unreachable. */ int answer; - const or_options_t *options = get_options(); const dirauth_options_t *dirauth_options = dirauth_get_options(); node_t *node = node_get_mutable_by_id(router->cache_info.identity_digest); tor_assert(node); @@ -501,8 +500,9 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now) /* A hibernating router is down unless we (somehow) had contact with it * since it declared itself to be hibernating. */ answer = 0; - } else if (options->AssumeReachable) { - /* If AssumeReachable, everybody is up unless they say they are down! */ + } else if (! dirauth_options->AuthDirTestReachability) { + /* If we aren't testing reachability, then everybody is up unless they say + * they are down. */ answer = 1; } else { /* Otherwise, a router counts as up if we found all announced OR |