tor

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

extendinfo.c (9824B)


      1 /* Copyright (c) 2001 Matej Pfajfar.
      2 * Copyright (c) 2001-2004, Roger Dingledine.
      3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      5 /* See LICENSE for licensing information */
      6 
      7 /**
      8 * @file extendinfo.c
      9 * @brief Functions for creating and using extend_info_t objects.
     10 *
     11 * An extend_info_t is the information we hold about a relay in order to
     12 * extend a circuit to it.
     13 **/
     14 
     15 #include "core/or/or.h"
     16 #include "core/or/extendinfo.h"
     17 
     18 #include "app/config/config.h"
     19 #include "core/or/policies.h"
     20 #include "feature/nodelist/describe.h"
     21 #include "feature/nodelist/nodelist.h"
     22 #include "feature/relay/router.h"
     23 #include "feature/relay/routermode.h"
     24 #include "lib/crypt_ops/crypto_rand.h"
     25 
     26 #include "core/or/extend_info_st.h"
     27 #include "feature/nodelist/node_st.h"
     28 #include "feature/nodelist/routerinfo_st.h"
     29 #include "feature/nodelist/routerstatus_st.h"
     30 
     31 /** Allocate a new extend_info object based on the various arguments. */
     32 extend_info_t *
     33 extend_info_new(const char *nickname,
     34                const char *rsa_id_digest,
     35                const ed25519_public_key_t *ed_id,
     36                const curve25519_public_key_t *ntor_key,
     37                const tor_addr_t *addr, uint16_t port,
     38                const protover_summary_flags_t *pv,
     39                bool for_exit_use)
     40 {
     41  extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
     42  if (rsa_id_digest)
     43    memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN);
     44  if (ed_id && !ed25519_public_key_is_zero(ed_id))
     45    memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t));
     46  if (nickname)
     47    strlcpy(info->nickname, nickname, sizeof(info->nickname));
     48  if (ntor_key)
     49    memcpy(&info->curve25519_onion_key, ntor_key,
     50           sizeof(curve25519_public_key_t));
     51  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
     52    tor_addr_make_unspec(&info->orports[i].addr);
     53  }
     54 
     55  if (addr) {
     56    extend_info_add_orport(info, addr, port);
     57  }
     58 
     59  if (pv && for_exit_use) {
     60    info->exit_supports_congestion_control =
     61      pv->supports_congestion_control;
     62  }
     63 
     64  if (pv) {
     65    info->supports_ntor_v3 = pv->supports_ntor_v3;
     66    info->enable_cgo = pv->supports_cgo;
     67  }
     68 
     69  return info;
     70 }
     71 
     72 /**
     73 * Add another address:port pair to a given extend_info_t, if there is
     74 * room.  Return 0 on success, -1 on failure.
     75 **/
     76 int
     77 extend_info_add_orport(extend_info_t *ei,
     78                       const tor_addr_t *addr,
     79                       uint16_t port)
     80 {
     81  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
     82    if (tor_addr_is_unspec(&ei->orports[i].addr)) {
     83      tor_addr_copy(&ei->orports[i].addr, addr);
     84      ei->orports[i].port = port;
     85      return 0;
     86    }
     87  }
     88  return -1;
     89 }
     90 
     91 /** Allocate and return a new extend_info that can be used to build a
     92 * circuit to or through the node <b>node</b>. Use the primary address
     93 * of the node (i.e. its IPv4 address) unless
     94 * <b>for_direct_connect</b> is true, in which case the preferred
     95 * address is used instead. May return NULL if there is not enough
     96 * info about <b>node</b> to extend to it--for example, if the preferred
     97 * routerinfo_t or microdesc_t is missing, or if for_direct_connect is
     98 * true and none of the node's addresses is allowed by tor's firewall
     99 * and IP version config.
    100 **/
    101 extend_info_t *
    102 extend_info_from_node(const node_t *node, int for_direct_connect,
    103                      bool for_exit)
    104 {
    105  extend_info_t *info = NULL;
    106  tor_addr_port_t ap;
    107  int valid_addr = 0;
    108 
    109  if (!node_has_preferred_descriptor(node, for_direct_connect)) {
    110    return NULL;
    111  }
    112 
    113  /* Choose a preferred address first, but fall back to an allowed address. */
    114  if (for_direct_connect)
    115    reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0, &ap);
    116  else {
    117    node_get_prim_orport(node, &ap);
    118  }
    119  valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
    120 
    121  if (valid_addr)
    122    log_debug(LD_CIRC, "using %s for %s",
    123              fmt_addrport(&ap.addr, ap.port),
    124              node->ri ? node->ri->nickname : node->rs->nickname);
    125  else
    126    log_warn(LD_CIRC, "Could not choose valid address for %s",
    127              node->ri ? node->ri->nickname : node->rs->nickname);
    128 
    129  /* Every node we connect or extend to must support ntor */
    130  if (!node_has_curve25519_onion_key(node)) {
    131    log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
    132           "Attempted to create extend_info for a node that does not support "
    133           "ntor: %s", node_describe(node));
    134    return NULL;
    135  }
    136 
    137  const ed25519_public_key_t *ed_pubkey = NULL;
    138 
    139  /* Don't send the ed25519 pubkey unless the target node actually supports
    140   * authenticating with it. */
    141  if (node_supports_ed25519_link_authentication(node, 0)) {
    142    log_info(LD_CIRC, "Including Ed25519 ID for %s", node_describe(node));
    143    ed_pubkey = node_get_ed25519_id(node);
    144  } else if (node_get_ed25519_id(node)) {
    145    log_info(LD_CIRC, "Not including the ed25519 ID for %s, since it won't "
    146             "be able to authenticate it.",
    147             node_describe(node));
    148  }
    149 
    150  /* Retrieve the curve25519 pubkey. */
    151  const curve25519_public_key_t *curve_pubkey =
    152    node_get_curve25519_onion_key(node);
    153 
    154  if (valid_addr && node->ri) {
    155    info = extend_info_new(node->ri->nickname,
    156                           node->identity,
    157                           ed_pubkey,
    158                           curve_pubkey,
    159                           &ap.addr,
    160                           ap.port,
    161                           &node->ri->pv,
    162                           for_exit);
    163  } else if (valid_addr && node->rs && node->md) {
    164    info = extend_info_new(node->rs->nickname,
    165                           node->identity,
    166                           ed_pubkey,
    167                           curve_pubkey,
    168                           &ap.addr,
    169                           ap.port,
    170                           &node->rs->pv,
    171                           for_exit);
    172  }
    173 
    174  return info;
    175 }
    176 
    177 /** Release storage held by an extend_info_t struct. */
    178 void
    179 extend_info_free_(extend_info_t *info)
    180 {
    181  if (!info)
    182    return;
    183  tor_free(info);
    184 }
    185 
    186 /** Allocate and return a new extend_info_t with the same contents as
    187 * <b>info</b>. */
    188 extend_info_t *
    189 extend_info_dup(extend_info_t *info)
    190 {
    191  extend_info_t *newinfo;
    192  tor_assert(info);
    193  newinfo = tor_malloc(sizeof(extend_info_t));
    194  memcpy(newinfo, info, sizeof(extend_info_t));
    195  return newinfo;
    196 }
    197 
    198 /* Does ei have a valid ntor key? */
    199 int
    200 extend_info_supports_ntor(const extend_info_t* ei)
    201 {
    202  tor_assert(ei);
    203  /* Valid ntor keys have at least one non-zero byte */
    204  return !fast_mem_is_zero(
    205                          (const char*)ei->curve25519_onion_key.public_key,
    206                          CURVE25519_PUBKEY_LEN);
    207 }
    208 
    209 /** Return true if we can use the Ntor v3 handshake with `ei` */
    210 int
    211 extend_info_supports_ntor_v3(const extend_info_t *ei)
    212 {
    213  tor_assert(ei);
    214  return ei->supports_ntor_v3;
    215 }
    216 
    217 /* Does ei have an onion key which it would prefer to use?
    218 * Currently, we prefer ntor keys*/
    219 int
    220 extend_info_has_preferred_onion_key(const extend_info_t* ei)
    221 {
    222  tor_assert(ei);
    223  return extend_info_supports_ntor(ei);
    224 }
    225 
    226 /** Return true iff the given address can be used to extend to. */
    227 int
    228 extend_info_addr_is_allowed(const tor_addr_t *addr)
    229 {
    230  tor_assert(addr);
    231 
    232  /* Check if we have a private address and if we can extend to it. */
    233  if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) &&
    234      !get_options()->ExtendAllowPrivateAddresses) {
    235    goto disallow;
    236  }
    237  /* Allowed! */
    238  return 1;
    239 disallow:
    240  return 0;
    241 }
    242 
    243 /**
    244 * Return true if @a addr : @a port is a listed ORPort in @a ei.
    245 **/
    246 bool
    247 extend_info_has_orport(const extend_info_t *ei,
    248                       const tor_addr_t *addr, uint16_t port)
    249 {
    250  IF_BUG_ONCE(ei == NULL) {
    251    return false;
    252  }
    253 
    254  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
    255    const tor_addr_port_t *ei_ap = &ei->orports[i];
    256    if (tor_addr_eq(&ei_ap->addr, addr) && ei_ap->port == port)
    257      return true;
    258  }
    259  return false;
    260 }
    261 
    262 /**
    263 * If the extend_info @a ei has an orport of the chosen family, then return
    264 * that orport.  Otherwise, return NULL.
    265 **/
    266 const tor_addr_port_t *
    267 extend_info_get_orport(const extend_info_t *ei, int family)
    268 {
    269  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
    270    if (tor_addr_is_unspec(&ei->orports[i].addr))
    271      continue;
    272    if (tor_addr_family(&ei->orports[i].addr) == family)
    273      return &ei->orports[i];
    274  }
    275  return NULL;
    276 }
    277 
    278 /**
    279 * Chose an addr_port_t within @a ei to connect to.
    280 **/
    281 const tor_addr_port_t *
    282 extend_info_pick_orport(const extend_info_t *ei)
    283 {
    284  IF_BUG_ONCE(!ei) {
    285    return NULL;
    286  }
    287  const or_options_t *options = get_options();
    288  if (!server_mode(options)) {
    289    // If we aren't a server, just pick the first address we built into
    290    // this extendinfo.
    291    return &ei->orports[0];
    292  }
    293 
    294  const bool ipv6_ok = router_can_extend_over_ipv6(options);
    295 
    296  // Use 'usable' to collect the usable orports, then pick one.
    297  const tor_addr_port_t *usable[EXTEND_INFO_MAX_ADDRS];
    298  int n_usable = 0;
    299  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
    300    const tor_addr_port_t *a = &ei->orports[i];
    301    const int family = tor_addr_family(&a->addr);
    302    if (family == AF_INET || (ipv6_ok && family == AF_INET6)) {
    303      usable[n_usable++] = a;
    304    }
    305  }
    306 
    307  if (n_usable == 0) {
    308    // Need to bail out early, since nothing will work.
    309    return NULL;
    310  }
    311 
    312  crypto_fast_rng_t *rng = get_thread_fast_rng();
    313  const int idx = crypto_fast_rng_get_uint(rng, n_usable);
    314 
    315  return usable[idx];
    316 }
    317 
    318 /**
    319 * Return true if any orport address in @a ei is an internal address.
    320 **/
    321 bool
    322 extend_info_any_orport_addr_is_internal(const extend_info_t *ei)
    323 {
    324  IF_BUG_ONCE(ei == NULL) {
    325    return false;
    326  }
    327 
    328  for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
    329    if (! tor_addr_is_unspec(&ei->orports[i].addr) &&
    330        tor_addr_is_internal(&ei->orports[i].addr, 0))
    331      return true;
    332  }
    333  return false;
    334 }