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