diff options
Diffstat (limited to 'src/or/router.c')
-rw-r--r-- | src/or/router.c | 117 |
1 files changed, 102 insertions, 15 deletions
diff --git a/src/or/router.c b/src/or/router.c index 01316c1bc2..8fa5799896 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -40,8 +40,6 @@ * and uploading server descriptors, retrying OR connections. **/ -extern long stats_n_seconds_working; - /************************************************************/ /***** @@ -454,7 +452,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 +561,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; @@ -1054,7 +1053,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; } @@ -1285,15 +1285,17 @@ 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)); + router_get_prim_orport(r, &ap); return extend_info_new(r->nickname, r->cache_info.identity_digest, r->onion_pkey, r->onion_curve25519_pkey, @@ -1537,7 +1539,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.*/ + /* XXXX I believe we can kill off ORListenAddress here.*/ return (options->ORPort_set || options->ORListenAddress); } @@ -1962,6 +1964,83 @@ router_pick_published_address,(const or_options_t *options, uint32_t *addr)) return 0; } +/* 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 * for this OR. Set r to the generated routerinfo, e to the generated * extra-info document. Return 0 on success, -1 on temporary error. Failure to @@ -1984,6 +2063,10 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e) 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); @@ -2754,6 +2837,10 @@ 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'. */ @@ -3078,17 +3165,17 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, } if (emit_ed_sigs) { - char digest[DIGEST256_LEN]; + char sha256_digest[DIGEST256_LEN]; smartlist_add(chunks, tor_strdup("router-sig-ed25519 ")); - crypto_digest_smartlist_prefix(digest, DIGEST256_LEN, + 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); @@ -3162,7 +3249,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); |