diff options
Diffstat (limited to 'src/or/routerparse.c')
-rw-r--r-- | src/or/routerparse.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 6b6e21d5d0..91025c1568 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1,7 +1,7 @@ - /* Copyright (c) 2001 Matej Pfajfar. +/* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2015, The Tor Project, Inc. */ + * Copyright (c) 2007-2016, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -35,8 +35,9 @@ /****************************************************************************/ /** Enumeration of possible token types. The ones starting with K_ correspond - * to directory 'keywords'. ERR_ is an error in the tokenizing process, EOF_ - * is an end-of-file marker, and NIL_ is used to encode not-a-token. + * to directory 'keywords'. A_ is for an annotation, R or C is related to + * hidden services, ERR_ is an error in the tokenizing process, EOF_ is an + * end-of-file marker, and NIL_ is used to encode not-a-token. */ typedef enum { K_ACCEPT = 0, @@ -125,6 +126,7 @@ typedef enum { K_DIR_KEY_CERTIFICATION, K_DIR_KEY_CROSSCERT, K_DIR_ADDRESS, + K_DIR_TUNNELLED, K_VOTE_STATUS, K_VALID_AFTER, @@ -318,6 +320,7 @@ static token_rule_t routerdesc_token_table[] = { T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ), T1( "bandwidth", K_BANDWIDTH, GE(3), NO_OBJ ), A01("@purpose", A_PURPOSE, GE(1), NO_OBJ ), + T01("tunnelled-dir-server",K_DIR_TUNNELLED, NO_ARGS, NO_OBJ ), END_OF_TABLE }; @@ -535,7 +538,7 @@ static int router_get_hash_impl(const char *s, size_t s_len, char *digest, char end_char, digest_algorithm_t alg); static int router_get_hashes_impl(const char *s, size_t s_len, - digests_t *digests, + common_digests_t *digests, const char *start_str, const char *end_str, char end_char); static void token_clear(directory_token_t *tok); @@ -635,7 +638,7 @@ router_get_router_hash(const char *s, size_t s_len, char *digest) /** Set <b>digests</b> to all the digests of the consensus document in * <b>s</b> */ int -router_get_networkstatus_v3_hashes(const char *s, digests_t *digests) +router_get_networkstatus_v3_hashes(const char *s, common_digests_t *digests) { return router_get_hashes_impl(s,strlen(s),digests, "network-status-version", @@ -1402,7 +1405,8 @@ router_parse_entry_from_string(const char *s, const char *end, log_warn(LD_DIR, "Couldn't parse ed25519 cert"); goto err; } - router->signing_key_cert = cert; /* makes sure it gets freed. */ + /* makes sure it gets freed. */ + router->cache_info.signing_key_cert = cert; if (cert->cert_type != CERT_TYPE_ID_SIGNING || ! cert->signing_key_included) { @@ -1597,8 +1601,8 @@ router_parse_entry_from_string(const char *s, const char *end, } if (tok->n_args >= 2) { - if (digest256_from_base64(router->extra_info_digest256, tok->args[1]) - < 0) { + if (digest256_from_base64(router->cache_info.extra_info_digest256, + tok->args[1]) < 0) { log_warn(LD_DIR, "Invalid extra info digest256 %s", escaped(tok->args[1])); } @@ -1609,6 +1613,12 @@ router_parse_entry_from_string(const char *s, const char *end, router->wants_to_be_hs_dir = 1; } + /* This router accepts tunnelled directory requests via begindir if it has + * an open dirport or it included "tunnelled-dir-server". */ + if (find_opt_by_keyword(tokens, K_DIR_TUNNELLED) || router->dir_port > 0) { + router->supports_tunnelled_dir_requests = 1; + } + tok = find_by_keyword(tokens, K_ROUTER_SIGNATURE); note_crypto_pk_op(VERIFY_RTR); #ifdef COUNT_DISTINCT_DIGESTS @@ -1777,7 +1787,9 @@ extrainfo_parse_entry_from_string(const char *s, const char *end, log_warn(LD_DIR, "Couldn't parse ed25519 cert"); goto err; } - extrainfo->signing_key_cert = cert; /* makes sure it gets freed. */ + /* makes sure it gets freed. */ + extrainfo->cache_info.signing_key_cert = cert; + if (cert->cert_type != CERT_TYPE_ID_SIGNING || ! cert->signing_key_included) { log_warn(LD_DIR, "Invalid form for ed25519 cert"); @@ -2061,7 +2073,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string) * object (starting with "r " at the start of a line). If none is found, * return the start of the directory footer, or the next directory signature. * If none is found, return the end of the string. */ -static INLINE const char * +static inline const char * find_start_of_next_routerstatus(const char *s) { const char *eos, *footer, *sig; @@ -2294,6 +2306,8 @@ routerstatus_parse_entry_from_string(memarea_t *area, rs->is_unnamed = 1; } else if (!strcmp(tok->args[i], "HSDir")) { rs->is_hs_dir = 1; + } else if (!strcmp(tok->args[i], "V2Dir")) { + rs->is_v2_dir = 1; } } } @@ -2836,7 +2850,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out, smartlist_t *rs_tokens = NULL, *footer_tokens = NULL; networkstatus_voter_info_t *voter = NULL; networkstatus_t *ns = NULL; - digests_t ns_digests; + common_digests_t ns_digests; const char *cert, *end_of_header, *end_of_footer, *s_dup = s; directory_token_t *tok; int ok; @@ -3431,15 +3445,16 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out, return ns; } -/** Return the digests_t that holds the digests of the +/** Return the common_digests_t that holds the digests of the * <b>flavor_name</b>-flavored networkstatus according to the detached - * signatures document <b>sigs</b>, allocating a new digests_t as neeeded. */ -static digests_t * + * signatures document <b>sigs</b>, allocating a new common_digests_t as + * neeeded. */ +static common_digests_t * detached_get_digests(ns_detached_signatures_t *sigs, const char *flavor_name) { - digests_t *d = strmap_get(sigs->digests, flavor_name); + common_digests_t *d = strmap_get(sigs->digests, flavor_name); if (!d) { - d = tor_malloc_zero(sizeof(digests_t)); + d = tor_malloc_zero(sizeof(common_digests_t)); strmap_set(sigs->digests, flavor_name, d); } return d; @@ -3447,7 +3462,7 @@ detached_get_digests(ns_detached_signatures_t *sigs, const char *flavor_name) /** Return the list of signatures of the <b>flavor_name</b>-flavored * networkstatus according to the detached signatures document <b>sigs</b>, - * allocating a new digests_t as neeeded. */ + * allocating a new common_digests_t as neeeded. */ static smartlist_t * detached_get_signatures(ns_detached_signatures_t *sigs, const char *flavor_name) @@ -3469,7 +3484,7 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos) * networkstatus_parse_vote_from_string(). */ directory_token_t *tok; memarea_t *area = NULL; - digests_t *digests; + common_digests_t *digests; smartlist_t *tokens = smartlist_new(); ns_detached_signatures_t *sigs = @@ -3667,10 +3682,10 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos) * * Returns NULL on policy errors. * - * If there is a policy error, malformed_list is set to true if the entire - * policy list should be discarded. Otherwise, it is set to false, and only - * this item should be ignored - the rest of the policy list can continue to - * be processed and used. + * Set *<b>malformed_list</b> to true if the entire policy list should be + * discarded. Otherwise, set it to false, and only this item should be ignored + * on error - the rest of the policy list can continue to be processed and + * used. * * The addr_policy_t returned by this function can have its address set to * AF_UNSPEC for '*'. Use policy_expand_unspec() to turn this into a pair @@ -3683,8 +3698,8 @@ router_parse_addr_policy_item_from_string,(const char *s, int assume_action, directory_token_t *tok = NULL; const char *cp, *eos; /* Longest possible policy is - * "accept6 ffff:ffff:..255/128:10000-65535", - * which contains a max-length IPv6 address, plus 24 characters. + * "accept6 [ffff:ffff:..255]/128:10000-65535", + * which contains a max-length IPv6 address, plus 26 characters. * But note that there can be an arbitrary amount of space between the * accept and the address:mask/port element. * We don't need to multiply TOR_ADDR_BUF_LEN by 2, as there is only one @@ -3696,9 +3711,12 @@ router_parse_addr_policy_item_from_string,(const char *s, int assume_action, memarea_t *area = NULL; tor_assert(malformed_list); + *malformed_list = 0; s = eat_whitespace(s); - if ((*s == '*' || TOR_ISDIGIT(*s)) && assume_action >= 0) { + /* We can only do assume_action on []-quoted IPv6, as "a" (accept) + * and ":" (port separator) are ambiguous */ + if ((*s == '*' || *s == '[' || TOR_ISDIGIT(*s)) && assume_action >= 0) { if (tor_snprintf(line, sizeof(line), "%s %s", assume_action == ADDR_POLICY_ACCEPT?"accept":"reject", s)<0) { log_warn(LD_DIR, "Policy %s is too long.", escaped(s)); @@ -3929,7 +3947,7 @@ token_clear(directory_token_t *tok) * Return <b>tok</b> on success, or a new ERR_ token if the token didn't * conform to the syntax we wanted. **/ -static INLINE directory_token_t * +static inline directory_token_t * token_check_object(memarea_t *area, const char *kwd, directory_token_t *tok, obj_syntax o_syn) { @@ -3994,7 +4012,7 @@ token_check_object(memarea_t *area, const char *kwd, * number of parsed elements into the n_args field of <b>tok</b>. Allocate * all storage in <b>area</b>. Return the number of arguments parsed, or * return -1 if there was an insanely high number of arguments. */ -static INLINE int +static inline int get_token_arguments(memarea_t *area, directory_token_t *tok, const char *s, const char *eol) { @@ -4429,7 +4447,7 @@ router_get_hash_impl(const char *s, size_t s_len, char *digest, /** As router_get_hash_impl, but compute all hashes. */ static int -router_get_hashes_impl(const char *s, size_t s_len, digests_t *digests, +router_get_hashes_impl(const char *s, size_t s_len, common_digests_t *digests, const char *start_str, const char *end_str, char end_c) { @@ -4438,7 +4456,7 @@ router_get_hashes_impl(const char *s, size_t s_len, digests_t *digests, &start,&end)<0) return -1; - if (crypto_digest_all(digests, start, end-start)) { + if (crypto_common_digests(digests, start, end-start)) { log_warn(LD_BUG,"couldn't compute digests"); return -1; } |