Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : /**
7 : * \file process_descs.c
8 : * \brief Make decisions about uploaded descriptors
9 : *
10 : * Authorities use the code in this module to decide what to do with just-
11 : * uploaded descriptors, and to manage the fingerprint file that helps
12 : * them make those decisions.
13 : **/
14 :
15 : #define PROCESS_DESCS_PRIVATE
16 :
17 : #include "core/or/or.h"
18 : #include "feature/dirauth/process_descs.h"
19 :
20 : #include "app/config/config.h"
21 : #include "core/or/policies.h"
22 : #include "core/or/versions.h"
23 : #include "feature/dirauth/dirauth_sys.h"
24 : #include "feature/dirauth/keypin.h"
25 : #include "feature/dirauth/reachability.h"
26 : #include "feature/dirclient/dlstatus.h"
27 : #include "feature/dircommon/directory.h"
28 : #include "feature/nodelist/describe.h"
29 : #include "feature/nodelist/microdesc.h"
30 : #include "feature/nodelist/networkstatus.h"
31 : #include "feature/nodelist/nodelist.h"
32 : #include "feature/nodelist/routerinfo.h"
33 : #include "feature/nodelist/routerlist.h"
34 : #include "feature/dirparse/routerparse.h"
35 : #include "feature/nodelist/torcert.h"
36 : #include "feature/relay/router.h"
37 :
38 : #include "core/or/tor_version_st.h"
39 : #include "feature/dirauth/dirauth_options_st.h"
40 : #include "feature/nodelist/extrainfo_st.h"
41 : #include "feature/nodelist/node_st.h"
42 : #include "feature/nodelist/microdesc_st.h"
43 : #include "feature/nodelist/routerinfo_st.h"
44 : #include "feature/nodelist/routerstatus_st.h"
45 : #include "feature/nodelist/vote_routerstatus_st.h"
46 :
47 : #include "lib/encoding/confline.h"
48 : #include "lib/crypt_ops/crypto_format.h"
49 :
50 : /** How far in the future do we allow a router to get? (seconds) */
51 : #define ROUTER_ALLOW_SKEW (60*60*12)
52 :
53 : static void directory_remove_invalid(void);
54 : static was_router_added_t dirserv_add_extrainfo(extrainfo_t *ei,
55 : const char **msg);
56 : static uint32_t
57 : dirserv_get_status_impl(const char *id_digest,
58 : const ed25519_public_key_t *ed25519_public_key,
59 : const char *nickname, const tor_addr_t *ipv4_addr,
60 : uint16_t ipv4_orport, const char *platform,
61 : const char **msg, int severity);
62 :
63 : /** Should be static; exposed for testing. */
64 : static authdir_config_t *fingerprint_list = NULL;
65 :
66 : /** Allocate and return a new, empty, authdir_config_t. */
67 : static authdir_config_t *
68 24 : authdir_config_new(void)
69 : {
70 24 : authdir_config_t *list = tor_malloc_zero(sizeof(authdir_config_t));
71 24 : list->fp_by_name = strmap_new();
72 24 : list->status_by_digest = digestmap_new();
73 24 : list->status_by_digest256 = digest256map_new();
74 24 : return list;
75 : }
76 :
77 : #ifdef TOR_UNIT_TESTS
78 :
79 : /** Initialize fingerprint_list to a new authdir_config_t. Used for tests. */
80 : void
81 17 : authdir_init_fingerprint_list(void)
82 : {
83 17 : fingerprint_list = authdir_config_new();
84 17 : }
85 :
86 : /* Return the current fingerprint_list. Used for tests. */
87 : authdir_config_t *
88 17 : authdir_return_fingerprint_list(void)
89 : {
90 17 : return fingerprint_list;
91 : }
92 :
93 : #endif /* defined(TOR_UNIT_TESTS) */
94 :
95 : /** Add the fingerprint <b>fp</b> to the smartlist of fingerprint_entry_t's
96 : * <b>list</b>, or-ing the currently set status flags with
97 : * <b>add_status</b>.
98 : */
99 : int
100 9 : add_rsa_fingerprint_to_dir(const char *fp, authdir_config_t *list,
101 : rtr_flags_t add_status)
102 : {
103 9 : char *fingerprint;
104 9 : char d[DIGEST_LEN];
105 9 : rtr_flags_t *status;
106 9 : tor_assert(fp);
107 9 : tor_assert(list);
108 :
109 9 : fingerprint = tor_strdup(fp);
110 9 : tor_strstrip(fingerprint, " ");
111 9 : if (base16_decode(d, DIGEST_LEN,
112 : fingerprint, strlen(fingerprint)) != DIGEST_LEN) {
113 2 : log_warn(LD_DIRSERV, "Couldn't decode fingerprint \"%s\"",
114 : escaped(fp));
115 2 : tor_free(fingerprint);
116 2 : return -1;
117 : }
118 :
119 7 : status = digestmap_get(list->status_by_digest, d);
120 7 : if (!status) {
121 7 : status = tor_malloc_zero(sizeof(rtr_flags_t));
122 7 : digestmap_set(list->status_by_digest, d, status);
123 : }
124 :
125 7 : tor_free(fingerprint);
126 7 : *status |= add_status;
127 7 : return 0;
128 : }
129 :
130 : /** Add the ed25519 key <b>edkey</b> to the smartlist of fingerprint_entry_t's
131 : * <b>list</b>, or-ing the currently set status flags with <b>add_status</b>.
132 : * Return -1 if we were unable to decode the key, else return 0.
133 : */
134 : int
135 8 : add_ed25519_to_dir(const ed25519_public_key_t *edkey, authdir_config_t *list,
136 : rtr_flags_t add_status)
137 : {
138 8 : rtr_flags_t *status;
139 :
140 8 : tor_assert(edkey);
141 8 : tor_assert(list);
142 :
143 8 : if (ed25519_validate_pubkey(edkey) < 0) {
144 1 : log_warn(LD_DIRSERV, "Invalid ed25519 key \"%s\"", ed25519_fmt(edkey));
145 1 : return -1;
146 : }
147 :
148 7 : status = digest256map_get(list->status_by_digest256, edkey->pubkey);
149 7 : if (!status) {
150 7 : status = tor_malloc_zero(sizeof(rtr_flags_t));
151 7 : digest256map_set(list->status_by_digest256, edkey->pubkey, status);
152 : }
153 :
154 7 : *status |= add_status;
155 7 : return 0;
156 : }
157 :
158 : /** Add the fingerprint for this OR to the global list of recognized
159 : * identity key fingerprints. */
160 : int
161 1 : dirserv_add_own_fingerprint(crypto_pk_t *pk, const ed25519_public_key_t *edkey)
162 : {
163 1 : char fp[FINGERPRINT_LEN+1];
164 1 : if (crypto_pk_get_fingerprint(pk, fp, 0)<0) {
165 0 : log_err(LD_BUG, "Error computing fingerprint");
166 0 : return -1;
167 : }
168 1 : if (!fingerprint_list)
169 0 : fingerprint_list = authdir_config_new();
170 1 : if (add_rsa_fingerprint_to_dir(fp, fingerprint_list, 0) < 0) {
171 0 : log_err(LD_BUG, "Error adding RSA fingerprint");
172 0 : return -1;
173 : }
174 1 : if (add_ed25519_to_dir(edkey, fingerprint_list, 0) < 0) {
175 0 : log_err(LD_BUG, "Error adding ed25519 key");
176 0 : return -1;
177 : }
178 : return 0;
179 : }
180 :
181 : /** Load the nickname-\>fingerprint mappings stored in the approved-routers
182 : * file. The file format is line-based, with each non-blank holding one
183 : * nickname, some space, and a fingerprint for that nickname. On success,
184 : * replace the current fingerprint list with the new list and return 0. On
185 : * failure, leave the current fingerprint list untouched, and return -1. */
186 : int
187 7 : dirserv_load_fingerprint_file(void)
188 : {
189 7 : char *fname;
190 7 : char *cf;
191 7 : char *nickname, *fingerprint;
192 7 : authdir_config_t *fingerprint_list_new;
193 7 : int result;
194 7 : config_line_t *front=NULL, *list;
195 :
196 7 : fname = get_datadir_fname("approved-routers");
197 7 : log_info(LD_GENERAL,
198 : "Reloading approved fingerprints from \"%s\"...", fname);
199 :
200 7 : cf = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
201 7 : if (!cf) {
202 0 : log_warn(LD_FS, "Cannot open fingerprint file '%s'. That's ok.", fname);
203 0 : tor_free(fname);
204 0 : return 0;
205 : }
206 7 : tor_free(fname);
207 :
208 7 : result = config_get_lines(cf, &front, 0);
209 7 : tor_free(cf);
210 7 : if (result < 0) {
211 0 : log_warn(LD_CONFIG, "Error reading from fingerprint file");
212 0 : return -1;
213 : }
214 :
215 7 : fingerprint_list_new = authdir_config_new();
216 :
217 14 : for (list=front; list; list=list->next) {
218 7 : rtr_flags_t add_status = 0;
219 7 : nickname = list->key; fingerprint = list->value;
220 7 : tor_strstrip(fingerprint, " "); /* remove spaces */
221 :
222 : /* Determine what we should do with the relay with the nickname field. */
223 7 : if (!strcasecmp(nickname, "!reject")) {
224 : add_status = RTR_REJECT;
225 7 : } else if (!strcasecmp(nickname, "!badexit")) {
226 : add_status = RTR_BADEXIT;
227 0 : } else if (!strcasecmp(nickname, "!invalid")) {
228 0 : add_status = RTR_INVALID;
229 : }
230 :
231 : /* Check if fingerprint is RSA or ed25519 by verifying it. */
232 7 : int ed25519_not_ok = -1, rsa_not_ok = -1;
233 :
234 : /* Attempt to add the RSA key. */
235 7 : if (strlen(fingerprint) == HEX_DIGEST_LEN) {
236 2 : rsa_not_ok = add_rsa_fingerprint_to_dir(fingerprint,
237 : fingerprint_list_new,
238 : add_status);
239 : }
240 :
241 : /* Check ed25519 key. We check the size to prevent buffer overflows.
242 : * If valid, attempt to add it, */
243 7 : ed25519_public_key_t ed25519_pubkey_tmp;
244 7 : if (strlen(fingerprint) == BASE64_DIGEST256_LEN) {
245 2 : if (!digest256_from_base64((char *) ed25519_pubkey_tmp.pubkey,
246 : fingerprint)) {
247 1 : ed25519_not_ok = add_ed25519_to_dir(&ed25519_pubkey_tmp,
248 : fingerprint_list_new, add_status);
249 : }
250 : }
251 :
252 : /* If both keys are invalid (or missing), log and skip. */
253 7 : if (ed25519_not_ok && rsa_not_ok) {
254 5 : log_warn(LD_CONFIG, "Invalid fingerprint (nickname '%s', "
255 : "fingerprint %s). Skipping.", nickname, fingerprint);
256 5 : continue;
257 : }
258 : }
259 :
260 7 : config_free_lines(front);
261 7 : dirserv_free_fingerprint_list();
262 7 : fingerprint_list = fingerprint_list_new;
263 : /* Delete any routers whose fingerprints we no longer recognize */
264 7 : directory_remove_invalid();
265 7 : return 0;
266 : }
267 :
268 : /* If this is set, then we don't allow routers that have advertised an Ed25519
269 : * identity to stop doing so. This is going to be essential for good identity
270 : * security: otherwise anybody who can attack RSA-1024 but not Ed25519 could
271 : * just sign fake descriptors missing the Ed25519 key. But we won't actually
272 : * be able to prevent that kind of thing until we're confident that there isn't
273 : * actually a legit reason to downgrade to 0.2.5. Now we are not recommending
274 : * 0.2.5 anymore so there is no reason to keep the #undef.
275 : */
276 :
277 : #define DISABLE_DISABLING_ED25519
278 :
279 : /** Check whether <b>router</b> has:
280 : * - a nickname/identity key combination that we recognize from the fingerprint
281 : * list,
282 : * - an IP we automatically act on according to our configuration,
283 : * - an appropriate version, and
284 : * - matching pinned keys.
285 : *
286 : * Return the appropriate router status.
287 : *
288 : * If the status is 'RTR_REJECT' and <b>msg</b> is provided, set
289 : * *<b>msg</b> to a string constant explaining why. */
290 : uint32_t
291 6 : dirserv_router_get_status(const routerinfo_t *router, const char **msg,
292 : int severity)
293 : {
294 6 : char d[DIGEST_LEN];
295 6 : const int key_pinning = dirauth_get_options()->AuthDirPinKeys;
296 6 : uint32_t r;
297 6 : ed25519_public_key_t *signing_key = NULL;
298 :
299 6 : if (crypto_pk_get_digest(router->identity_pkey, d)) {
300 0 : log_warn(LD_BUG,"Error computing fingerprint");
301 0 : if (msg)
302 0 : *msg = "Bug: Error computing fingerprint";
303 0 : return RTR_REJECT;
304 : }
305 :
306 : /* First, check for the more common reasons to reject a router. */
307 6 : if (router->cache_info.signing_key_cert) {
308 : /* This has an ed25519 identity key. */
309 6 : signing_key = &router->cache_info.signing_key_cert->signing_key;
310 : }
311 12 : r = dirserv_get_status_impl(d, signing_key, router->nickname,
312 6 : &router->ipv4_addr, router->ipv4_orport,
313 6 : router->platform, msg, severity);
314 :
315 6 : if (r)
316 : return r;
317 :
318 : /* dirserv_get_status_impl already rejects versions older than 0.2.4.18-rc,
319 : * and onion_curve25519_pkey was introduced in 0.2.4.8-alpha.
320 : * But just in case a relay doesn't provide or lies about its version, or
321 : * doesn't include an ntor key in its descriptor, check that it exists,
322 : * and is non-zero (clients check that it's non-zero before using it). */
323 4 : if (!routerinfo_has_curve25519_onion_key(router)) {
324 0 : log_fn(severity, LD_DIR,
325 : "Descriptor from router %s (platform %s) "
326 : "is missing an ntor curve25519 onion key.",
327 : router_describe(router), router->platform);
328 0 : if (msg)
329 0 : *msg = "Missing ntor curve25519 onion key. Please upgrade!";
330 0 : return RTR_REJECT;
331 : }
332 :
333 4 : if (router->cache_info.signing_key_cert) {
334 : /* This has an ed25519 identity key. */
335 4 : if (KEYPIN_MISMATCH ==
336 4 : keypin_check((const uint8_t*)router->cache_info.identity_digest,
337 4 : router->cache_info.signing_key_cert->signing_key.pubkey)) {
338 0 : log_fn(severity, LD_DIR,
339 : "Descriptor from router %s has an Ed25519 key, "
340 : "but the <rsa,ed25519> keys don't match what they were before.",
341 : router_describe(router));
342 0 : if (key_pinning) {
343 0 : if (msg) {
344 0 : *msg = "Ed25519 identity key or RSA identity key has changed.";
345 : }
346 0 : return RTR_REJECT;
347 : }
348 : }
349 : } else {
350 : /* No ed25519 key */
351 0 : if (KEYPIN_MISMATCH == keypin_check_lone_rsa(
352 0 : (const uint8_t*)router->cache_info.identity_digest)) {
353 0 : log_fn(severity, LD_DIR,
354 : "Descriptor from router %s has no Ed25519 key, "
355 : "when we previously knew an Ed25519 for it. Ignoring for now, "
356 : "since Ed25519 keys are fairly new.",
357 : router_describe(router));
358 : #ifdef DISABLE_DISABLING_ED25519
359 0 : if (key_pinning) {
360 0 : if (msg) {
361 0 : *msg = "Ed25519 identity key has disappeared.";
362 : }
363 0 : return RTR_REJECT;
364 : }
365 : #endif /* defined(DISABLE_DISABLING_ED25519) */
366 : }
367 : }
368 :
369 : return 0;
370 : }
371 :
372 : /** Return true if there is no point in downloading the router described by
373 : * <b>rs</b> because this directory would reject it. */
374 : int
375 6 : dirserv_would_reject_router(const routerstatus_t *rs,
376 : const vote_routerstatus_t *vrs)
377 : {
378 6 : uint32_t res;
379 6 : struct ed25519_public_key_t pk;
380 6 : memcpy(&pk.pubkey, vrs->ed25519_id, ED25519_PUBKEY_LEN);
381 :
382 12 : res = dirserv_get_status_impl(rs->identity_digest, &pk, rs->nickname,
383 6 : &rs->ipv4_addr, rs->ipv4_orport, NULL, NULL,
384 : LOG_DEBUG);
385 :
386 6 : return (res & RTR_REJECT) != 0;
387 : }
388 :
389 : /**
390 : * Check whether the platform string in <b>platform</b> describes a platform
391 : * that, as a directory authority, we want to reject. If it does, return
392 : * true, and set *<b>msg</b> (if present) to a rejection message. Otherwise
393 : * return false.
394 : */
395 : STATIC bool
396 32 : dirserv_rejects_tor_version(const char *platform,
397 : const char **msg)
398 : {
399 32 : if (!platform)
400 : return false;
401 :
402 32 : static const char please_upgrade_string[] =
403 : "Tor version is insecure or unsupported. Please upgrade!";
404 :
405 : /* Versions before Tor 0.3.5 are unsupported.
406 : *
407 : * Also, reject unstable versions of 0.3.5, since (as of this writing)
408 : * they are almost none of the network. */
409 32 : if (!tor_version_as_new_as(platform,"0.3.5.7")) {
410 14 : if (msg)
411 14 : *msg = please_upgrade_string;
412 14 : return true;
413 : }
414 :
415 : /* Series between Tor 0.3.6 and 0.4.1 inclusive are unsupported. Reject
416 : * them. 0.3.6.0-alpha-dev only existed for a short time, before it was
417 : * renamed to 0.4.0.0-alpha-dev. */
418 34 : if (tor_version_as_new_as(platform,"0.3.6.0-alpha-dev") &&
419 16 : !tor_version_as_new_as(platform,"0.4.2.1-alpha")) {
420 5 : if (msg) {
421 5 : *msg = please_upgrade_string;
422 : }
423 5 : return true;
424 : }
425 :
426 : return false;
427 : }
428 :
429 : /** Helper: As dirserv_router_get_status, but takes the router fingerprint
430 : * (hex, no spaces), ed25519 key, nickname, address (used for logging only),
431 : * IP address, OR port and platform (logging only) as arguments.
432 : *
433 : * Log messages at 'severity'. (There's not much point in
434 : * logging that we're rejecting servers we'll not download.)
435 : */
436 : static uint32_t
437 12 : dirserv_get_status_impl(const char *id_digest,
438 : const ed25519_public_key_t *ed25519_public_key,
439 : const char *nickname, const tor_addr_t *ipv4_addr,
440 : uint16_t ipv4_orport, const char *platform,
441 : const char **msg, int severity)
442 : {
443 12 : uint32_t result = 0;
444 12 : rtr_flags_t *status_by_digest;
445 :
446 12 : if (!fingerprint_list)
447 0 : fingerprint_list = authdir_config_new();
448 :
449 12 : log_debug(LD_DIRSERV, "%d fingerprints, %d digests known.",
450 : strmap_size(fingerprint_list->fp_by_name),
451 : digestmap_size(fingerprint_list->status_by_digest));
452 :
453 12 : if (platform) {
454 6 : tor_version_t ver_tmp;
455 6 : if (tor_version_parse_platform(platform, &ver_tmp, 1) < 0) {
456 0 : if (msg) {
457 0 : *msg = "Malformed platform string.";
458 : }
459 0 : return RTR_REJECT;
460 : }
461 : }
462 :
463 : /* Check whether the version is obsolete, broken, insecure, etc... */
464 12 : if (platform && dirserv_rejects_tor_version(platform, msg)) {
465 : return RTR_REJECT;
466 : }
467 :
468 12 : status_by_digest = digestmap_get(fingerprint_list->status_by_digest,
469 : id_digest);
470 12 : if (status_by_digest)
471 4 : result |= *status_by_digest;
472 :
473 12 : if (ed25519_public_key) {
474 24 : status_by_digest = digest256map_get(fingerprint_list->status_by_digest256,
475 12 : ed25519_public_key->pubkey);
476 12 : if (status_by_digest)
477 4 : result |= *status_by_digest;
478 : }
479 :
480 12 : if (result & RTR_REJECT) {
481 4 : if (msg)
482 2 : *msg = "Fingerprint and/or ed25519 identity is marked rejected -- if "
483 : "you think this is a mistake please set a valid email address "
484 : "in ContactInfo and send an email to "
485 : "bad-relays@lists.torproject.org mentioning your fingerprint(s)?";
486 4 : return RTR_REJECT;
487 8 : } else if (result & RTR_INVALID) {
488 0 : if (msg)
489 0 : *msg = "Fingerprint and/or ed25519 identity is marked invalid";
490 : }
491 :
492 8 : if (authdir_policy_badexit_address(ipv4_addr, ipv4_orport)) {
493 0 : log_fn(severity, LD_DIRSERV,
494 : "Marking '%s' as bad exit because of address '%s'",
495 : nickname, fmt_addr(ipv4_addr));
496 0 : result |= RTR_BADEXIT;
497 : }
498 :
499 8 : if (!authdir_policy_permits_address(ipv4_addr, ipv4_orport)) {
500 0 : log_fn(severity, LD_DIRSERV, "Rejecting '%s' because of address '%s'",
501 : nickname, fmt_addr(ipv4_addr));
502 0 : if (msg)
503 0 : *msg = "Suspicious relay address range -- if you think this is a "
504 : "mistake please set a valid email address in ContactInfo and "
505 : "send an email to bad-relays@lists.torproject.org mentioning "
506 : "your address(es) and fingerprint(s)?";
507 0 : return RTR_REJECT;
508 : }
509 8 : if (!authdir_policy_valid_address(ipv4_addr, ipv4_orport)) {
510 0 : log_fn(severity, LD_DIRSERV,
511 : "Not marking '%s' valid because of address '%s'",
512 : nickname, fmt_addr(ipv4_addr));
513 0 : result |= RTR_INVALID;
514 : }
515 :
516 : return result;
517 : }
518 :
519 : /** Clear the current fingerprint list. */
520 : void
521 266 : dirserv_free_fingerprint_list(void)
522 : {
523 266 : if (!fingerprint_list)
524 : return;
525 :
526 24 : strmap_free(fingerprint_list->fp_by_name, tor_free_);
527 24 : digestmap_free(fingerprint_list->status_by_digest, tor_free_);
528 24 : digest256map_free(fingerprint_list->status_by_digest256, tor_free_);
529 24 : tor_free(fingerprint_list);
530 : }
531 :
532 : /*
533 : * Descriptor list
534 : */
535 :
536 : /** Return -1 if <b>ri</b> has a private or otherwise bad address,
537 : * unless we're configured to not care. Return 0 if all ok. */
538 : STATIC int
539 18 : dirserv_router_has_valid_address(routerinfo_t *ri)
540 : {
541 18 : if (get_options()->DirAllowPrivateAddresses)
542 : return 0; /* whatever it is, we're fine with it */
543 :
544 15 : if (tor_addr_is_null(&ri->ipv4_addr) ||
545 6 : tor_addr_is_internal(&ri->ipv4_addr, 0)) {
546 4 : log_info(LD_DIRSERV,
547 : "Router %s published internal IPv4 address. Refusing.",
548 : router_describe(ri));
549 4 : return -1; /* it's a private IP, we should reject it */
550 : }
551 :
552 : /* We only check internal v6 on non-null addresses because we do not require
553 : * IPv6 and null IPv6 is normal. */
554 7 : if (!tor_addr_is_null(&ri->ipv6_addr) &&
555 2 : tor_addr_is_internal(&ri->ipv6_addr, 0)) {
556 1 : log_info(LD_DIRSERV,
557 : "Router %s published internal IPv6 address. Refusing.",
558 : router_describe(ri));
559 1 : return -1; /* it's a private IP, we should reject it */
560 : }
561 :
562 : return 0;
563 : }
564 :
565 : /** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
566 : * set its is_valid,running fields and return 0. Otherwise, return -1.
567 : *
568 : * If the router is rejected, set *<b>msg</b> to a string constant explining
569 : * why.
570 : *
571 : * If <b>complain</b> then explain at log-level 'notice' why we refused
572 : * a descriptor; else explain at log-level 'info'.
573 : */
574 : int
575 0 : authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
576 : int complain, int *valid_out)
577 : {
578 : /* Okay. Now check whether the fingerprint is recognized. */
579 0 : time_t now;
580 0 : int severity = (complain && ri->contact_info) ? LOG_NOTICE : LOG_INFO;
581 0 : uint32_t status = dirserv_router_get_status(ri, msg, severity);
582 0 : tor_assert(msg);
583 0 : if (status & RTR_REJECT)
584 : return -1; /* msg is already set. */
585 :
586 : /* Is there too much clock skew? */
587 0 : now = time(NULL);
588 0 : if (ri->cache_info.published_on > now+ROUTER_ALLOW_SKEW) {
589 0 : log_fn(severity, LD_DIRSERV, "Publication time for %s is too "
590 : "far (%d minutes) in the future; possible clock skew. Not adding "
591 : "(%s)",
592 : router_describe(ri),
593 : (int)((ri->cache_info.published_on-now)/60),
594 : esc_router_info(ri));
595 0 : *msg = "Rejected: Your clock is set too far in the future, or your "
596 : "timezone is not correct.";
597 0 : return -1;
598 : }
599 0 : if (ri->cache_info.published_on < now-ROUTER_MAX_AGE_TO_PUBLISH) {
600 0 : log_fn(severity, LD_DIRSERV,
601 : "Publication time for %s is too far "
602 : "(%d minutes) in the past. Not adding (%s)",
603 : router_describe(ri),
604 : (int)((now-ri->cache_info.published_on)/60),
605 : esc_router_info(ri));
606 0 : *msg = "Rejected: Server is expired, or your clock is too far in the past,"
607 : " or your timezone is not correct.";
608 0 : return -1;
609 : }
610 0 : if (dirserv_router_has_valid_address(ri) < 0) {
611 0 : log_fn(severity, LD_DIRSERV,
612 : "Router %s has invalid address. Not adding (%s).",
613 : router_describe(ri),
614 : esc_router_info(ri));
615 0 : *msg = "Rejected: Address is a private address.";
616 0 : return -1;
617 : }
618 :
619 0 : *valid_out = ! (status & RTR_INVALID);
620 :
621 0 : return 0;
622 : }
623 :
624 : /** Update the relevant flags of <b>node</b> based on our opinion as a
625 : * directory authority in <b>authstatus</b>, as returned by
626 : * dirserv_router_get_status or equivalent. */
627 : void
628 0 : dirserv_set_node_flags_from_authoritative_status(node_t *node,
629 : uint32_t authstatus)
630 : {
631 0 : node->is_valid = (authstatus & RTR_INVALID) ? 0 : 1;
632 0 : node->is_bad_exit = (authstatus & RTR_BADEXIT) ? 1 : 0;
633 0 : }
634 :
635 : /** True iff <b>a</b> is more severe than <b>b</b>. */
636 : static int
637 0 : WRA_MORE_SEVERE(was_router_added_t a, was_router_added_t b)
638 : {
639 0 : return a < b;
640 : }
641 :
642 : /** As for dirserv_add_descriptor(), but accepts multiple documents, and
643 : * returns the most severe error that occurred for any one of them. */
644 : was_router_added_t
645 0 : dirserv_add_multiple_descriptors(const char *desc, size_t desclen,
646 : uint8_t purpose,
647 : const char *source,
648 : const char **msg)
649 : {
650 0 : was_router_added_t r, r_tmp;
651 0 : const char *msg_out;
652 0 : smartlist_t *list;
653 0 : const char *s;
654 0 : int n_parsed = 0;
655 0 : time_t now = time(NULL);
656 0 : char annotation_buf[ROUTER_ANNOTATION_BUF_LEN];
657 0 : char time_buf[ISO_TIME_LEN+1];
658 0 : int general = purpose == ROUTER_PURPOSE_GENERAL;
659 0 : tor_assert(msg);
660 :
661 0 : r=ROUTER_ADDED_SUCCESSFULLY; /* Least severe return value. */
662 :
663 0 : if (!string_is_utf8_no_bom(desc, desclen)) {
664 0 : *msg = "descriptor(s) or extrainfo(s) not valid UTF-8 or had BOM.";
665 0 : return ROUTER_AUTHDIR_REJECTS;
666 : }
667 :
668 0 : format_iso_time(time_buf, now);
669 0 : if (tor_snprintf(annotation_buf, sizeof(annotation_buf),
670 : "@uploaded-at %s\n"
671 : "@source %s\n"
672 : "%s%s%s", time_buf, escaped(source),
673 : !general ? "@purpose " : "",
674 0 : !general ? router_purpose_to_string(purpose) : "",
675 : !general ? "\n" : "")<0) {
676 0 : *msg = "Couldn't format annotations";
677 0 : return ROUTER_AUTHDIR_BUG_ANNOTATIONS;
678 : }
679 :
680 0 : s = desc;
681 0 : list = smartlist_new();
682 0 : if (!router_parse_list_from_string(&s, s+desclen, list, SAVED_NOWHERE, 0, 0,
683 : annotation_buf, NULL)) {
684 0 : SMARTLIST_FOREACH(list, routerinfo_t *, ri, {
685 : msg_out = NULL;
686 : tor_assert(ri->purpose == purpose);
687 : r_tmp = dirserv_add_descriptor(ri, &msg_out, source);
688 : if (WRA_MORE_SEVERE(r_tmp, r)) {
689 : r = r_tmp;
690 : *msg = msg_out;
691 : }
692 : });
693 : }
694 0 : n_parsed += smartlist_len(list);
695 0 : smartlist_clear(list);
696 :
697 0 : s = desc;
698 0 : if (!router_parse_list_from_string(&s, s+desclen, list, SAVED_NOWHERE, 1, 0,
699 : NULL, NULL)) {
700 0 : SMARTLIST_FOREACH(list, extrainfo_t *, ei, {
701 : msg_out = NULL;
702 :
703 : r_tmp = dirserv_add_extrainfo(ei, &msg_out);
704 : if (WRA_MORE_SEVERE(r_tmp, r)) {
705 : r = r_tmp;
706 : *msg = msg_out;
707 : }
708 : });
709 : }
710 0 : n_parsed += smartlist_len(list);
711 0 : smartlist_free(list);
712 :
713 0 : if (! *msg) {
714 0 : if (!n_parsed) {
715 0 : *msg = "No descriptors found in your POST.";
716 0 : if (WRA_WAS_ADDED(r))
717 0 : r = ROUTER_IS_ALREADY_KNOWN;
718 : } else {
719 0 : *msg = "(no message)";
720 : }
721 : }
722 :
723 : return r;
724 : }
725 :
726 : /** Examine the parsed server descriptor in <b>ri</b> and maybe insert it into
727 : * the list of server descriptors. Set *<b>msg</b> to a message that should be
728 : * passed back to the origin of this descriptor, or NULL if there is no such
729 : * message. Use <b>source</b> to produce better log messages.
730 : *
731 : * If <b>ri</b> is not added to the list of server descriptors, free it.
732 : * That means the caller must not access <b>ri</b> after this function
733 : * returns, since it might have been freed.
734 : *
735 : * Return the status of the operation, and set *<b>msg</b> to a string
736 : * constant describing the status.
737 : *
738 : * This function is only called when fresh descriptors are posted, not when
739 : * we re-load the cache.
740 : */
741 : was_router_added_t
742 0 : dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
743 : {
744 0 : was_router_added_t r;
745 0 : routerinfo_t *ri_old;
746 0 : char *desc, *nickname;
747 0 : const size_t desclen = ri->cache_info.signed_descriptor_len +
748 0 : ri->cache_info.annotations_len;
749 0 : const int key_pinning = dirauth_get_options()->AuthDirPinKeys;
750 0 : *msg = NULL;
751 :
752 : /* If it's too big, refuse it now. Otherwise we'll cache it all over the
753 : * network and it'll clog everything up. */
754 0 : if (ri->cache_info.signed_descriptor_len > MAX_DESCRIPTOR_UPLOAD_SIZE) {
755 0 : log_notice(LD_DIR, "Somebody attempted to publish a router descriptor '%s'"
756 : " (source: %s) with size %d. Either this is an attack, or the "
757 : "MAX_DESCRIPTOR_UPLOAD_SIZE (%d) constant is too low.",
758 : ri->nickname, source, (int)ri->cache_info.signed_descriptor_len,
759 : MAX_DESCRIPTOR_UPLOAD_SIZE);
760 0 : *msg = "Router descriptor was too large.";
761 0 : r = ROUTER_AUTHDIR_REJECTS;
762 0 : goto fail;
763 : }
764 :
765 0 : log_info(LD_DIR, "Assessing new descriptor: %s: %s",
766 : ri->nickname, ri->platform);
767 :
768 : /* Check whether this descriptor is semantically identical to the last one
769 : * from this server. (We do this here and not in router_add_to_routerlist
770 : * because we want to be able to accept the newest router descriptor that
771 : * another authority has, so we all converge on the same one.) */
772 0 : ri_old = router_get_mutable_by_digest(ri->cache_info.identity_digest);
773 0 : if (ri_old && ri_old->cache_info.published_on < ri->cache_info.published_on
774 0 : && router_differences_are_cosmetic(ri_old, ri)
775 0 : && !router_is_me(ri)) {
776 0 : log_info(LD_DIRSERV,
777 : "Not replacing descriptor from %s (source: %s); "
778 : "differences are cosmetic.",
779 : router_describe(ri), source);
780 0 : *msg = "Not replacing router descriptor; no information has changed since "
781 : "the last one with this identity.";
782 0 : r = ROUTER_IS_ALREADY_KNOWN;
783 0 : goto fail;
784 : }
785 :
786 : /* Do keypinning again ... this time, to add the pin if appropriate */
787 0 : int keypin_status;
788 0 : if (ri->cache_info.signing_key_cert) {
789 0 : ed25519_public_key_t *pkey = &ri->cache_info.signing_key_cert->signing_key;
790 : /* First let's validate this pubkey before pinning it */
791 0 : if (ed25519_validate_pubkey(pkey) < 0) {
792 0 : log_warn(LD_DIRSERV, "Received bad key from %s (source %s)",
793 : router_describe(ri), source);
794 0 : routerinfo_free(ri);
795 0 : return ROUTER_AUTHDIR_REJECTS;
796 : }
797 :
798 : /* Now pin it! */
799 0 : keypin_status = keypin_check_and_add(
800 : (const uint8_t*)ri->cache_info.identity_digest,
801 0 : pkey->pubkey, ! key_pinning);
802 : } else {
803 0 : keypin_status = keypin_check_lone_rsa(
804 : (const uint8_t*)ri->cache_info.identity_digest);
805 : #ifndef DISABLE_DISABLING_ED25519
806 : if (keypin_status == KEYPIN_MISMATCH)
807 : keypin_status = KEYPIN_NOT_FOUND;
808 : #endif
809 : }
810 0 : if (keypin_status == KEYPIN_MISMATCH && key_pinning) {
811 0 : log_info(LD_DIRSERV, "Dropping descriptor from %s (source: %s) because "
812 : "its key did not match an older RSA/Ed25519 keypair",
813 : router_describe(ri), source);
814 0 : *msg = "Looks like your keypair has changed? This authority previously "
815 : "recorded a different RSA identity for this Ed25519 identity (or vice "
816 : "versa.) Did you replace or copy some of your key files, but not "
817 : "the others? You should either restore the expected keypair, or "
818 : "delete your keys and restart Tor to start your relay with a new "
819 : "identity.";
820 0 : r = ROUTER_AUTHDIR_REJECTS;
821 0 : goto fail;
822 : }
823 :
824 : /* Make a copy of desc, since router_add_to_routerlist might free
825 : * ri and its associated signed_descriptor_t. */
826 0 : desc = tor_strndup(ri->cache_info.signed_descriptor_body, desclen);
827 0 : nickname = tor_strdup(ri->nickname);
828 :
829 : /* Tell if we're about to need to launch a test if we add this. */
830 0 : ri->needs_retest_if_added =
831 0 : dirserv_should_launch_reachability_test(ri, ri_old);
832 :
833 0 : r = router_add_to_routerlist(ri, msg, 0, 0);
834 0 : if (!WRA_WAS_ADDED(r)) {
835 : /* unless the routerinfo was fine, just out-of-date */
836 0 : log_info(LD_DIRSERV,
837 : "Did not add descriptor from '%s' (source: %s): %s.",
838 : nickname, source, *msg ? *msg : "(no message)");
839 : } else {
840 0 : smartlist_t *changed;
841 :
842 0 : changed = smartlist_new();
843 0 : smartlist_add(changed, ri);
844 0 : routerlist_descriptors_added(changed, 0);
845 0 : smartlist_free(changed);
846 0 : if (!*msg) {
847 0 : *msg = "Descriptor accepted";
848 : }
849 0 : log_info(LD_DIRSERV,
850 : "Added descriptor from '%s' (source: %s): %s.",
851 : nickname, source, *msg);
852 : }
853 0 : tor_free(desc);
854 0 : tor_free(nickname);
855 0 : return r;
856 0 : fail:
857 : {
858 0 : const char *desc_digest = ri->cache_info.signed_descriptor_digest;
859 0 : download_status_t *dls =
860 0 : router_get_dl_status_by_descriptor_digest(desc_digest);
861 0 : if (dls) {
862 0 : log_info(LD_GENERAL, "Marking router with descriptor %s as rejected, "
863 : "and therefore undownloadable",
864 : hex_str(desc_digest, DIGEST_LEN));
865 0 : download_status_mark_impossible(dls);
866 : }
867 0 : routerinfo_free(ri);
868 : }
869 0 : return r;
870 : }
871 :
872 : /** As dirserv_add_descriptor, but for an extrainfo_t <b>ei</b>. */
873 : static was_router_added_t
874 0 : dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
875 : {
876 0 : routerinfo_t *ri;
877 0 : int r;
878 0 : was_router_added_t rv;
879 0 : tor_assert(msg);
880 0 : *msg = NULL;
881 :
882 : /* Needs to be mutable so routerinfo_incompatible_with_extrainfo
883 : * can mess with some of the flags in ri->cache_info. */
884 0 : ri = router_get_mutable_by_digest(ei->cache_info.identity_digest);
885 0 : if (!ri) {
886 0 : *msg = "No corresponding router descriptor for extra-info descriptor";
887 0 : rv = ROUTER_BAD_EI;
888 0 : goto fail;
889 : }
890 :
891 : /* If it's too big, refuse it now. Otherwise we'll cache it all over the
892 : * network and it'll clog everything up. */
893 0 : if (ei->cache_info.signed_descriptor_len > MAX_EXTRAINFO_UPLOAD_SIZE) {
894 0 : log_notice(LD_DIR, "Somebody attempted to publish an extrainfo "
895 : "with size %d. Either this is an attack, or the "
896 : "MAX_EXTRAINFO_UPLOAD_SIZE (%d) constant is too low.",
897 : (int)ei->cache_info.signed_descriptor_len,
898 : MAX_EXTRAINFO_UPLOAD_SIZE);
899 0 : *msg = "Extrainfo document was too large";
900 0 : rv = ROUTER_BAD_EI;
901 0 : goto fail;
902 : }
903 :
904 0 : if ((r = routerinfo_incompatible_with_extrainfo(ri->identity_pkey, ei,
905 : &ri->cache_info, msg))) {
906 0 : if (r<0) {
907 0 : extrainfo_free(ei);
908 0 : return ROUTER_IS_ALREADY_KNOWN;
909 : }
910 0 : rv = ROUTER_BAD_EI;
911 0 : goto fail;
912 : }
913 0 : router_add_extrainfo_to_routerlist(ei, msg, 0, 0);
914 0 : return ROUTER_ADDED_SUCCESSFULLY;
915 0 : fail:
916 : {
917 0 : const char *d = ei->cache_info.signed_descriptor_digest;
918 0 : signed_descriptor_t *sd = router_get_by_extrainfo_digest((char*)d);
919 0 : if (sd) {
920 0 : log_info(LD_GENERAL, "Marking extrainfo with descriptor %s as "
921 : "rejected, and therefore undownloadable",
922 : hex_str((char*)d,DIGEST_LEN));
923 0 : download_status_mark_impossible(&sd->ei_dl_status);
924 : }
925 0 : extrainfo_free(ei);
926 : }
927 0 : return rv;
928 : }
929 :
930 : /** Remove all descriptors whose nicknames or fingerprints no longer
931 : * are allowed by our fingerprint list. (Descriptors that used to be
932 : * good can become bad when we reload the fingerprint list.)
933 : */
934 : static void
935 7 : directory_remove_invalid(void)
936 : {
937 7 : routerlist_t *rl = router_get_routerlist();
938 7 : smartlist_t *nodes = smartlist_new();
939 7 : smartlist_add_all(nodes, nodelist_get_list());
940 :
941 7 : SMARTLIST_FOREACH_BEGIN(nodes, node_t *, node) {
942 0 : const char *msg = NULL;
943 0 : const char *description;
944 0 : routerinfo_t *ent = node->ri;
945 0 : uint32_t r;
946 0 : if (!ent)
947 0 : continue;
948 0 : r = dirserv_router_get_status(ent, &msg, LOG_INFO);
949 0 : description = router_describe(ent);
950 0 : if (r & RTR_REJECT) {
951 0 : log_info(LD_DIRSERV, "Router %s is now rejected: %s",
952 : description, msg?msg:"");
953 0 : routerlist_remove(rl, ent, 0, time(NULL));
954 0 : continue;
955 : }
956 0 : if (bool_neq((r & RTR_INVALID), !node->is_valid)) {
957 0 : log_info(LD_DIRSERV, "Router '%s' is now %svalid.", description,
958 : (r&RTR_INVALID) ? "in" : "");
959 0 : node->is_valid = (r&RTR_INVALID)?0:1;
960 : }
961 0 : if (bool_neq((r & RTR_BADEXIT), node->is_bad_exit)) {
962 0 : log_info(LD_DIRSERV, "Router '%s' is now a %s exit", description,
963 : (r & RTR_BADEXIT) ? "bad" : "good");
964 0 : node->is_bad_exit = (r&RTR_BADEXIT) ? 1: 0;
965 : }
966 0 : } SMARTLIST_FOREACH_END(node);
967 :
968 7 : routerlist_assert_ok(rl);
969 7 : smartlist_free(nodes);
970 7 : }
|