Merge branch 'maint-0.4.5' into maint-0.4.6
[tor.git] / src / core / or / extendinfo.c
blob6bcef181be63555774a92c9bd86568a5701a893b
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 */
7 /**
8 * @file extendinfo.c
9 * @brief Functions for creating and using extend_info_t objects.
11 * An extend_info_t is the information we hold about a relay in order to
12 * extend a circuit to it.
13 **/
15 #include "core/or/or.h"
16 #include "core/or/extendinfo.h"
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"
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"
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 crypto_pk_t *onion_key,
37 const curve25519_public_key_t *ntor_key,
38 const tor_addr_t *addr, uint16_t port)
40 extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
41 if (rsa_id_digest)
42 memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN);
43 if (ed_id && !ed25519_public_key_is_zero(ed_id))
44 memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t));
45 if (nickname)
46 strlcpy(info->nickname, nickname, sizeof(info->nickname));
47 if (onion_key)
48 info->onion_key = crypto_pk_dup_key(onion_key);
49 if (ntor_key)
50 memcpy(&info->curve25519_onion_key, ntor_key,
51 sizeof(curve25519_public_key_t));
52 for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
53 tor_addr_make_unspec(&info->orports[i].addr);
56 if (addr) {
57 extend_info_add_orport(info, addr, port);
59 return info;
62 /**
63 * Add another address:port pair to a given extend_info_t, if there is
64 * room. Return 0 on success, -1 on failure.
65 **/
66 int
67 extend_info_add_orport(extend_info_t *ei,
68 const tor_addr_t *addr,
69 uint16_t port)
71 for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
72 if (tor_addr_is_unspec(&ei->orports[i].addr)) {
73 tor_addr_copy(&ei->orports[i].addr, addr);
74 ei->orports[i].port = port;
75 return 0;
78 return -1;
81 /** Allocate and return a new extend_info that can be used to build a
82 * circuit to or through the node <b>node</b>. Use the primary address
83 * of the node (i.e. its IPv4 address) unless
84 * <b>for_direct_connect</b> is true, in which case the preferred
85 * address is used instead. May return NULL if there is not enough
86 * info about <b>node</b> to extend to it--for example, if the preferred
87 * routerinfo_t or microdesc_t is missing, or if for_direct_connect is
88 * true and none of the node's addresses is allowed by tor's firewall
89 * and IP version config.
90 **/
91 extend_info_t *
92 extend_info_from_node(const node_t *node, int for_direct_connect)
94 crypto_pk_t *rsa_pubkey = NULL;
95 extend_info_t *info = NULL;
96 tor_addr_port_t ap;
97 int valid_addr = 0;
99 if (!node_has_preferred_descriptor(node, for_direct_connect)) {
100 return NULL;
103 /* Choose a preferred address first, but fall back to an allowed address. */
104 if (for_direct_connect)
105 reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0, &ap);
106 else {
107 node_get_prim_orport(node, &ap);
109 valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
111 if (valid_addr)
112 log_debug(LD_CIRC, "using %s for %s",
113 fmt_addrport(&ap.addr, ap.port),
114 node->ri ? node->ri->nickname : node->rs->nickname);
115 else
116 log_warn(LD_CIRC, "Could not choose valid address for %s",
117 node->ri ? node->ri->nickname : node->rs->nickname);
119 /* Every node we connect or extend to must support ntor */
120 if (!node_has_curve25519_onion_key(node)) {
121 log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
122 "Attempted to create extend_info for a node that does not support "
123 "ntor: %s", node_describe(node));
124 return NULL;
127 const ed25519_public_key_t *ed_pubkey = NULL;
129 /* Don't send the ed25519 pubkey unless the target node actually supports
130 * authenticating with it. */
131 if (node_supports_ed25519_link_authentication(node, 0)) {
132 log_info(LD_CIRC, "Including Ed25519 ID for %s", node_describe(node));
133 ed_pubkey = node_get_ed25519_id(node);
134 } else if (node_get_ed25519_id(node)) {
135 log_info(LD_CIRC, "Not including the ed25519 ID for %s, since it won't "
136 "be able to authenticate it.",
137 node_describe(node));
140 /* Retrieve the curve25519 pubkey. */
141 const curve25519_public_key_t *curve_pubkey =
142 node_get_curve25519_onion_key(node);
143 rsa_pubkey = node_get_rsa_onion_key(node);
145 if (valid_addr && node->ri) {
146 info = extend_info_new(node->ri->nickname,
147 node->identity,
148 ed_pubkey,
149 rsa_pubkey,
150 curve_pubkey,
151 &ap.addr,
152 ap.port);
153 } else if (valid_addr && node->rs && node->md) {
154 info = extend_info_new(node->rs->nickname,
155 node->identity,
156 ed_pubkey,
157 rsa_pubkey,
158 curve_pubkey,
159 &ap.addr,
160 ap.port);
163 crypto_pk_free(rsa_pubkey);
164 return info;
167 /** Release storage held by an extend_info_t struct. */
168 void
169 extend_info_free_(extend_info_t *info)
171 if (!info)
172 return;
173 crypto_pk_free(info->onion_key);
174 tor_free(info);
177 /** Allocate and return a new extend_info_t with the same contents as
178 * <b>info</b>. */
179 extend_info_t *
180 extend_info_dup(extend_info_t *info)
182 extend_info_t *newinfo;
183 tor_assert(info);
184 newinfo = tor_malloc(sizeof(extend_info_t));
185 memcpy(newinfo, info, sizeof(extend_info_t));
186 if (info->onion_key)
187 newinfo->onion_key = crypto_pk_dup_key(info->onion_key);
188 else
189 newinfo->onion_key = NULL;
190 return newinfo;
193 /* Does ei have a valid TAP key? */
195 extend_info_supports_tap(const extend_info_t* ei)
197 tor_assert(ei);
198 /* Valid TAP keys are not NULL */
199 return ei->onion_key != NULL;
202 /* Does ei have a valid ntor key? */
204 extend_info_supports_ntor(const extend_info_t* ei)
206 tor_assert(ei);
207 /* Valid ntor keys have at least one non-zero byte */
208 return !fast_mem_is_zero(
209 (const char*)ei->curve25519_onion_key.public_key,
210 CURVE25519_PUBKEY_LEN);
213 /* Does ei have an onion key which it would prefer to use?
214 * Currently, we prefer ntor keys*/
216 extend_info_has_preferred_onion_key(const extend_info_t* ei)
218 tor_assert(ei);
219 return extend_info_supports_ntor(ei);
222 /** Return true iff the given address can be used to extend to. */
224 extend_info_addr_is_allowed(const tor_addr_t *addr)
226 tor_assert(addr);
228 /* Check if we have a private address and if we can extend to it. */
229 if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) &&
230 !get_options()->ExtendAllowPrivateAddresses) {
231 goto disallow;
233 /* Allowed! */
234 return 1;
235 disallow:
236 return 0;
240 * Return true if @a addr : @a port is a listed ORPort in @a ei.
242 bool
243 extend_info_has_orport(const extend_info_t *ei,
244 const tor_addr_t *addr, uint16_t port)
246 IF_BUG_ONCE(ei == NULL) {
247 return false;
250 for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
251 const tor_addr_port_t *ei_ap = &ei->orports[i];
252 if (tor_addr_eq(&ei_ap->addr, addr) && ei_ap->port == port)
253 return true;
255 return false;
259 * If the extend_info @a ei has an orport of the chosen family, then return
260 * that orport. Otherwise, return NULL.
262 const tor_addr_port_t *
263 extend_info_get_orport(const extend_info_t *ei, int family)
265 for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
266 if (tor_addr_is_unspec(&ei->orports[i].addr))
267 continue;
268 if (tor_addr_family(&ei->orports[i].addr) == family)
269 return &ei->orports[i];
271 return NULL;
275 * Chose an addr_port_t within @a ei to connect to.
277 const tor_addr_port_t *
278 extend_info_pick_orport(const extend_info_t *ei)
280 IF_BUG_ONCE(!ei) {
281 return NULL;
283 const or_options_t *options = get_options();
284 if (!server_mode(options)) {
285 // If we aren't a server, just pick the first address we built into
286 // this extendinfo.
287 return &ei->orports[0];
290 const bool ipv6_ok = router_can_extend_over_ipv6(options);
292 // Use 'usable' to collect the usable orports, then pick one.
293 const tor_addr_port_t *usable[EXTEND_INFO_MAX_ADDRS];
294 int n_usable = 0;
295 for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
296 const tor_addr_port_t *a = &ei->orports[i];
297 const int family = tor_addr_family(&a->addr);
298 if (family == AF_INET || (ipv6_ok && family == AF_INET6)) {
299 usable[n_usable++] = a;
303 if (n_usable == 0) {
304 // Need to bail out early, since nothing will work.
305 return NULL;
308 crypto_fast_rng_t *rng = get_thread_fast_rng();
309 const int idx = crypto_fast_rng_get_uint(rng, n_usable);
311 return usable[idx];
315 * Return true if any orport address in @a ei is an internal address.
317 bool
318 extend_info_any_orport_addr_is_internal(const extend_info_t *ei)
320 IF_BUG_ONCE(ei == NULL) {
321 return false;
324 for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
325 if (! tor_addr_is_unspec(&ei->orports[i].addr) &&
326 tor_addr_is_internal(&ei->orports[i].addr, 0))
327 return true;
329 return false;