tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

process_descs.c (35171B)


      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 authdir_config_new(void)
     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. */
     80 void
     81 authdir_init_fingerprint_list(void)
     82 {
     83  fingerprint_list = authdir_config_new();
     84 }
     85 
     86 /* Return the current fingerprint_list. Used for tests. */
     87 authdir_config_t *
     88 authdir_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 */
     99 int
    100 add_rsa_fingerprint_to_dir(const char *fp, authdir_config_t *list,
    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, " ");
    111  if (base16_decode(d, DIGEST_LEN,
    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 */
    134 int
    135 add_ed25519_to_dir(const ed25519_public_key_t *edkey, authdir_config_t *list,
    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. */
    160 int
    161 dirserv_add_own_fingerprint(crypto_pk_t *pk, const ed25519_public_key_t *edkey)
    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)
    169    fingerprint_list = authdir_config_new();
    170  if (add_rsa_fingerprint_to_dir(fp, fingerprint_list, 0) < 0) {
    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. */
    186 int
    187 dirserv_load_fingerprint_file(void)
    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    } else if (!strcasecmp(nickname, "!stripguard")) {
    232        add_status = RTR_STRIPGUARD;
    233    } else if (!strcasecmp(nickname, "!striphsdir")) {
    234        add_status = RTR_STRIPHSDIR;
    235    } else if (!strcasecmp(nickname, "!stripv2dir")) {
    236        add_status = RTR_STRIPV2DIR;
    237    }
    238 
    239    /* Check if fingerprint is RSA or ed25519 by verifying it. */
    240    int ed25519_not_ok = -1, rsa_not_ok = -1;
    241 
    242    /* Attempt to add the RSA key. */
    243    if (strlen(fingerprint) == HEX_DIGEST_LEN) {
    244      rsa_not_ok = add_rsa_fingerprint_to_dir(fingerprint,
    245                                              fingerprint_list_new,
    246                                              add_status);
    247    }
    248 
    249    /* Check ed25519 key. We check the size to prevent buffer overflows.
    250     * If valid, attempt to add it, */
    251    ed25519_public_key_t ed25519_pubkey_tmp;
    252    if (strlen(fingerprint) == BASE64_DIGEST256_LEN) {
    253      if (!digest256_from_base64((char *) ed25519_pubkey_tmp.pubkey,
    254                                 fingerprint)) {
    255        ed25519_not_ok = add_ed25519_to_dir(&ed25519_pubkey_tmp,
    256                                            fingerprint_list_new, add_status);
    257      }
    258    }
    259 
    260    /* If both keys are invalid (or missing), log and skip. */
    261    if (ed25519_not_ok && rsa_not_ok) {
    262      log_warn(LD_CONFIG, "Invalid fingerprint (nickname '%s', "
    263               "fingerprint %s). Skipping.", nickname, fingerprint);
    264      continue;
    265    }
    266  }
    267 
    268  config_free_lines(front);
    269  dirserv_free_fingerprint_list();
    270  fingerprint_list = fingerprint_list_new;
    271  /* Delete any routers whose fingerprints we no longer recognize */
    272  directory_remove_invalid();
    273  return 0;
    274 }
    275 
    276 /* If this is set, then we don't allow routers that have advertised an Ed25519
    277 * identity to stop doing so.  This is going to be essential for good identity
    278 * security: otherwise anybody who can attack RSA-1024 but not Ed25519 could
    279 * just sign fake descriptors missing the Ed25519 key.  But we won't actually
    280 * be able to prevent that kind of thing until we're confident that there isn't
    281 * actually a legit reason to downgrade to 0.2.5.  Now we are not recommending
    282 * 0.2.5 anymore so there is no reason to keep the #undef.
    283 */
    284 
    285 #define DISABLE_DISABLING_ED25519
    286 
    287 /** Check whether <b>router</b> has:
    288 * - a nickname/identity key combination that we recognize from the fingerprint
    289 *   list,
    290 * - an IP we automatically act on according to our configuration,
    291 * - an appropriate version, and
    292 * - matching pinned keys.
    293 *
    294 * Return the appropriate router status.
    295 *
    296 * If the status is 'RTR_REJECT' and <b>msg</b> is provided, set
    297 * *<b>msg</b> to a string constant explaining why. */
    298 uint32_t
    299 dirserv_router_get_status(const routerinfo_t *router, const char **msg,
    300                          int severity)
    301 {
    302  char d[DIGEST_LEN];
    303  const int key_pinning = dirauth_get_options()->AuthDirPinKeys;
    304  uint32_t r;
    305  ed25519_public_key_t *signing_key = NULL;
    306 
    307  if (crypto_pk_get_digest(router->identity_pkey, d)) {
    308    log_warn(LD_BUG,"Error computing fingerprint");
    309    if (msg)
    310      *msg = "Bug: Error computing fingerprint";
    311    return RTR_REJECT;
    312  }
    313 
    314  /* First, check for the more common reasons to reject a router. */
    315  if (router->cache_info.signing_key_cert) {
    316    /* This has an ed25519 identity key. */
    317    signing_key = &router->cache_info.signing_key_cert->signing_key;
    318  }
    319  r = dirserv_get_status_impl(d, signing_key, router->nickname,
    320                              &router->ipv4_addr, router->ipv4_orport,
    321                              router->platform, msg, severity);
    322 
    323  if (r)
    324    return r;
    325 
    326  /* dirserv_get_status_impl already rejects versions older than 0.2.4.18-rc,
    327   * and onion_curve25519_pkey was introduced in 0.2.4.8-alpha.
    328   * But just in case a relay doesn't provide or lies about its version, or
    329   * doesn't include an ntor key in its descriptor, check that it exists,
    330   * and is non-zero (clients check that it's non-zero before using it). */
    331  if (!routerinfo_has_curve25519_onion_key(router)) {
    332    log_fn(severity, LD_DIR,
    333           "Descriptor from router %s (platform %s) "
    334           "is missing an ntor curve25519 onion key.",
    335           router_describe(router), router->platform);
    336    if (msg)
    337      *msg = "Missing ntor curve25519 onion key. Please upgrade!";
    338    return RTR_REJECT;
    339  }
    340 
    341  if (router->cache_info.signing_key_cert) {
    342    /* This has an ed25519 identity key. */
    343    if (KEYPIN_MISMATCH ==
    344        keypin_check((const uint8_t*)router->cache_info.identity_digest,
    345                   router->cache_info.signing_key_cert->signing_key.pubkey)) {
    346      log_fn(severity, LD_DIR,
    347             "Descriptor from router %s has an Ed25519 key, "
    348               "but the <rsa,ed25519> keys don't match what they were before.",
    349               router_describe(router));
    350      if (key_pinning) {
    351        if (msg) {
    352          *msg = "Ed25519 identity key or RSA identity key has changed.";
    353        }
    354        return RTR_REJECT;
    355      }
    356    }
    357  } else {
    358    /* No ed25519 key */
    359    if (KEYPIN_MISMATCH == keypin_check_lone_rsa(
    360                        (const uint8_t*)router->cache_info.identity_digest)) {
    361      log_fn(severity, LD_DIR,
    362               "Descriptor from router %s has no Ed25519 key, "
    363               "when we previously knew an Ed25519 for it. Ignoring for now, "
    364               "since Ed25519 keys are fairly new.",
    365               router_describe(router));
    366 #ifdef DISABLE_DISABLING_ED25519
    367      if (key_pinning) {
    368        if (msg) {
    369          *msg = "Ed25519 identity key has disappeared.";
    370        }
    371        return RTR_REJECT;
    372      }
    373 #endif /* defined(DISABLE_DISABLING_ED25519) */
    374    }
    375  }
    376 
    377  return 0;
    378 }
    379 
    380 /** Return true if there is no point in downloading the router described by
    381 * <b>rs</b> because this directory would reject it. */
    382 int
    383 dirserv_would_reject_router(const routerstatus_t *rs,
    384                            const vote_routerstatus_t *vrs)
    385 {
    386  uint32_t res;
    387  struct ed25519_public_key_t pk;
    388  memcpy(&pk.pubkey, vrs->ed25519_id, ED25519_PUBKEY_LEN);
    389 
    390  res = dirserv_get_status_impl(rs->identity_digest, &pk, rs->nickname,
    391                                &rs->ipv4_addr, rs->ipv4_orport, NULL, NULL,
    392                                LOG_DEBUG);
    393 
    394  return (res & RTR_REJECT) != 0;
    395 }
    396 
    397 /**
    398 * Check whether the platform string in <b>platform</b> describes a platform
    399 * that, as a directory authority, we want to reject.  If it does, return
    400 * true, and set *<b>msg</b> (if present) to a rejection message.  Otherwise
    401 * return false.
    402 */
    403 STATIC bool
    404 dirserv_rejects_tor_version(const char *platform,
    405                            const char **msg)
    406 {
    407  if (!platform)
    408    return false;
    409 
    410  static const char please_upgrade_string[] =
    411    "Tor version is insecure or unsupported. Please upgrade!";
    412 
    413  if (!tor_version_as_new_as(platform,
    414        dirauth_get_options()->MinimalAcceptedServerVersion)) {
    415    if (msg) {
    416      *msg = please_upgrade_string;
    417    }
    418    return true;
    419  }
    420 
    421  return false;
    422 }
    423 
    424 /** Helper: As dirserv_router_get_status, but takes the router fingerprint
    425 * (hex, no spaces), ed25519 key, nickname, address (used for logging only),
    426 * IP address, OR port and platform (logging only) as arguments.
    427 *
    428 * Log messages at 'severity'. (There's not much point in
    429 * logging that we're rejecting servers we'll not download.)
    430 */
    431 static uint32_t
    432 dirserv_get_status_impl(const char *id_digest,
    433                        const ed25519_public_key_t *ed25519_public_key,
    434                        const char *nickname, const tor_addr_t *ipv4_addr,
    435                        uint16_t ipv4_orport, const char *platform,
    436                        const char **msg, int severity)
    437 {
    438  uint32_t result = 0;
    439  rtr_flags_t *status_by_digest;
    440 
    441  if (!fingerprint_list)
    442    fingerprint_list = authdir_config_new();
    443 
    444  log_debug(LD_DIRSERV, "%d fingerprints, %d digests known.",
    445            strmap_size(fingerprint_list->fp_by_name),
    446            digestmap_size(fingerprint_list->status_by_digest));
    447 
    448  if (platform) {
    449    tor_version_t ver_tmp;
    450    if (tor_version_parse_platform(platform, &ver_tmp, 1) < 0) {
    451      if (msg) {
    452        *msg = "Malformed platform string.";
    453      }
    454      return RTR_REJECT;
    455    }
    456  }
    457 
    458  /* Check whether the version is obsolete, broken, insecure, etc... */
    459  if (platform && dirserv_rejects_tor_version(platform, msg)) {
    460    return RTR_REJECT;
    461  }
    462 
    463  status_by_digest = digestmap_get(fingerprint_list->status_by_digest,
    464                                   id_digest);
    465  if (status_by_digest)
    466    result |= *status_by_digest;
    467 
    468  if (ed25519_public_key) {
    469    status_by_digest = digest256map_get(fingerprint_list->status_by_digest256,
    470                                        ed25519_public_key->pubkey);
    471    if (status_by_digest)
    472      result |= *status_by_digest;
    473  }
    474 
    475  if (result & RTR_REJECT) {
    476    if (msg)
    477      *msg = "Fingerprint and/or ed25519 identity is marked rejected -- if "
    478             "you think this is a mistake please set a valid email address "
    479             "in ContactInfo and send an email to "
    480             "bad-relays@lists.torproject.org mentioning your fingerprint(s)?";
    481    return RTR_REJECT;
    482  } else if (result & RTR_INVALID) {
    483    if (msg)
    484      *msg = "Fingerprint and/or ed25519 identity is marked invalid";
    485  }
    486 
    487  if (authdir_policy_badexit_address(ipv4_addr, ipv4_orport)) {
    488    log_fn(severity, LD_DIRSERV,
    489           "Marking '%s' as bad exit because of address '%s'",
    490               nickname, fmt_addr(ipv4_addr));
    491    result |= RTR_BADEXIT;
    492  }
    493 
    494  if (authdir_policy_middleonly_address(ipv4_addr, ipv4_orport)) {
    495    log_fn(severity, LD_DIRSERV,
    496           "Marking '%s' as middle-only because of address '%s'",
    497               nickname, fmt_addr(ipv4_addr));
    498    result |= RTR_MIDDLEONLY;
    499  }
    500 
    501  if (!authdir_policy_permits_address(ipv4_addr, ipv4_orport)) {
    502    log_fn(severity, LD_DIRSERV, "Rejecting '%s' because of address '%s'",
    503               nickname, fmt_addr(ipv4_addr));
    504    if (msg)
    505      *msg = "Suspicious relay address range -- if you think this is a "
    506             "mistake please set a valid email address in ContactInfo and "
    507             "send an email to bad-relays@lists.torproject.org mentioning "
    508             "your address(es) and fingerprint(s)?";
    509    return RTR_REJECT;
    510  }
    511  if (!authdir_policy_valid_address(ipv4_addr, ipv4_orport)) {
    512    log_fn(severity, LD_DIRSERV,
    513           "Not marking '%s' valid because of address '%s'",
    514               nickname, fmt_addr(ipv4_addr));
    515    result |= RTR_INVALID;
    516  }
    517 
    518  return result;
    519 }
    520 
    521 /** Clear the current fingerprint list. */
    522 void
    523 dirserv_free_fingerprint_list(void)
    524 {
    525  if (!fingerprint_list)
    526    return;
    527 
    528  strmap_free(fingerprint_list->fp_by_name, tor_free_);
    529  digestmap_free(fingerprint_list->status_by_digest, tor_free_);
    530  digest256map_free(fingerprint_list->status_by_digest256, tor_free_);
    531  tor_free(fingerprint_list);
    532 }
    533 
    534 /*
    535 *    Descriptor list
    536 */
    537 
    538 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
    539 * unless we're configured to not care. Return 0 if all ok. */
    540 STATIC int
    541 dirserv_router_has_valid_address(routerinfo_t *ri)
    542 {
    543  if (get_options()->DirAllowPrivateAddresses)
    544    return 0; /* whatever it is, we're fine with it */
    545 
    546  if (tor_addr_is_null(&ri->ipv4_addr) ||
    547      tor_addr_is_internal(&ri->ipv4_addr, 0)) {
    548    log_info(LD_DIRSERV,
    549             "Router %s published internal IPv4 address. Refusing.",
    550             router_describe(ri));
    551    return -1; /* it's a private IP, we should reject it */
    552  }
    553 
    554  /* We only check internal v6 on non-null addresses because we do not require
    555   * IPv6 and null IPv6 is normal. */
    556  if (!tor_addr_is_null(&ri->ipv6_addr) &&
    557      tor_addr_is_internal(&ri->ipv6_addr, 0)) {
    558    log_info(LD_DIRSERV,
    559             "Router %s published internal IPv6 address. Refusing.",
    560             router_describe(ri));
    561    return -1; /* it's a private IP, we should reject it */
    562  }
    563 
    564  return 0;
    565 }
    566 
    567 /** Check whether we, as a directory server, want to accept <b>ri</b>.  If so,
    568 * set its is_valid,running fields and return 0.  Otherwise, return -1.
    569 *
    570 * If the router is rejected, set *<b>msg</b> to a string constant explining
    571 * why.
    572 *
    573 * If <b>complain</b> then explain at log-level 'notice' why we refused
    574 * a descriptor; else explain at log-level 'info'.
    575 */
    576 int
    577 authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
    578                               int complain, int *valid_out)
    579 {
    580  /* Okay.  Now check whether the fingerprint is recognized. */
    581  time_t now;
    582  int severity = (complain && ri->contact_info) ? LOG_NOTICE : LOG_INFO;
    583  uint32_t status = dirserv_router_get_status(ri, msg, severity);
    584  tor_assert(msg);
    585  if (status & RTR_REJECT)
    586    return -1; /* msg is already set. */
    587 
    588  /* Is there too much clock skew? */
    589  now = time(NULL);
    590  if (ri->cache_info.published_on > now+ROUTER_ALLOW_SKEW) {
    591    log_fn(severity, LD_DIRSERV, "Publication time for %s is too "
    592           "far (%d minutes) in the future; possible clock skew. Not adding "
    593           "(%s)",
    594           router_describe(ri),
    595           (int)((ri->cache_info.published_on-now)/60),
    596           esc_router_info(ri));
    597    *msg = "Rejected: Your clock is set too far in the future, or your "
    598      "timezone is not correct.";
    599    return -1;
    600  }
    601  if (ri->cache_info.published_on < now-ROUTER_MAX_AGE_TO_PUBLISH) {
    602    log_fn(severity, LD_DIRSERV,
    603           "Publication time for %s is too far "
    604           "(%d minutes) in the past. Not adding (%s)",
    605           router_describe(ri),
    606           (int)((now-ri->cache_info.published_on)/60),
    607           esc_router_info(ri));
    608    *msg = "Rejected: Server is expired, or your clock is too far in the past,"
    609      " or your timezone is not correct.";
    610    return -1;
    611  }
    612  if (dirserv_router_has_valid_address(ri) < 0) {
    613    log_fn(severity, LD_DIRSERV,
    614           "Router %s has invalid address. Not adding (%s).",
    615           router_describe(ri),
    616           esc_router_info(ri));
    617    *msg = "Rejected: Address is a private address.";
    618    return -1;
    619  }
    620 
    621  *valid_out = ! (status & RTR_INVALID);
    622 
    623  return 0;
    624 }
    625 
    626 /** Update the relevant flags of <b>node</b> based on our opinion as a
    627 * directory authority in <b>authstatus</b>, as returned by
    628 * dirserv_router_get_status or equivalent.  */
    629 void
    630 dirserv_set_node_flags_from_authoritative_status(node_t *node,
    631                                                 uint32_t authstatus)
    632 {
    633  node->is_valid = (authstatus & RTR_INVALID) ? 0 : 1;
    634  node->is_bad_exit = (authstatus & RTR_BADEXIT) ? 1 : 0;
    635  node->is_middle_only = (authstatus & RTR_MIDDLEONLY) ? 1 : 0;
    636  node->strip_guard = (authstatus & RTR_STRIPGUARD) ? 1 : 0;
    637  node->strip_hsdir = (authstatus & RTR_STRIPHSDIR) ? 1 : 0;
    638  node->strip_v2dir = (authstatus & RTR_STRIPV2DIR) ? 1 : 0;
    639 }
    640 
    641 /** True iff <b>a</b> is more severe than <b>b</b>. */
    642 static int
    643 WRA_MORE_SEVERE(was_router_added_t a, was_router_added_t b)
    644 {
    645  return a < b;
    646 }
    647 
    648 /** As for dirserv_add_descriptor(), but accepts multiple documents, and
    649 * returns the most severe error that occurred for any one of them. */
    650 was_router_added_t
    651 dirserv_add_multiple_descriptors(const char *desc, size_t desclen,
    652                                 uint8_t purpose,
    653                                 const char *source,
    654                                 const char **msg)
    655 {
    656  was_router_added_t r, r_tmp;
    657  const char *msg_out;
    658  smartlist_t *list;
    659  const char *s;
    660  int n_parsed = 0;
    661  time_t now = time(NULL);
    662  char annotation_buf[ROUTER_ANNOTATION_BUF_LEN];
    663  char time_buf[ISO_TIME_LEN+1];
    664  int general = purpose == ROUTER_PURPOSE_GENERAL;
    665  tor_assert(msg);
    666 
    667  r=ROUTER_ADDED_SUCCESSFULLY; /* Least severe return value. */
    668 
    669  if (!string_is_utf8_no_bom(desc, desclen)) {
    670    *msg = "descriptor(s) or extrainfo(s) not valid UTF-8 or had BOM.";
    671    return ROUTER_AUTHDIR_REJECTS;
    672  }
    673 
    674  format_iso_time(time_buf, now);
    675  if (tor_snprintf(annotation_buf, sizeof(annotation_buf),
    676                   "@uploaded-at %s\n"
    677                   "@source %s\n"
    678                   "%s%s%s", time_buf, escaped(source),
    679                   !general ? "@purpose " : "",
    680                   !general ? router_purpose_to_string(purpose) : "",
    681                   !general ? "\n" : "")<0) {
    682    *msg = "Couldn't format annotations";
    683    return ROUTER_AUTHDIR_BUG_ANNOTATIONS;
    684  }
    685 
    686  s = desc;
    687  list = smartlist_new();
    688  if (!router_parse_list_from_string(&s, s+desclen, list, SAVED_NOWHERE, 0, 0,
    689                                     annotation_buf, NULL)) {
    690    SMARTLIST_FOREACH(list, routerinfo_t *, ri, {
    691        msg_out = NULL;
    692        tor_assert(ri->purpose == purpose);
    693        r_tmp = dirserv_add_descriptor(ri, &msg_out, source);
    694        if (WRA_MORE_SEVERE(r_tmp, r)) {
    695          r = r_tmp;
    696          *msg = msg_out;
    697        }
    698      });
    699  }
    700  n_parsed += smartlist_len(list);
    701  smartlist_clear(list);
    702 
    703  s = desc;
    704  if (!router_parse_list_from_string(&s, s+desclen, list, SAVED_NOWHERE, 1, 0,
    705                                     NULL, NULL)) {
    706    SMARTLIST_FOREACH(list, extrainfo_t *, ei, {
    707        msg_out = NULL;
    708 
    709        r_tmp = dirserv_add_extrainfo(ei, &msg_out);
    710        if (WRA_MORE_SEVERE(r_tmp, r)) {
    711          r = r_tmp;
    712          *msg = msg_out;
    713        }
    714      });
    715  }
    716  n_parsed += smartlist_len(list);
    717  smartlist_free(list);
    718 
    719  if (! *msg) {
    720    if (!n_parsed) {
    721      *msg = "No descriptors found in your POST.";
    722      if (WRA_WAS_ADDED(r))
    723        r = ROUTER_IS_ALREADY_KNOWN;
    724    } else {
    725      *msg = "(no message)";
    726    }
    727  }
    728 
    729  return r;
    730 }
    731 
    732 /** Examine the parsed server descriptor in <b>ri</b> and maybe insert it into
    733 * the list of server descriptors. Set *<b>msg</b> to a message that should be
    734 * passed back to the origin of this descriptor, or NULL if there is no such
    735 * message. Use <b>source</b> to produce better log messages.
    736 *
    737 * If <b>ri</b> is not added to the list of server descriptors, free it.
    738 * That means the caller must not access <b>ri</b> after this function
    739 * returns, since it might have been freed.
    740 *
    741 * Return the status of the operation, and set *<b>msg</b> to a string
    742 * constant describing the status.
    743 *
    744 * This function is only called when fresh descriptors are posted, not when
    745 * we re-load the cache.
    746 */
    747 was_router_added_t
    748 dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
    749 {
    750  was_router_added_t r;
    751  routerinfo_t *ri_old;
    752  char *desc, *nickname;
    753  const size_t desclen = ri->cache_info.signed_descriptor_len +
    754      ri->cache_info.annotations_len;
    755  const int key_pinning = dirauth_get_options()->AuthDirPinKeys;
    756  *msg = NULL;
    757 
    758  /* If it's too big, refuse it now. Otherwise we'll cache it all over the
    759   * network and it'll clog everything up. */
    760  if (ri->cache_info.signed_descriptor_len > MAX_DESCRIPTOR_UPLOAD_SIZE) {
    761    log_notice(LD_DIR, "Somebody attempted to publish a router descriptor '%s'"
    762               " (source: %s) with size %d. Either this is an attack, or the "
    763               "MAX_DESCRIPTOR_UPLOAD_SIZE (%d) constant is too low.",
    764               ri->nickname, source, (int)ri->cache_info.signed_descriptor_len,
    765               MAX_DESCRIPTOR_UPLOAD_SIZE);
    766    *msg = "Router descriptor was too large.";
    767    r = ROUTER_AUTHDIR_REJECTS;
    768    goto fail;
    769  }
    770 
    771  log_info(LD_DIR, "Assessing new descriptor: %s: %s",
    772           ri->nickname, ri->platform);
    773 
    774  /* For now, TAP keys are still required. */
    775  if (! ri->tap_onion_pkey) {
    776    log_info(LD_DIRSERV, "Rejecting descriptor from %s (source: %s); "
    777             "it has no TAP key.",
    778             router_describe(ri), source);
    779    *msg = "Missing TAP key in descriptor.";
    780    r = ROUTER_AUTHDIR_REJECTS;
    781    goto fail;
    782  }
    783 
    784  /* Check whether this descriptor is semantically identical to the last one
    785   * from this server.  (We do this here and not in router_add_to_routerlist
    786   * because we want to be able to accept the newest router descriptor that
    787   * another authority has, so we all converge on the same one.) */
    788  ri_old = router_get_mutable_by_digest(ri->cache_info.identity_digest);
    789  if (ri_old && ri_old->cache_info.published_on < ri->cache_info.published_on
    790      && router_differences_are_cosmetic(ri_old, ri)
    791      && !router_is_me(ri)) {
    792    log_info(LD_DIRSERV,
    793             "Not replacing descriptor from %s (source: %s); "
    794             "differences are cosmetic.",
    795             router_describe(ri), source);
    796    *msg = "Not replacing router descriptor; no information has changed since "
    797      "the last one with this identity.";
    798    r = ROUTER_IS_ALREADY_KNOWN;
    799    goto fail;
    800  }
    801 
    802  /* Do keypinning again ... this time, to add the pin if appropriate */
    803  int keypin_status;
    804  if (ri->cache_info.signing_key_cert) {
    805    ed25519_public_key_t *pkey = &ri->cache_info.signing_key_cert->signing_key;
    806    /* First let's validate this pubkey before pinning it */
    807    if (ed25519_validate_pubkey(pkey) < 0) {
    808      log_warn(LD_DIRSERV, "Received bad key from %s (source %s)",
    809               router_describe(ri), source);
    810      routerinfo_free(ri);
    811      return ROUTER_AUTHDIR_REJECTS;
    812    }
    813 
    814    /* Now pin it! */
    815    keypin_status = keypin_check_and_add(
    816      (const uint8_t*)ri->cache_info.identity_digest,
    817      pkey->pubkey, ! key_pinning);
    818  } else {
    819    keypin_status = keypin_check_lone_rsa(
    820      (const uint8_t*)ri->cache_info.identity_digest);
    821 #ifndef DISABLE_DISABLING_ED25519
    822    if (keypin_status == KEYPIN_MISMATCH)
    823      keypin_status = KEYPIN_NOT_FOUND;
    824 #endif
    825  }
    826  if (keypin_status == KEYPIN_MISMATCH && key_pinning) {
    827    log_info(LD_DIRSERV, "Dropping descriptor from %s (source: %s) because "
    828             "its key did not match an older RSA/Ed25519 keypair",
    829             router_describe(ri), source);
    830    *msg = "Looks like your keypair has changed? This authority previously "
    831      "recorded a different RSA identity for this Ed25519 identity (or vice "
    832      "versa.) Did you replace or copy some of your key files, but not "
    833      "the others? You should either restore the expected keypair, or "
    834      "delete your keys and restart Tor to start your relay with a new "
    835      "identity.";
    836    r = ROUTER_AUTHDIR_REJECTS;
    837    goto fail;
    838  }
    839 
    840  /* Make a copy of desc, since router_add_to_routerlist might free
    841   * ri and its associated signed_descriptor_t. */
    842  desc = tor_strndup(ri->cache_info.signed_descriptor_body, desclen);
    843  nickname = tor_strdup(ri->nickname);
    844 
    845  /* Tell if we're about to need to launch a test if we add this. */
    846  ri->needs_retest_if_added =
    847    dirserv_should_launch_reachability_test(ri, ri_old);
    848 
    849  r = router_add_to_routerlist(ri, msg, 0, 0);
    850  if (!WRA_WAS_ADDED(r)) {
    851    /* unless the routerinfo was fine, just out-of-date */
    852    log_info(LD_DIRSERV,
    853             "Did not add descriptor from '%s' (source: %s): %s.",
    854             nickname, source, *msg ? *msg : "(no message)");
    855  } else {
    856    smartlist_t *changed;
    857 
    858    changed = smartlist_new();
    859    smartlist_add(changed, ri);
    860    routerlist_descriptors_added(changed, 0);
    861    smartlist_free(changed);
    862    if (!*msg) {
    863      *msg =  "Descriptor accepted";
    864    }
    865    log_info(LD_DIRSERV,
    866             "Added descriptor from '%s' (source: %s): %s.",
    867             nickname, source, *msg);
    868  }
    869  tor_free(desc);
    870  tor_free(nickname);
    871  return r;
    872 fail:
    873  {
    874    const char *desc_digest = ri->cache_info.signed_descriptor_digest;
    875    download_status_t *dls =
    876      router_get_dl_status_by_descriptor_digest(desc_digest);
    877    if (dls) {
    878      log_info(LD_GENERAL, "Marking router with descriptor %s as rejected, "
    879               "and therefore undownloadable",
    880               hex_str(desc_digest, DIGEST_LEN));
    881      download_status_mark_impossible(dls);
    882    }
    883    routerinfo_free(ri);
    884  }
    885  return r;
    886 }
    887 
    888 /** As dirserv_add_descriptor, but for an extrainfo_t <b>ei</b>. */
    889 static was_router_added_t
    890 dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
    891 {
    892  routerinfo_t *ri;
    893  int r;
    894  was_router_added_t rv;
    895  tor_assert(msg);
    896  *msg = NULL;
    897 
    898  /* Needs to be mutable so routerinfo_incompatible_with_extrainfo
    899   * can mess with some of the flags in ri->cache_info. */
    900  ri = router_get_mutable_by_digest(ei->cache_info.identity_digest);
    901  if (!ri) {
    902    *msg = "No corresponding router descriptor for extra-info descriptor";
    903    rv = ROUTER_BAD_EI;
    904    goto fail;
    905  }
    906 
    907  /* If it's too big, refuse it now. Otherwise we'll cache it all over the
    908   * network and it'll clog everything up. */
    909  if (ei->cache_info.signed_descriptor_len > MAX_EXTRAINFO_UPLOAD_SIZE) {
    910    log_notice(LD_DIR, "Somebody attempted to publish an extrainfo "
    911               "with size %d. Either this is an attack, or the "
    912               "MAX_EXTRAINFO_UPLOAD_SIZE (%d) constant is too low.",
    913               (int)ei->cache_info.signed_descriptor_len,
    914               MAX_EXTRAINFO_UPLOAD_SIZE);
    915    *msg = "Extrainfo document was too large";
    916    rv = ROUTER_BAD_EI;
    917    goto fail;
    918  }
    919 
    920  if ((r = routerinfo_incompatible_with_extrainfo(ri->identity_pkey, ei,
    921                                                  &ri->cache_info, msg))) {
    922    if (r<0) {
    923      extrainfo_free(ei);
    924      return ROUTER_IS_ALREADY_KNOWN;
    925    }
    926    rv = ROUTER_BAD_EI;
    927    goto fail;
    928  }
    929  router_add_extrainfo_to_routerlist(ei, msg, 0, 0);
    930  return ROUTER_ADDED_SUCCESSFULLY;
    931 fail:
    932  {
    933    const char *d = ei->cache_info.signed_descriptor_digest;
    934    signed_descriptor_t *sd = router_get_by_extrainfo_digest((char*)d);
    935    if (sd) {
    936      log_info(LD_GENERAL, "Marking extrainfo with descriptor %s as "
    937               "rejected, and therefore undownloadable",
    938               hex_str((char*)d,DIGEST_LEN));
    939      download_status_mark_impossible(&sd->ei_dl_status);
    940    }
    941    extrainfo_free(ei);
    942  }
    943  return rv;
    944 }
    945 
    946 /** Remove all descriptors whose nicknames or fingerprints no longer
    947 * are allowed by our fingerprint list. (Descriptors that used to be
    948 * good can become bad when we reload the fingerprint list.)
    949 */
    950 static void
    951 directory_remove_invalid(void)
    952 {
    953  routerlist_t *rl = router_get_routerlist();
    954  smartlist_t *nodes = smartlist_new();
    955  smartlist_add_all(nodes, nodelist_get_list());
    956 
    957  SMARTLIST_FOREACH_BEGIN(nodes, node_t *, node) {
    958    const char *msg = NULL;
    959    const char *description;
    960    routerinfo_t *ent = node->ri;
    961    uint32_t r;
    962    if (!ent)
    963      continue;
    964    r = dirserv_router_get_status(ent, &msg, LOG_INFO);
    965    description = router_describe(ent);
    966    if (r & RTR_REJECT) {
    967      log_info(LD_DIRSERV, "Router %s is now rejected: %s",
    968               description, msg?msg:"");
    969      routerlist_remove(rl, ent, 0, time(NULL));
    970      continue;
    971    }
    972    if (bool_neq((r & RTR_INVALID), !node->is_valid)) {
    973      log_info(LD_DIRSERV, "Router '%s' is now %svalid.", description,
    974               (r&RTR_INVALID) ? "in" : "");
    975      node->is_valid = (r&RTR_INVALID)?0:1;
    976    }
    977    if (bool_neq((r & RTR_BADEXIT), node->is_bad_exit)) {
    978      log_info(LD_DIRSERV, "Router '%s' is now a %s exit", description,
    979               (r & RTR_BADEXIT) ? "bad" : "good");
    980      node->is_bad_exit = (r&RTR_BADEXIT) ? 1: 0;
    981    }
    982    if (bool_neq((r & RTR_MIDDLEONLY), node->is_middle_only)) {
    983      log_info(LD_DIRSERV, "Router '%s' is now %smiddle-only", description,
    984               (r & RTR_MIDDLEONLY) ? "" : "not");
    985      node->is_middle_only = (r&RTR_MIDDLEONLY) ? 1: 0;
    986    }
    987    if (bool_neq((r & RTR_STRIPGUARD), node->strip_guard)) {
    988      log_info(LD_DIRSERV, "Router '%s' is now %s guard", description,
    989               (r & RTR_STRIPGUARD) ? "stripped of" : "not");
    990      node->strip_guard = (r&RTR_STRIPGUARD) ? 1: 0;
    991    }
    992    if (bool_neq((r & RTR_STRIPHSDIR), node->strip_hsdir)) {
    993      log_info(LD_DIRSERV, "Router '%s' is now %s hidden service directory",
    994               description, (r & RTR_STRIPHSDIR) ? "stripped of" : "not");
    995      node->strip_hsdir = (r&RTR_STRIPHSDIR) ? 1: 0;
    996    }
    997    if (bool_neq((r & RTR_STRIPV2DIR), node->strip_v2dir)) {
    998      log_info(LD_DIRSERV, "Router '%s' is now %s v2 directory",
    999               description, (r & RTR_STRIPV2DIR) ? "stripped of" : "not");
   1000      node->strip_v2dir = (r&RTR_STRIPV2DIR) ? 1: 0;
   1001    }
   1002  } SMARTLIST_FOREACH_END(node);
   1003 
   1004  routerlist_assert_ok(rl);
   1005  smartlist_free(nodes);
   1006 }