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 }