diff options
Diffstat (limited to 'src/or/router.c')
-rw-r--r-- | src/or/router.c | 459 |
1 files changed, 336 insertions, 123 deletions
diff --git a/src/or/router.c b/src/or/router.c index 01316c1bc2..172531e70e 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2016, The Tor Project, Inc. */ + * Copyright (c) 2007-2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ROUTER_PRIVATE @@ -23,6 +23,7 @@ #include "networkstatus.h" #include "nodelist.h" #include "policies.h" +#include "protover.h" #include "relay.h" #include "rephist.h" #include "router.h" @@ -36,12 +37,25 @@ /** * \file router.c - * \brief OR functionality, including key maintenance, generating - * and uploading server descriptors, retrying OR connections. + * \brief Miscellaneous relay functionality, including RSA key maintenance, + * generating and uploading server descriptors, picking an address to + * advertise, and so on. + * + * This module handles the job of deciding whether we are a Tor relay, and if + * so what kind. (Mostly through functions like server_mode() that inspect an + * or_options_t, but in some cases based on our own capabilities, such as when + * we are deciding whether to be a directory cache in + * router_has_bandwidth_to_be_dirserver().) + * + * Also in this module are the functions to generate our own routerinfo_t and + * extrainfo_t, and to encode those to signed strings for upload to the + * directory authorities. + * + * This module also handles key maintenance for RSA and Curve25519-ntor keys, + * and for our TLS context. (These functions should eventually move to + * routerkeys.c along with the code that handles Ed25519 keys now.) **/ -extern long stats_n_seconds_working; - /************************************************************/ /***** @@ -134,6 +148,51 @@ dup_onion_keys(crypto_pk_t **key, crypto_pk_t **last) tor_mutex_release(key_lock); } +/** Expire our old set of onion keys. This is done by setting + * last_curve25519_onion_key and lastonionkey to all zero's and NULL + * respectively. + * + * This function does not perform any grace period checks for the old onion + * keys. + */ +void +expire_old_onion_keys(void) +{ + char *fname = NULL; + + tor_mutex_acquire(key_lock); + + /* Free lastonionkey and set it to NULL. */ + if (lastonionkey) { + crypto_pk_free(lastonionkey); + lastonionkey = NULL; + } + + /* We zero out the keypair. See the tor_mem_is_zero() check made in + * construct_ntor_key_map() below. */ + memset(&last_curve25519_onion_key, 0, sizeof(last_curve25519_onion_key)); + + tor_mutex_release(key_lock); + + fname = get_datadir_fname2("keys", "secret_onion_key.old"); + if (file_status(fname) == FN_FILE) { + if (tor_unlink(fname) != 0) { + log_warn(LD_FS, "Couldn't unlink old onion key file %s: %s", + fname, strerror(errno)); + } + } + tor_free(fname); + + fname = get_datadir_fname2("keys", "secret_onion_key_ntor.old"); + if (file_status(fname) == FN_FILE) { + if (tor_unlink(fname) != 0) { + log_warn(LD_FS, "Couldn't unlink old ntor onion key file %s: %s", + fname, strerror(errno)); + } + } + tor_free(fname); +} + /** Return the current secret onion key for the ntor handshake. Must only * be called from the main thread. */ static const curve25519_keypair_t * @@ -198,7 +257,11 @@ set_server_identity_key(crypto_pk_t *k) { crypto_pk_free(server_identitykey); server_identitykey = k; - crypto_pk_get_digest(server_identitykey, server_identitykey_digest); + if (crypto_pk_get_digest(server_identitykey, + server_identitykey_digest) < 0) { + log_err(LD_BUG, "Couldn't compute our own identity key digest."); + tor_assert(0); + } } /** Make sure that we have set up our identity keys to match or not match as @@ -454,7 +517,8 @@ init_key_from_file(const char *fname, int generate, int severity, goto error; } } else { - log_info(LD_GENERAL, "No key found in \"%s\"", fname); + tor_log(severity, LD_GENERAL, "No key found in \"%s\"", fname); + goto error; } return prkey; case FN_FILE: @@ -562,7 +626,7 @@ load_authority_keyset(int legacy, crypto_pk_t **key_out, fname = get_datadir_fname2("keys", legacy ? "legacy_signing_key" : "authority_signing_key"); - signing_key = init_key_from_file(fname, 0, LOG_INFO, 0); + signing_key = init_key_from_file(fname, 0, LOG_ERR, 0); if (!signing_key) { log_warn(LD_DIR, "No version 3 directory key found in %s", fname); goto done; @@ -668,6 +732,47 @@ v3_authority_check_key_expiry(void) last_warned = now; } +/** Get the lifetime of an onion key in days. This value is defined by the + * network consesus parameter "onion-key-rotation-days". Always returns a value + * between <b>MIN_ONION_KEY_LIFETIME_DAYS</b> and + * <b>MAX_ONION_KEY_LIFETIME_DAYS</b>. + */ +static int +get_onion_key_rotation_days_(void) +{ + return networkstatus_get_param(NULL, + "onion-key-rotation-days", + DEFAULT_ONION_KEY_LIFETIME_DAYS, + MIN_ONION_KEY_LIFETIME_DAYS, + MAX_ONION_KEY_LIFETIME_DAYS); +} + +/** Get the current lifetime of an onion key in seconds. This value is defined + * by the network consesus parameter "onion-key-rotation-days", but the value + * is converted to seconds. + */ +int +get_onion_key_lifetime(void) +{ + return get_onion_key_rotation_days_()*24*60*60; +} + +/** Get the grace period of an onion key in seconds. This value is defined by + * the network consesus parameter "onion-key-grace-period-days", but the value + * is converted to seconds. + */ +int +get_onion_key_grace_period(void) +{ + int grace_period; + grace_period = networkstatus_get_param(NULL, + "onion-key-grace-period-days", + DEFAULT_ONION_KEY_GRACE_PERIOD_DAYS, + MIN_ONION_KEY_GRACE_PERIOD_DAYS, + get_onion_key_rotation_days_()); + return grace_period*24*60*60; +} + /** Set up Tor's TLS contexts, based on our configuration and keys. Return 0 * on success, and -1 on failure. */ int @@ -678,12 +783,6 @@ router_initialize_tls_context(void) int lifetime = options->SSLKeyLifetime; if (public_server_mode(options)) flags |= TOR_TLS_CTX_IS_PUBLIC_SERVER; - if (options->TLSECGroup) { - if (!strcasecmp(options->TLSECGroup, "P256")) - flags |= TOR_TLS_CTX_USE_ECDHE_P256; - else if (!strcasecmp(options->TLSECGroup, "P224")) - flags |= TOR_TLS_CTX_USE_ECDHE_P224; - } if (!lifetime) { /* we should guess a good ssl cert lifetime */ /* choose between 5 and 365 days, and round to the day */ @@ -834,7 +933,12 @@ init_keys(void) if (init_keys_common() < 0) return -1; /* Make sure DataDirectory exists, and is private. */ - if (check_private_dir(options->DataDirectory, CPD_CREATE, options->User)) { + cpd_check_t cpd_opts = CPD_CREATE; + if (options->DataDirectoryGroupReadable) + cpd_opts |= CPD_GROUP_READ; + if (check_private_dir(options->DataDirectory, cpd_opts, options->User)) { + log_err(LD_OR, "Can't create/check datadirectory %s", + options->DataDirectory); return -1; } /* Check the key directory. */ @@ -856,8 +960,12 @@ init_keys(void) } cert = get_my_v3_authority_cert(); if (cert) { - crypto_pk_get_digest(get_my_v3_authority_cert()->identity_key, - v3_digest); + if (crypto_pk_get_digest(get_my_v3_authority_cert()->identity_key, + v3_digest) < 0) { + log_err(LD_BUG, "Couldn't compute my v3 authority identity key " + "digest."); + return -1; + } v3_digest_set = 1; } } @@ -886,7 +994,8 @@ init_keys(void) } /* 1d. Load all ed25519 keys */ - if (load_ed_keys(options,now) < 0) + const int new_signing_key = load_ed_keys(options,now); + if (new_signing_key < 0) return -1; /* 2. Read onion key. Make it if none is found. */ @@ -908,7 +1017,7 @@ init_keys(void) /* We have no LastRotatedOnionKey set; either we just created the key * or it's a holdover from 0.1.2.4-alpha-dev or earlier. In either case, * start the clock ticking now so that we will eventually rotate it even - * if we don't stay up for a full MIN_ONION_KEY_LIFETIME. */ + * if we don't stay up for the full lifetime of an onion key. */ state->LastRotatedOnionKey = onionkey_set_at = now; or_state_mark_dirty(state, options->AvoidDiskWrites ? time(NULL)+3600 : 0); @@ -956,7 +1065,7 @@ init_keys(void) /* 3b. Get an ed25519 link certificate. Note that we need to do this * after we set up the TLS context */ - if (generate_ed_link_cert(options, now) < 0) { + if (generate_ed_link_cert(options, now, new_signing_key > 0) < 0) { log_err(LD_GENERAL,"Couldn't make link cert"); return -1; } @@ -964,7 +1073,7 @@ init_keys(void) /* 4. Build our router descriptor. */ /* Must be called after keys are initialized. */ mydesc = router_get_my_descriptor(); - if (authdir_mode_handles_descs(options, ROUTER_PURPOSE_GENERAL)) { + if (authdir_mode_v3(options)) { const char *m = NULL; routerinfo_t *ri; /* We need to add our own fingerprint so it gets recognized. */ @@ -1054,7 +1163,8 @@ init_keys(void) log_info(LD_DIR, "adding my own v3 cert"); if (trusted_dirs_load_certs_from_string( cert->cache_info.signed_descriptor_body, - TRUSTED_DIRS_CERTS_SRC_SELF, 0)<0) { + TRUSTED_DIRS_CERTS_SRC_SELF, 0, + NULL)<0) { log_warn(LD_DIR, "Unable to parse my own v3 cert! Failing."); return -1; } @@ -1162,9 +1272,9 @@ router_should_be_directory_server(const or_options_t *options, int dir_port) if (accounting_is_enabled(options) && get_options()->AccountingRule != ACCT_IN) { /* Don't spend bytes for directory traffic if we could end up hibernating, - * but allow DirPort otherwise. Some people set AccountingMax because - * they're confused or to get statistics. Directory traffic has a much - * larger effect on output than input so there is no reason to turn it + * but allow DirPort otherwise. Some relay operators set AccountingMax + * because they're confused or to get statistics. Directory traffic has a + * much larger effect on output than input so there is no reason to turn it * off if using AccountingRule in. */ int interval_length = accounting_get_interval_length(); uint32_t effective_bw = get_effective_bwrate(options); @@ -1285,17 +1395,26 @@ decide_to_advertise_begindir(const or_options_t *options, } /** Allocate and return a new extend_info_t that can be used to build - * a circuit to or through the router <b>r</b>. Use the primary - * address of the router unless <b>for_direct_connect</b> is true, in - * which case the preferred address is used instead. */ + * a circuit to or through the router <b>r</b>. Uses the primary + * address of the router, so should only be called on a server. */ static extend_info_t * extend_info_from_router(const routerinfo_t *r) { tor_addr_port_t ap; tor_assert(r); + /* Make sure we don't need to check address reachability */ + tor_assert_nonfatal(router_skip_or_reachability(get_options(), 0)); + + const ed25519_public_key_t *ed_id_key; + if (r->cache_info.signing_key_cert) + ed_id_key = &r->cache_info.signing_key_cert->signing_key; + else + ed_id_key = NULL; + router_get_prim_orport(r, &ap); return extend_info_new(r->nickname, r->cache_info.identity_digest, + ed_id_key, r->onion_pkey, r->onion_curve25519_pkey, &ap.addr, ap.port); } @@ -1354,13 +1473,23 @@ consider_testing_reachability(int test_or, int test_dir) !connection_get_by_type_addr_port_purpose( CONN_TYPE_DIR, &addr, me->dir_port, DIR_PURPOSE_FETCH_SERVERDESC)) { + tor_addr_port_t my_orport, my_dirport; + memcpy(&my_orport.addr, &addr, sizeof(addr)); + memcpy(&my_dirport.addr, &addr, sizeof(addr)); + my_orport.port = me->or_port; + my_dirport.port = me->dir_port; /* ask myself, via tor, for my server descriptor. */ - directory_initiate_command(&addr, me->or_port, - &addr, me->dir_port, - me->cache_info.identity_digest, - DIR_PURPOSE_FETCH_SERVERDESC, - ROUTER_PURPOSE_GENERAL, - DIRIND_ANON_DIRPORT, "authority.z", NULL, 0, 0); + directory_request_t *req = + directory_request_new(DIR_PURPOSE_FETCH_SERVERDESC); + directory_request_set_or_addr_port(req, &my_orport); + directory_request_set_dir_addr_port(req, &my_dirport); + directory_request_set_directory_id_digest(req, + me->cache_info.identity_digest); + // ask via an anon circuit, connecting to our dirport. + directory_request_set_indirection(req, DIRIND_ANON_DIRPORT); + directory_request_set_resource(req, "authority.z"); + directory_initiate_request(req); + directory_request_free(req); } } @@ -1475,32 +1604,19 @@ authdir_mode_v3(const or_options_t *options) { return authdir_mode(options) && options->V3AuthoritativeDir != 0; } -/** Return true iff we are a v3 directory authority. */ -int -authdir_mode_any_main(const or_options_t *options) -{ - return options->V3AuthoritativeDir; -} -/** Return true if we believe ourselves to be any kind of - * authoritative directory beyond just a hidserv authority. */ -int -authdir_mode_any_nonhidserv(const or_options_t *options) -{ - return options->BridgeAuthoritativeDir || - authdir_mode_any_main(options); -} /** Return true iff we are an authoritative directory server that is * authoritative about receiving and serving descriptors of type - * <b>purpose</b> on its dirport. Use -1 for "any purpose". */ + * <b>purpose</b> on its dirport. + */ int authdir_mode_handles_descs(const or_options_t *options, int purpose) { - if (purpose < 0) - return authdir_mode_any_nonhidserv(options); + if (BUG(purpose < 0)) /* Deprecated. */ + return authdir_mode(options); else if (purpose == ROUTER_PURPOSE_GENERAL) - return authdir_mode_any_main(options); + return authdir_mode_v3(options); else if (purpose == ROUTER_PURPOSE_BRIDGE) - return (options->BridgeAuthoritativeDir); + return authdir_mode_bridge(options); else return 0; } @@ -1512,7 +1628,7 @@ authdir_mode_publishes_statuses(const or_options_t *options) { if (authdir_mode_bridge(options)) return 0; - return authdir_mode_any_nonhidserv(options); + return authdir_mode(options); } /** Return true iff we are an authoritative directory server that * tests reachability of the descriptors it learns about. @@ -1520,7 +1636,7 @@ authdir_mode_publishes_statuses(const or_options_t *options) int authdir_mode_tests_reachability(const or_options_t *options) { - return authdir_mode_handles_descs(options, -1); + return authdir_mode(options); } /** Return true iff we believe ourselves to be a bridge authoritative * directory server. @@ -1537,8 +1653,7 @@ MOCK_IMPL(int, server_mode,(const or_options_t *options)) { if (options->ClientOnly) return 0; - /* XXXX024 I believe we can kill off ORListenAddress here.*/ - return (options->ORPort_set || options->ORListenAddress); + return (options->ORPort_set); } /** Return true iff we are trying to be a non-bridge server. @@ -1749,7 +1864,7 @@ static const char *desc_gen_reason = NULL; * now. */ static time_t desc_clean_since = 0; /** Why did we mark the descriptor dirty? */ -static const char *desc_dirty_reason = NULL; +static const char *desc_dirty_reason = "Tor just started"; /** Boolean: do we need to regenerate the above? */ static int desc_needs_upload = 0; @@ -1830,7 +1945,7 @@ router_compare_to_my_exit_policy(const tor_addr_t *addr, uint16_t port) desc_routerinfo->ipv6_exit_policy && compare_tor_addr_to_short_policy(addr, port, me->ipv6_exit_policy) != ADDR_POLICY_ACCEPTED; -#endif +#endif /* 0 */ } else { return -1; } @@ -1943,23 +2058,111 @@ static int router_guess_address_from_dir_headers(uint32_t *guess); /** Make a current best guess at our address, either because * it's configured in torrc, or because we've learned it from * dirserver headers. Place the answer in *<b>addr</b> and return - * 0 on success, else return -1 if we have no guess. */ + * 0 on success, else return -1 if we have no guess. + * + * If <b>cache_only</b> is true, just return any cached answers, and + * don't try to get any new answers. + */ MOCK_IMPL(int, -router_pick_published_address,(const or_options_t *options, uint32_t *addr)) +router_pick_published_address,(const or_options_t *options, uint32_t *addr, + int cache_only)) { + /* First, check the cached output from resolve_my_address(). */ *addr = get_last_resolved_addr(); - if (!*addr && - resolve_my_address(LOG_INFO, options, addr, NULL, NULL) < 0) { - log_info(LD_CONFIG, "Could not determine our address locally. " - "Checking if directory headers provide any hints."); - if (router_guess_address_from_dir_headers(addr) < 0) { - log_info(LD_CONFIG, "No hints from directory headers either. " - "Will try again later."); - return -1; + if (*addr) + return 0; + + /* Second, consider doing a resolve attempt right here. */ + if (!cache_only) { + if (resolve_my_address(LOG_INFO, options, addr, NULL, NULL) >= 0) { + log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr32(*addr)); + return 0; } } - log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr32(*addr)); - return 0; + + /* Third, check the cached output from router_new_address_suggestion(). */ + if (router_guess_address_from_dir_headers(addr) >= 0) + return 0; + + /* We have no useful cached answers. Return failure. */ + return -1; +} + +/* Like router_check_descriptor_address_consistency, but specifically for the + * ORPort or DirPort. + * listener_type is either CONN_TYPE_OR_LISTENER or CONN_TYPE_DIR_LISTENER. */ +static void +router_check_descriptor_address_port_consistency(uint32_t ipv4h_desc_addr, + int listener_type) +{ + tor_assert(listener_type == CONN_TYPE_OR_LISTENER || + listener_type == CONN_TYPE_DIR_LISTENER); + + /* The first advertised Port may be the magic constant CFG_AUTO_PORT. + */ + int port_v4_cfg = get_first_advertised_port_by_type_af(listener_type, + AF_INET); + if (port_v4_cfg != 0 && + !port_exists_by_type_addr32h_port(listener_type, + ipv4h_desc_addr, port_v4_cfg, 1)) { + const tor_addr_t *port_addr = get_first_advertised_addr_by_type_af( + listener_type, + AF_INET); + /* If we're building a descriptor with no advertised address, + * something is terribly wrong. */ + tor_assert(port_addr); + + tor_addr_t desc_addr; + char port_addr_str[TOR_ADDR_BUF_LEN]; + char desc_addr_str[TOR_ADDR_BUF_LEN]; + + tor_addr_to_str(port_addr_str, port_addr, TOR_ADDR_BUF_LEN, 0); + + tor_addr_from_ipv4h(&desc_addr, ipv4h_desc_addr); + tor_addr_to_str(desc_addr_str, &desc_addr, TOR_ADDR_BUF_LEN, 0); + + const char *listener_str = (listener_type == CONN_TYPE_OR_LISTENER ? + "OR" : "Dir"); + log_warn(LD_CONFIG, "The IPv4 %sPort address %s does not match the " + "descriptor address %s. If you have a static public IPv4 " + "address, use 'Address <IPv4>' and 'OutboundBindAddress " + "<IPv4>'. If you are behind a NAT, use two %sPort lines: " + "'%sPort <PublicPort> NoListen' and '%sPort <InternalPort> " + "NoAdvertise'.", + listener_str, port_addr_str, desc_addr_str, listener_str, + listener_str, listener_str); + } +} + +/* Tor relays only have one IPv4 address in the descriptor, which is derived + * from the Address torrc option, or guessed using various methods in + * router_pick_published_address(). + * Warn the operator if there is no ORPort on the descriptor address + * ipv4h_desc_addr. + * Warn the operator if there is no DirPort on the descriptor address. + * This catches a few common config errors: + * - operators who expect ORPorts and DirPorts to be advertised on the + * ports' listen addresses, rather than the torrc Address (or guessed + * addresses in the absence of an Address config). This includes + * operators who attempt to put their ORPort and DirPort on different + * addresses; + * - discrepancies between guessed addresses and configured listen + * addresses (when the Address option isn't set). + * If a listener is listening on all IPv4 addresses, it is assumed that it + * is listening on the configured Address, and no messages are logged. + * If an operators has specified NoAdvertise ORPorts in a NAT setting, + * no messages are logged, unless they have specified other advertised + * addresses. + * The message tells operators to configure an ORPort and DirPort that match + * the Address (using NoListen if needed). + */ +static void +router_check_descriptor_address_consistency(uint32_t ipv4h_desc_addr) +{ + router_check_descriptor_address_port_consistency(ipv4h_desc_addr, + CONN_TYPE_OR_LISTENER); + router_check_descriptor_address_port_consistency(ipv4h_desc_addr, + CONN_TYPE_DIR_LISTENER); } /** Build a fresh routerinfo, signed server descriptor, and extra-info document @@ -1979,11 +2182,15 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) int hibernating = we_are_hibernating(); const or_options_t *options = get_options(); - if (router_pick_published_address(options, &addr) < 0) { + if (router_pick_published_address(options, &addr, 0) < 0) { log_warn(LD_CONFIG, "Don't know my address while generating descriptor"); return -1; } + /* Log a message if the address in the descriptor doesn't match the ORPort + * and DirPort addresses configured by the operator. */ + router_check_descriptor_address_consistency(addr); + ri = tor_malloc_zero(sizeof(routerinfo_t)); ri->cache_info.routerlist_index = -1; ri->nickname = tor_strdup(options->Nickname); @@ -2009,8 +2216,7 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) tor_addr_family(&p->addr) == AF_INET6) { /* Like IPv4, if the relay is configured using the default * authorities, disallow internal IPs. Otherwise, allow them. */ - const int default_auth = (!options->DirAuthorities && - !options->AlternateDirAuthority); + const int default_auth = using_default_dir_authorities(options); if (! tor_addr_is_internal(&p->addr, 0) || ! default_auth) { ipv6_orport = p; break; @@ -2042,6 +2248,8 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) get_platform_str(platform, sizeof(platform)); ri->platform = tor_strdup(platform); + ri->protocol_list = tor_strdup(protover_get_supported_protocols()); + /* compute ri->bandwidthrate as the min of various options */ ri->bandwidthrate = get_effective_bwrate(options); @@ -2058,8 +2266,8 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) &ri->exit_policy); } ri->policy_is_reject_star = - policy_is_reject_star(ri->exit_policy, AF_INET) && - policy_is_reject_star(ri->exit_policy, AF_INET6); + policy_is_reject_star(ri->exit_policy, AF_INET, 1) && + policy_is_reject_star(ri->exit_policy, AF_INET6, 1); if (options->IPv6Exit) { char *p_tmp = policy_summarize(ri->exit_policy, AF_INET6); @@ -2069,19 +2277,17 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) } if (options->MyFamily && ! options->BridgeRelay) { - smartlist_t *family; if (!warned_nonexistent_family) warned_nonexistent_family = smartlist_new(); - family = smartlist_new(); ri->declared_family = smartlist_new(); - smartlist_split_string(family, options->MyFamily, ",", - SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0); - SMARTLIST_FOREACH_BEGIN(family, char *, name) { + config_line_t *family; + for (family = options->MyFamily; family; family = family->next) { + char *name = family->value; const node_t *member; if (!strcasecmp(name, options->Nickname)) - goto skip; /* Don't list ourself, that's redundant */ + continue; /* Don't list ourself, that's redundant */ else - member = node_get_by_nickname(name, 1); + member = node_get_by_nickname(name, 0); if (!member) { int is_legal = is_legal_nickname_or_hexdigest(name); if (!smartlist_contains_string(warned_nonexistent_family, name) && @@ -2095,11 +2301,10 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) log_warn(LD_CONFIG, "There is a router named \"%s\" in my " "declared family, but that isn't a legal nickname. " "Skipping it.", escaped(name)); - smartlist_add(warned_nonexistent_family, tor_strdup(name)); + smartlist_add_strdup(warned_nonexistent_family, name); } if (is_legal) { - smartlist_add(ri->declared_family, name); - name = NULL; + smartlist_add_strdup(ri->declared_family, name); } } else if (router_digest_is_me(member->identity)) { /* Don't list ourself in our own family; that's redundant */ @@ -2113,15 +2318,11 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) if (smartlist_contains_string(warned_nonexistent_family, name)) smartlist_string_remove(warned_nonexistent_family, name); } - skip: - tor_free(name); - } SMARTLIST_FOREACH_END(name); + } /* remove duplicates from the list */ smartlist_sort_strings(ri->declared_family); smartlist_uniq_strings(ri->declared_family); - - smartlist_free(family); } /* Now generate the extrainfo. */ @@ -2223,7 +2424,7 @@ router_rebuild_descriptor(int force) if (desc_clean_since && !force) return 0; - if (router_pick_published_address(options, &addr) < 0 || + if (router_pick_published_address(options, &addr, 0) < 0 || router_get_advertised_or_port(options) == 0) { /* Stop trying to rebuild our descriptor every second. We'll * learn that it's time to try again when ip_address_changed() @@ -2534,6 +2735,7 @@ router_dump_router_to_string(routerinfo_t *router, char *ed_cert_line = NULL; char *rsa_tap_cc_line = NULL; char *ntor_cc_line = NULL; + char *proto_line = NULL; /* Make sure the identity key matches the one in the routerinfo. */ if (!crypto_pk_eq_keys(ident_key, router->identity_pkey)) { @@ -2636,7 +2838,7 @@ router_dump_router_to_string(routerinfo_t *router, make_ntor_onion_key_crosscert(ntor_keypair, &router->cache_info.signing_key_cert->signing_key, router->cache_info.published_on, - MIN_ONION_KEY_LIFETIME, &sign); + get_onion_key_lifetime(), &sign); if (!cert) { log_warn(LD_BUG,"make_ntor_onion_key_crosscert failed!"); goto err; @@ -2698,6 +2900,12 @@ router_dump_router_to_string(routerinfo_t *router, } } + if (router->protocol_list) { + tor_asprintf(&proto_line, "proto %s\n", router->protocol_list); + } else { + proto_line = tor_strdup(""); + } + address = tor_dup_ip(router->addr); chunks = smartlist_new(); @@ -2707,7 +2915,7 @@ router_dump_router_to_string(routerinfo_t *router, "%s" "%s" "platform %s\n" - "protocols Link 1 2 Circuit 1\n" + "%s" "published %s\n" "fingerprint %s\n" "uptime %ld\n" @@ -2716,7 +2924,7 @@ router_dump_router_to_string(routerinfo_t *router, "onion-key\n%s" "signing-key\n%s" "%s%s" - "%s%s%s%s", + "%s%s%s", router->nickname, address, router->or_port, @@ -2724,6 +2932,7 @@ router_dump_router_to_string(routerinfo_t *router, ed_cert_line ? ed_cert_line : "", extra_or_address ? extra_or_address : "", router->platform, + proto_line, published, fingerprint, stats_n_seconds_working, @@ -2738,8 +2947,7 @@ router_dump_router_to_string(routerinfo_t *router, ntor_cc_line ? ntor_cc_line : "", family_line, we_are_hibernating() ? "hibernating 1\n" : "", - "hidden-service-dir\n", - options->AllowSingleHopExits ? "allow-single-hop-exits\n" : ""); + "hidden-service-dir\n"); if (options->ContactInfo && strlen(options->ContactInfo)) { const char *ci = options->ContactInfo; @@ -2754,11 +2962,15 @@ router_dump_router_to_string(routerinfo_t *router, (const char *)router->onion_curve25519_pkey->public_key, CURVE25519_PUBKEY_LEN, BASE64_ENCODE_MULTILINE); smartlist_add_asprintf(chunks, "ntor-onion-key %s", kbuf); + } else { + /* Authorities will start rejecting relays without ntor keys in 0.2.9 */ + log_err(LD_BUG, "A relay must have an ntor onion key"); + goto err; } /* Write the exit policy to the end of 's'. */ if (!router->exit_policy || !smartlist_len(router->exit_policy)) { - smartlist_add(chunks, tor_strdup("reject *:*\n")); + smartlist_add_strdup(chunks, "reject *:*\n"); } else if (router->exit_policy) { char *exit_policy = router_dump_exit_policy_to_string(router,1,0); @@ -2780,12 +2992,12 @@ router_dump_router_to_string(routerinfo_t *router, if (decide_to_advertise_begindir(options, router->supports_tunnelled_dir_requests)) { - smartlist_add(chunks, tor_strdup("tunnelled-dir-server\n")); + smartlist_add_strdup(chunks, "tunnelled-dir-server\n"); } /* Sign the descriptor with Ed25519 */ if (emit_ed_sigs) { - smartlist_add(chunks, tor_strdup("router-sig-ed25519 ")); + smartlist_add_strdup(chunks, "router-sig-ed25519 "); crypto_digest_smartlist_prefix(digest, DIGEST256_LEN, ED_DESC_SIGNATURE_PREFIX, chunks, "", DIGEST_SHA256); @@ -2801,11 +3013,10 @@ router_dump_router_to_string(routerinfo_t *router, } /* Sign the descriptor with RSA */ - smartlist_add(chunks, tor_strdup("router-signature\n")); + smartlist_add_strdup(chunks, "router-signature\n"); crypto_digest_smartlist(digest, DIGEST_LEN, chunks, "", DIGEST_SHA1); - note_crypto_pk_op(SIGN_RTR); { char *sig; if (!(sig = router_get_dirobj_signature(digest, DIGEST_LEN, ident_key))) { @@ -2816,7 +3027,7 @@ router_dump_router_to_string(routerinfo_t *router, } /* include a last '\n' */ - smartlist_add(chunks, tor_strdup("\n")); + smartlist_add_strdup(chunks, "\n"); output = smartlist_join_strings(chunks, "", 0, NULL); @@ -2836,7 +3047,7 @@ router_dump_router_to_string(routerinfo_t *router, tor_free(s_dup); routerinfo_free(ri_tmp); } -#endif +#endif /* defined(DEBUG_ROUTER_DUMP_ROUTER_TO_STRING) */ goto done; @@ -2856,6 +3067,7 @@ router_dump_router_to_string(routerinfo_t *router, tor_free(rsa_tap_cc_line); tor_free(ntor_cc_line); tor_free(extra_info_line); + tor_free(proto_line); return output; } @@ -3063,6 +3275,12 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, } } + if (options->PaddingStatistics) { + contents = rep_hist_get_padding_count_lines(); + if (contents) + smartlist_add(chunks, contents); + } + /* Add information about the pluggable transports we support. */ if (options->ServerTransportPlugin) { char *pluggable_transports = pt_get_extra_info_descriptor_string(); @@ -3073,28 +3291,28 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, if (should_record_bridge_info(options) && write_stats_to_extrainfo) { const char *bridge_stats = geoip_get_bridge_stats_extrainfo(now); if (bridge_stats) { - smartlist_add(chunks, tor_strdup(bridge_stats)); + smartlist_add_strdup(chunks, bridge_stats); } } if (emit_ed_sigs) { - char digest[DIGEST256_LEN]; - smartlist_add(chunks, tor_strdup("router-sig-ed25519 ")); - crypto_digest_smartlist_prefix(digest, DIGEST256_LEN, + char sha256_digest[DIGEST256_LEN]; + smartlist_add_strdup(chunks, "router-sig-ed25519 "); + crypto_digest_smartlist_prefix(sha256_digest, DIGEST256_LEN, ED_DESC_SIGNATURE_PREFIX, chunks, "", DIGEST_SHA256); - ed25519_signature_t sig; + ed25519_signature_t ed_sig; char buf[ED25519_SIG_BASE64_LEN+1]; - if (ed25519_sign(&sig, (const uint8_t*)digest, DIGEST256_LEN, + if (ed25519_sign(&ed_sig, (const uint8_t*)sha256_digest, DIGEST256_LEN, signing_keypair) < 0) goto err; - if (ed25519_signature_to_base64(buf, &sig) < 0) + if (ed25519_signature_to_base64(buf, &ed_sig) < 0) goto err; smartlist_add_asprintf(chunks, "%s\n", buf); } - smartlist_add(chunks, tor_strdup("router-signature\n")); + smartlist_add_strdup(chunks, "router-signature\n"); s = smartlist_join_strings(chunks, "", 0, NULL); while (strlen(s) > MAX_EXTRAINFO_UPLOAD_SIZE - DIROBJ_MAX_SIG_LEN) { @@ -3129,7 +3347,7 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, "descriptor."); goto err; } - smartlist_add(chunks, tor_strdup(sig)); + smartlist_add_strdup(chunks, sig); tor_free(s); s = smartlist_join_strings(chunks, "", 0, NULL); @@ -3162,7 +3380,7 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, done: tor_free(s); - SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + SMARTLIST_FOREACH(chunks, char *, chunk, tor_free(chunk)); smartlist_free(chunks); tor_free(s_dup); tor_free(ed_cert_line); @@ -3279,7 +3497,7 @@ router_get_description(char *buf, const routerinfo_t *ri) return "<null>"; return format_node_description(buf, ri->cache_info.identity_digest, - router_is_named(ri), + 0, ri->nickname, NULL, ri->addr); @@ -3389,7 +3607,7 @@ routerstatus_describe(const routerstatus_t *rs) return routerstatus_get_description(buf, rs); } -/** Return a human-readable description of the extend_info_t <b>ri</b>. +/** Return a human-readable description of the extend_info_t <b>ei</b>. * * This function is not thread-safe. Each call to this function invalidates * previous values returned by this function. @@ -3405,21 +3623,16 @@ extend_info_describe(const extend_info_t *ei) * verbose representation of the identity of <b>router</b>. The format is: * A dollar sign. * The upper-case hexadecimal encoding of the SHA1 hash of router's identity. - * A "=" if the router is named; a "~" if it is not. + * A "=" if the router is named (no longer implemented); a "~" if it is not. * The router's nickname. **/ void router_get_verbose_nickname(char *buf, const routerinfo_t *router) { - const char *good_digest = networkstatus_get_router_digest_by_nickname( - router->nickname); - int is_named = good_digest && tor_memeq(good_digest, - router->cache_info.identity_digest, - DIGEST_LEN); buf[0] = '$'; base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest, DIGEST_LEN); - buf[1+HEX_DIGEST_LEN] = is_named ? '=' : '~'; + buf[1+HEX_DIGEST_LEN] = '~'; strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1); } |