Line data Source code
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 145 : 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)
39 : {
40 145 : extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
41 145 : if (rsa_id_digest)
42 145 : memcpy(info->identity_digest, rsa_id_digest, DIGEST_LEN);
43 145 : if (ed_id && !ed25519_public_key_is_zero(ed_id))
44 0 : memcpy(&info->ed_identity, ed_id, sizeof(ed25519_public_key_t));
45 145 : if (nickname)
46 53 : strlcpy(info->nickname, nickname, sizeof(info->nickname));
47 145 : if (onion_key)
48 0 : info->onion_key = crypto_pk_dup_key(onion_key);
49 145 : if (ntor_key)
50 102 : memcpy(&info->curve25519_onion_key, ntor_key,
51 : sizeof(curve25519_public_key_t));
52 435 : for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
53 290 : tor_addr_make_unspec(&info->orports[i].addr);
54 : }
55 :
56 145 : if (addr) {
57 145 : extend_info_add_orport(info, addr, port);
58 : }
59 145 : return info;
60 : }
61 :
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 145 : extend_info_add_orport(extend_info_t *ei,
68 : const tor_addr_t *addr,
69 : uint16_t port)
70 : {
71 145 : for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
72 145 : if (tor_addr_is_unspec(&ei->orports[i].addr)) {
73 145 : tor_addr_copy(&ei->orports[i].addr, addr);
74 145 : ei->orports[i].port = port;
75 145 : return 0;
76 : }
77 : }
78 : return -1;
79 : }
80 :
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 21 : extend_info_from_node(const node_t *node, int for_direct_connect)
93 : {
94 21 : crypto_pk_t *rsa_pubkey = NULL;
95 21 : extend_info_t *info = NULL;
96 21 : tor_addr_port_t ap;
97 21 : int valid_addr = 0;
98 :
99 21 : if (!node_has_preferred_descriptor(node, for_direct_connect)) {
100 : return NULL;
101 : }
102 :
103 : /* Choose a preferred address first, but fall back to an allowed address. */
104 21 : if (for_direct_connect)
105 6 : reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0, &ap);
106 : else {
107 15 : node_get_prim_orport(node, &ap);
108 : }
109 21 : valid_addr = tor_addr_port_is_valid_ap(&ap, 0);
110 :
111 21 : if (valid_addr)
112 21 : 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 0 : log_warn(LD_CIRC, "Could not choose valid address for %s",
117 : node->ri ? node->ri->nickname : node->rs->nickname);
118 :
119 : /* Every node we connect or extend to must support ntor */
120 21 : if (!node_has_curve25519_onion_key(node)) {
121 0 : 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 0 : return NULL;
125 : }
126 :
127 21 : const ed25519_public_key_t *ed_pubkey = NULL;
128 :
129 : /* Don't send the ed25519 pubkey unless the target node actually supports
130 : * authenticating with it. */
131 21 : if (node_supports_ed25519_link_authentication(node, 0)) {
132 0 : log_info(LD_CIRC, "Including Ed25519 ID for %s", node_describe(node));
133 0 : ed_pubkey = node_get_ed25519_id(node);
134 21 : } else if (node_get_ed25519_id(node)) {
135 0 : 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));
138 : }
139 :
140 : /* Retrieve the curve25519 pubkey. */
141 21 : const curve25519_public_key_t *curve_pubkey =
142 21 : node_get_curve25519_onion_key(node);
143 21 : rsa_pubkey = node_get_rsa_onion_key(node);
144 :
145 21 : if (valid_addr && node->ri) {
146 0 : info = extend_info_new(node->ri->nickname,
147 0 : node->identity,
148 : ed_pubkey,
149 : rsa_pubkey,
150 : curve_pubkey,
151 : &ap.addr,
152 0 : ap.port);
153 21 : } else if (valid_addr && node->rs && node->md) {
154 21 : info = extend_info_new(node->rs->nickname,
155 21 : node->identity,
156 : ed_pubkey,
157 : rsa_pubkey,
158 : curve_pubkey,
159 : &ap.addr,
160 21 : ap.port);
161 : }
162 :
163 21 : crypto_pk_free(rsa_pubkey);
164 21 : return info;
165 : }
166 :
167 : /** Release storage held by an extend_info_t struct. */
168 : void
169 363 : extend_info_free_(extend_info_t *info)
170 : {
171 363 : if (!info)
172 : return;
173 166 : crypto_pk_free(info->onion_key);
174 166 : tor_free(info);
175 : }
176 :
177 : /** Allocate and return a new extend_info_t with the same contents as
178 : * <b>info</b>. */
179 : extend_info_t *
180 62 : extend_info_dup(extend_info_t *info)
181 : {
182 62 : extend_info_t *newinfo;
183 62 : tor_assert(info);
184 62 : newinfo = tor_malloc(sizeof(extend_info_t));
185 62 : memcpy(newinfo, info, sizeof(extend_info_t));
186 62 : if (info->onion_key)
187 0 : newinfo->onion_key = crypto_pk_dup_key(info->onion_key);
188 : else
189 62 : newinfo->onion_key = NULL;
190 62 : return newinfo;
191 : }
192 :
193 : /* Does ei have a valid TAP key? */
194 : int
195 0 : extend_info_supports_tap(const extend_info_t* ei)
196 : {
197 0 : tor_assert(ei);
198 : /* Valid TAP keys are not NULL */
199 0 : return ei->onion_key != NULL;
200 : }
201 :
202 : /* Does ei have a valid ntor key? */
203 : int
204 8 : extend_info_supports_ntor(const extend_info_t* ei)
205 : {
206 8 : tor_assert(ei);
207 : /* Valid ntor keys have at least one non-zero byte */
208 8 : return !fast_mem_is_zero(
209 8 : (const char*)ei->curve25519_onion_key.public_key,
210 : CURVE25519_PUBKEY_LEN);
211 : }
212 :
213 : /* Does ei have an onion key which it would prefer to use?
214 : * Currently, we prefer ntor keys*/
215 : int
216 0 : extend_info_has_preferred_onion_key(const extend_info_t* ei)
217 : {
218 0 : tor_assert(ei);
219 0 : return extend_info_supports_ntor(ei);
220 : }
221 :
222 : /** Return true iff the given address can be used to extend to. */
223 : int
224 81 : extend_info_addr_is_allowed(const tor_addr_t *addr)
225 : {
226 81 : tor_assert(addr);
227 :
228 : /* Check if we have a private address and if we can extend to it. */
229 81 : if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) &&
230 0 : !get_options()->ExtendAllowPrivateAddresses) {
231 0 : goto disallow;
232 : }
233 : /* Allowed! */
234 : return 1;
235 0 : disallow:
236 0 : return 0;
237 : }
238 :
239 : /**
240 : * Return true if @a addr : @a port is a listed ORPort in @a ei.
241 : **/
242 : bool
243 0 : extend_info_has_orport(const extend_info_t *ei,
244 : const tor_addr_t *addr, uint16_t port)
245 : {
246 0 : IF_BUG_ONCE(ei == NULL) {
247 : return false;
248 : }
249 :
250 0 : for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
251 0 : const tor_addr_port_t *ei_ap = &ei->orports[i];
252 0 : if (tor_addr_eq(&ei_ap->addr, addr) && ei_ap->port == port)
253 : return true;
254 : }
255 : return false;
256 : }
257 :
258 : /**
259 : * If the extend_info @a ei has an orport of the chosen family, then return
260 : * that orport. Otherwise, return NULL.
261 : **/
262 : const tor_addr_port_t *
263 58 : extend_info_get_orport(const extend_info_t *ei, int family)
264 : {
265 120 : for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
266 89 : if (tor_addr_is_unspec(&ei->orports[i].addr))
267 35 : continue;
268 54 : if (tor_addr_family(&ei->orports[i].addr) == family)
269 27 : return &ei->orports[i];
270 : }
271 : return NULL;
272 : }
273 :
274 : /**
275 : * Chose an addr_port_t within @a ei to connect to.
276 : **/
277 : const tor_addr_port_t *
278 0 : extend_info_pick_orport(const extend_info_t *ei)
279 : {
280 0 : IF_BUG_ONCE(!ei) {
281 : return NULL;
282 : }
283 0 : const or_options_t *options = get_options();
284 0 : if (!server_mode(options)) {
285 : // If we aren't a server, just pick the first address we built into
286 : // this extendinfo.
287 0 : return &ei->orports[0];
288 : }
289 :
290 0 : const bool ipv6_ok = router_can_extend_over_ipv6(options);
291 :
292 : // Use 'usable' to collect the usable orports, then pick one.
293 0 : const tor_addr_port_t *usable[EXTEND_INFO_MAX_ADDRS];
294 0 : int n_usable = 0;
295 0 : for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
296 0 : const tor_addr_port_t *a = &ei->orports[i];
297 0 : const int family = tor_addr_family(&a->addr);
298 0 : if (family == AF_INET || (ipv6_ok && family == AF_INET6)) {
299 0 : usable[n_usable++] = a;
300 : }
301 : }
302 :
303 0 : if (n_usable == 0) {
304 : // Need to bail out early, since nothing will work.
305 : return NULL;
306 : }
307 :
308 0 : crypto_fast_rng_t *rng = get_thread_fast_rng();
309 0 : const int idx = crypto_fast_rng_get_uint(rng, n_usable);
310 :
311 0 : return usable[idx];
312 : }
313 :
314 : /**
315 : * Return true if any orport address in @a ei is an internal address.
316 : **/
317 : bool
318 0 : extend_info_any_orport_addr_is_internal(const extend_info_t *ei)
319 : {
320 0 : IF_BUG_ONCE(ei == NULL) {
321 : return false;
322 : }
323 :
324 0 : for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
325 0 : if (! tor_addr_is_unspec(&ei->orports[i].addr) &&
326 0 : tor_addr_is_internal(&ei->orports[i].addr, 0))
327 : return true;
328 : }
329 : return false;
330 : }
|