Line data Source code
1 : /* Copyright (c) 2016-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : /**
5 : * \file hs_client.c
6 : * \brief Implement next generation hidden service client functionality
7 : **/
8 :
9 : #define HS_CLIENT_PRIVATE
10 :
11 : #include "core/or/or.h"
12 : #include "app/config/config.h"
13 : #include "core/crypto/hs_ntor.h"
14 : #include "core/mainloop/connection.h"
15 : #include "core/or/circuitbuild.h"
16 : #include "core/or/circuitlist.h"
17 : #include "core/or/circuituse.h"
18 : #include "core/or/connection_edge.h"
19 : #include "core/or/extendinfo.h"
20 : #include "core/or/reasons.h"
21 : #include "feature/client/circpathbias.h"
22 : #include "feature/dirclient/dirclient.h"
23 : #include "feature/dircommon/directory.h"
24 : #include "feature/hs/hs_cache.h"
25 : #include "feature/hs/hs_cell.h"
26 : #include "feature/hs/hs_circuit.h"
27 : #include "feature/hs/hs_circuitmap.h"
28 : #include "feature/hs/hs_client.h"
29 : #include "feature/hs/hs_control.h"
30 : #include "feature/hs/hs_descriptor.h"
31 : #include "feature/hs/hs_ident.h"
32 : #include "feature/nodelist/describe.h"
33 : #include "feature/nodelist/microdesc.h"
34 : #include "feature/nodelist/networkstatus.h"
35 : #include "feature/nodelist/nodelist.h"
36 : #include "feature/nodelist/routerset.h"
37 : #include "lib/crypt_ops/crypto_format.h"
38 : #include "lib/crypt_ops/crypto_rand.h"
39 : #include "lib/crypt_ops/crypto_util.h"
40 :
41 : #include "core/or/cpath_build_state_st.h"
42 : #include "feature/dircommon/dir_connection_st.h"
43 : #include "core/or/entry_connection_st.h"
44 : #include "core/or/extend_info_st.h"
45 : #include "core/or/origin_circuit_st.h"
46 : #include "core/or/socks_request_st.h"
47 :
48 : /** Client-side authorizations for hidden services; map of service identity
49 : * public key to hs_client_service_authorization_t *. */
50 : static digest256map_t *client_auths = NULL;
51 :
52 : #include "trunnel/hs/cell_introduce1.h"
53 :
54 : /** Return a human-readable string for the client fetch status code. */
55 : static const char *
56 1 : fetch_status_to_string(hs_client_fetch_status_t status)
57 : {
58 1 : switch (status) {
59 : case HS_CLIENT_FETCH_ERROR:
60 : return "Internal error";
61 0 : case HS_CLIENT_FETCH_LAUNCHED:
62 0 : return "Descriptor fetch launched";
63 0 : case HS_CLIENT_FETCH_HAVE_DESC:
64 0 : return "Already have descriptor";
65 0 : case HS_CLIENT_FETCH_NO_HSDIRS:
66 0 : return "No more HSDir available to query";
67 0 : case HS_CLIENT_FETCH_NOT_ALLOWED:
68 0 : return "Fetching descriptors is not allowed";
69 0 : case HS_CLIENT_FETCH_MISSING_INFO:
70 0 : return "Missing directory information";
71 0 : case HS_CLIENT_FETCH_PENDING:
72 0 : return "Pending descriptor fetch";
73 0 : default:
74 0 : return "(Unknown client fetch status code)";
75 : }
76 : }
77 :
78 : /** Return true iff tor should close the SOCKS request(s) for the descriptor
79 : * fetch that ended up with this given status code. */
80 : static int
81 1 : fetch_status_should_close_socks(hs_client_fetch_status_t status)
82 : {
83 1 : switch (status) {
84 1 : case HS_CLIENT_FETCH_NO_HSDIRS:
85 : /* No more HSDir to query, we can't complete the SOCKS request(s). */
86 : case HS_CLIENT_FETCH_ERROR:
87 : /* The fetch triggered an internal error. */
88 : case HS_CLIENT_FETCH_NOT_ALLOWED:
89 : /* Client is not allowed to fetch (FetchHidServDescriptors 0). */
90 1 : goto close;
91 0 : case HS_CLIENT_FETCH_MISSING_INFO:
92 : case HS_CLIENT_FETCH_HAVE_DESC:
93 : case HS_CLIENT_FETCH_PENDING:
94 : case HS_CLIENT_FETCH_LAUNCHED:
95 : /* The rest doesn't require tor to close the SOCKS request(s). */
96 0 : goto no_close;
97 : }
98 :
99 1 : no_close:
100 : return 0;
101 1 : close:
102 1 : return 1;
103 : }
104 :
105 : /* Return a newly allocated list of all the entry connections that matches the
106 : * given service identity pk. If service_identity_pk is NULL, all entry
107 : * connections with an hs_ident are returned.
108 : *
109 : * Caller must free the returned list but does NOT have ownership of the
110 : * object inside thus they have to remain untouched. */
111 : static smartlist_t *
112 45182 : find_entry_conns(const ed25519_public_key_t *service_identity_pk)
113 : {
114 45182 : time_t now = time(NULL);
115 45182 : smartlist_t *conns = NULL, *entry_conns = NULL;
116 :
117 45182 : entry_conns = smartlist_new();
118 :
119 45182 : conns = connection_list_by_type_state(CONN_TYPE_AP,
120 : AP_CONN_STATE_RENDDESC_WAIT);
121 45189 : SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
122 7 : entry_connection_t *entry_conn = TO_ENTRY_CONN(base_conn);
123 7 : const edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
124 :
125 : /* Only consider the entry connections that matches the service for which
126 : * we just fetched its descriptor. */
127 7 : if (!edge_conn->hs_ident ||
128 7 : (service_identity_pk &&
129 7 : !ed25519_pubkey_eq(service_identity_pk,
130 7 : &edge_conn->hs_ident->identity_pk))) {
131 0 : continue;
132 : }
133 7 : assert_connection_ok(base_conn, now);
134 :
135 : /* Validated! Add the entry connection to the list. */
136 7 : smartlist_add(entry_conns, entry_conn);
137 7 : } SMARTLIST_FOREACH_END(base_conn);
138 :
139 : /* We don't have ownership of the objects in this list. */
140 45182 : smartlist_free(conns);
141 45182 : return entry_conns;
142 : }
143 :
144 : /* Cancel all descriptor fetches currently in progress. */
145 : static void
146 0 : cancel_descriptor_fetches(void)
147 : {
148 0 : smartlist_t *conns =
149 0 : connection_list_by_type_purpose(CONN_TYPE_DIR, DIR_PURPOSE_FETCH_HSDESC);
150 0 : SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
151 0 : const hs_ident_dir_conn_t *ident = TO_DIR_CONN(conn)->hs_ident;
152 0 : if (BUG(ident == NULL)) {
153 : /* A directory connection fetching a service descriptor can't have an
154 : * empty hidden service identifier. */
155 0 : continue;
156 : }
157 0 : log_debug(LD_REND, "Marking for close a directory connection fetching "
158 : "a hidden service descriptor for service %s.",
159 : safe_str_client(ed25519_fmt(&ident->identity_pk)));
160 0 : connection_mark_for_close(conn);
161 0 : } SMARTLIST_FOREACH_END(conn);
162 :
163 : /* No ownership of the objects in this list. */
164 0 : smartlist_free(conns);
165 0 : log_info(LD_REND, "Hidden service client descriptor fetches cancelled.");
166 0 : }
167 :
168 : /** Get all connections that are waiting on a circuit and flag them back to
169 : * waiting for a hidden service descriptor for the given service key
170 : * service_identity_pk. */
171 : static void
172 0 : flag_all_conn_wait_desc(const ed25519_public_key_t *service_identity_pk)
173 : {
174 0 : tor_assert(service_identity_pk);
175 :
176 0 : smartlist_t *conns =
177 0 : connection_list_by_type_state(CONN_TYPE_AP, AP_CONN_STATE_CIRCUIT_WAIT);
178 :
179 0 : SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
180 0 : edge_connection_t *edge_conn;
181 0 : if (BUG(!CONN_IS_EDGE(conn))) {
182 0 : continue;
183 : }
184 0 : edge_conn = TO_EDGE_CONN(conn);
185 0 : if (edge_conn->hs_ident &&
186 0 : ed25519_pubkey_eq(&edge_conn->hs_ident->identity_pk,
187 : service_identity_pk)) {
188 0 : connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
189 : }
190 0 : } SMARTLIST_FOREACH_END(conn);
191 :
192 0 : smartlist_free(conns);
193 0 : }
194 :
195 : /** Remove tracked HSDir requests from our history for this hidden service
196 : * identity public key. */
197 : static void
198 6 : purge_hid_serv_request(const ed25519_public_key_t *identity_pk)
199 : {
200 6 : char base64_blinded_pk[ED25519_BASE64_LEN + 1];
201 6 : ed25519_public_key_t blinded_pk;
202 :
203 6 : tor_assert(identity_pk);
204 :
205 : /* Get blinded pubkey of hidden service. It is possible that we just moved
206 : * to a new time period meaning that we won't be able to purge the request
207 : * from the previous time period. That is fine because they will expire at
208 : * some point and we don't care about those anymore. */
209 6 : hs_build_blinded_pubkey(identity_pk, NULL, 0,
210 : hs_get_time_period_num(0), &blinded_pk);
211 6 : ed25519_public_to_base64(base64_blinded_pk, &blinded_pk);
212 : /* Purge last hidden service request from cache for this blinded key. */
213 6 : hs_purge_hid_serv_from_last_hid_serv_requests(base64_blinded_pk);
214 6 : }
215 :
216 : /** Return true iff there is at least one pending directory descriptor request
217 : * for the service identity_pk. */
218 : static int
219 2 : directory_request_is_pending(const ed25519_public_key_t *identity_pk)
220 : {
221 2 : int ret = 0;
222 4 : smartlist_t *conns =
223 2 : connection_list_by_type_purpose(CONN_TYPE_DIR, DIR_PURPOSE_FETCH_HSDESC);
224 :
225 2 : SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
226 1 : const hs_ident_dir_conn_t *ident = TO_DIR_CONN(conn)->hs_ident;
227 1 : if (BUG(ident == NULL)) {
228 : /* A directory connection fetching a service descriptor can't have an
229 : * empty hidden service identifier. */
230 0 : continue;
231 : }
232 1 : if (!ed25519_pubkey_eq(identity_pk, &ident->identity_pk)) {
233 0 : continue;
234 : }
235 : ret = 1;
236 : break;
237 0 : } SMARTLIST_FOREACH_END(conn);
238 :
239 : /* No ownership of the objects in this list. */
240 2 : smartlist_free(conns);
241 2 : return ret;
242 : }
243 :
244 : /** Helper function that changes the state of an entry connection to waiting
245 : * for a circuit. For this to work properly, the connection timestamps are set
246 : * to now and the connection is then marked as pending for a circuit. */
247 : static void
248 0 : mark_conn_as_waiting_for_circuit(connection_t *conn, time_t now)
249 : {
250 0 : tor_assert(conn);
251 :
252 : /* Because the connection can now proceed to opening circuit and ultimately
253 : * connect to the service, reset those timestamp so the connection is
254 : * considered "fresh" and can continue without being closed too early. */
255 0 : conn->timestamp_created = now;
256 0 : conn->timestamp_last_read_allowed = now;
257 0 : conn->timestamp_last_write_allowed = now;
258 : /* Change connection's state into waiting for a circuit. */
259 0 : conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
260 :
261 0 : connection_ap_mark_as_pending_circuit(TO_ENTRY_CONN(conn));
262 0 : }
263 :
264 : /** We failed to fetch a descriptor for the service with <b>identity_pk</b>
265 : * because of <b>status</b>. Find all pending SOCKS connections for this
266 : * service that are waiting on the descriptor and close them with
267 : * <b>reason</b>. */
268 : static void
269 1 : close_all_socks_conns_waiting_for_desc(const ed25519_public_key_t *identity_pk,
270 : hs_client_fetch_status_t status,
271 : int reason)
272 : {
273 1 : unsigned int count = 0;
274 1 : smartlist_t *entry_conns = find_entry_conns(identity_pk);
275 :
276 2 : SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
277 : /* Unattach the entry connection which will close for the reason. */
278 1 : connection_mark_unattached_ap(entry_conn, reason);
279 1 : count++;
280 1 : } SMARTLIST_FOREACH_END(entry_conn);
281 :
282 1 : if (count > 0) {
283 1 : char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1];
284 1 : hs_build_address(identity_pk, HS_VERSION_THREE, onion_address);
285 1 : log_notice(LD_REND, "Closed %u streams for service %s.onion "
286 : "for reason %s. Fetch status: %s.",
287 : count, safe_str_client(onion_address),
288 : stream_end_reason_to_string(reason),
289 : fetch_status_to_string(status));
290 : }
291 :
292 : /* No ownership of the object(s) in this list. */
293 1 : smartlist_free(entry_conns);
294 1 : }
295 :
296 : /** Find all pending SOCKS connection waiting for a descriptor and retry them
297 : * all. This is called when the directory information changed. */
298 : STATIC void
299 45175 : retry_all_socks_conn_waiting_for_desc(void)
300 : {
301 45175 : smartlist_t *entry_conns = find_entry_conns(NULL);
302 :
303 45175 : SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
304 0 : hs_client_fetch_status_t status;
305 0 : edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
306 0 : connection_t *base_conn = &edge_conn->base_;
307 :
308 : /* Ignore non HS or non v3 connection. */
309 0 : if (edge_conn->hs_ident == NULL) {
310 0 : continue;
311 : }
312 :
313 : /* In this loop, we will possibly try to fetch a descriptor for the
314 : * pending connections because we just got more directory information.
315 : * However, the refetch process can cleanup all SOCKS request to the same
316 : * service if an internal error happens. Thus, we can end up with closed
317 : * connections in our list. */
318 0 : if (base_conn->marked_for_close) {
319 0 : continue;
320 : }
321 :
322 : /* XXX: There is an optimization we could do which is that for a service
323 : * key, we could check if we can fetch and remember that decision. */
324 :
325 : /* Order a refetch in case it works this time. */
326 0 : status = hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
327 0 : if (status == HS_CLIENT_FETCH_HAVE_DESC) {
328 : /* This is a rare case where a SOCKS connection is in state waiting for
329 : * a descriptor but we do have it in the cache.
330 : *
331 : * This can happen is tor comes back from suspend where it previously
332 : * had the descriptor but the intro points were not usable. Once it
333 : * came back to life, the intro point failure cache was cleaned up and
334 : * thus the descriptor became usable again leaving us in this code path.
335 : *
336 : * We'll mark the connection as waiting for a circuit so the descriptor
337 : * can be retried. This is safe because a connection in state waiting
338 : * for a descriptor can not be in the entry connection pending list. */
339 0 : mark_conn_as_waiting_for_circuit(base_conn, approx_time());
340 0 : continue;
341 : }
342 : /* In the case of an error, either all SOCKS connections have been
343 : * closed or we are still missing directory information. Leave the
344 : * connection in renddesc wait state so when we get more info, we'll be
345 : * able to try it again. */
346 0 : } SMARTLIST_FOREACH_END(entry_conn);
347 :
348 : /* We don't have ownership of those objects. */
349 45175 : smartlist_free(entry_conns);
350 45175 : }
351 :
352 : /** A v3 HS circuit successfully connected to the hidden service. Update the
353 : * stream state at <b>hs_conn_ident</b> appropriately. */
354 : static void
355 5 : note_connection_attempt_succeeded(const hs_ident_edge_conn_t *hs_conn_ident)
356 : {
357 5 : tor_assert(hs_conn_ident);
358 :
359 : /* Remove from the hid serv cache all requests for that service so we can
360 : * query the HSDir again later on for various reasons. */
361 5 : purge_hid_serv_request(&hs_conn_ident->identity_pk);
362 5 : }
363 :
364 : /** Given the pubkey of a hidden service in <b>onion_identity_pk</b>, fetch its
365 : * descriptor by launching a dir connection to <b>hsdir</b>. Return a
366 : * hs_client_fetch_status_t status code depending on how it went. */
367 : static hs_client_fetch_status_t
368 0 : directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
369 : const routerstatus_t *hsdir)
370 : {
371 0 : uint64_t current_time_period = hs_get_time_period_num(0);
372 0 : ed25519_public_key_t blinded_pubkey;
373 0 : char base64_blinded_pubkey[ED25519_BASE64_LEN + 1];
374 0 : hs_ident_dir_conn_t hs_conn_dir_ident;
375 :
376 0 : tor_assert(hsdir);
377 0 : tor_assert(onion_identity_pk);
378 :
379 : /* Get blinded pubkey */
380 0 : hs_build_blinded_pubkey(onion_identity_pk, NULL, 0,
381 : current_time_period, &blinded_pubkey);
382 : /* ...and base64 it. */
383 0 : ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
384 :
385 : /* Copy onion pk to a dir_ident so that we attach it to the dir conn */
386 0 : hs_ident_dir_conn_init(onion_identity_pk, &blinded_pubkey,
387 : &hs_conn_dir_ident);
388 :
389 : /* Setup directory request */
390 0 : directory_request_t *req =
391 0 : directory_request_new(DIR_PURPOSE_FETCH_HSDESC);
392 0 : directory_request_set_routerstatus(req, hsdir);
393 0 : directory_request_set_indirection(req, DIRIND_ANONYMOUS);
394 0 : directory_request_set_resource(req, base64_blinded_pubkey);
395 0 : directory_request_fetch_set_hs_ident(req, &hs_conn_dir_ident);
396 0 : directory_initiate_request(req);
397 0 : directory_request_free(req);
398 :
399 0 : log_info(LD_REND, "Descriptor fetch request for service %s with blinded "
400 : "key %s to directory %s",
401 : safe_str_client(ed25519_fmt(onion_identity_pk)),
402 : safe_str_client(base64_blinded_pubkey),
403 : safe_str_client(routerstatus_describe(hsdir)));
404 :
405 : /* Fire a REQUESTED event on the control port. */
406 0 : hs_control_desc_event_requested(onion_identity_pk, base64_blinded_pubkey,
407 : hsdir);
408 :
409 : /* Cleanup memory. */
410 0 : memwipe(&blinded_pubkey, 0, sizeof(blinded_pubkey));
411 0 : memwipe(base64_blinded_pubkey, 0, sizeof(base64_blinded_pubkey));
412 0 : memwipe(&hs_conn_dir_ident, 0, sizeof(hs_conn_dir_ident));
413 :
414 0 : return HS_CLIENT_FETCH_LAUNCHED;
415 : }
416 :
417 : /** Return the HSDir we should use to fetch the descriptor of the hidden
418 : * service with identity key <b>onion_identity_pk</b>. */
419 : STATIC routerstatus_t *
420 42 : pick_hsdir_v3(const ed25519_public_key_t *onion_identity_pk)
421 : {
422 42 : char base64_blinded_pubkey[ED25519_BASE64_LEN + 1];
423 42 : uint64_t current_time_period = hs_get_time_period_num(0);
424 42 : smartlist_t *responsible_hsdirs = NULL;
425 42 : ed25519_public_key_t blinded_pubkey;
426 42 : routerstatus_t *hsdir_rs = NULL;
427 :
428 42 : tor_assert(onion_identity_pk);
429 :
430 : /* Get blinded pubkey of hidden service */
431 42 : hs_build_blinded_pubkey(onion_identity_pk, NULL, 0,
432 : current_time_period, &blinded_pubkey);
433 : /* ...and base64 it. */
434 42 : ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
435 :
436 : /* Get responsible hsdirs of service for this time period */
437 42 : responsible_hsdirs = smartlist_new();
438 :
439 42 : hs_get_responsible_hsdirs(&blinded_pubkey, current_time_period,
440 : 0, 1, responsible_hsdirs);
441 :
442 42 : log_debug(LD_REND, "Found %d responsible HSDirs and about to pick one.",
443 : smartlist_len(responsible_hsdirs));
444 :
445 : /* Pick an HSDir from the responsible ones. The ownership of
446 : * responsible_hsdirs is given to this function so no need to free it. */
447 42 : hsdir_rs = hs_pick_hsdir(responsible_hsdirs, base64_blinded_pubkey, NULL);
448 :
449 42 : return hsdir_rs;
450 : }
451 :
452 : /** Fetch a v3 descriptor using the given <b>onion_identity_pk</b>.
453 : *
454 : * On success, HS_CLIENT_FETCH_LAUNCHED is returned. Otherwise, an error from
455 : * hs_client_fetch_status_t is returned. */
456 0 : MOCK_IMPL(STATIC hs_client_fetch_status_t,
457 : fetch_v3_desc, (const ed25519_public_key_t *onion_identity_pk))
458 : {
459 0 : routerstatus_t *hsdir_rs =NULL;
460 :
461 0 : tor_assert(onion_identity_pk);
462 :
463 0 : hsdir_rs = pick_hsdir_v3(onion_identity_pk);
464 0 : if (!hsdir_rs) {
465 0 : log_info(LD_REND, "Couldn't pick a v3 hsdir.");
466 0 : return HS_CLIENT_FETCH_NO_HSDIRS;
467 : }
468 :
469 0 : return directory_launch_v3_desc_fetch(onion_identity_pk, hsdir_rs);
470 : }
471 :
472 : /** With a given <b>onion_identity_pk</b>, fetch its descriptor. If
473 : * <b>hsdirs</b> is specified, use the directory servers specified in the list.
474 : * Else, use a random server. */
475 : void
476 0 : hs_client_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
477 : const smartlist_t *hsdirs)
478 : {
479 0 : tor_assert(onion_identity_pk);
480 :
481 0 : if (hsdirs != NULL) {
482 0 : SMARTLIST_FOREACH_BEGIN(hsdirs, const routerstatus_t *, hsdir) {
483 0 : directory_launch_v3_desc_fetch(onion_identity_pk, hsdir);
484 0 : } SMARTLIST_FOREACH_END(hsdir);
485 : } else {
486 0 : fetch_v3_desc(onion_identity_pk);
487 : }
488 0 : }
489 :
490 : /** Make sure that the given v3 origin circuit circ is a valid correct
491 : * introduction circuit. This will BUG() on any problems and hard assert if
492 : * the anonymity of the circuit is not ok. Return 0 on success else -1 where
493 : * the circuit should be mark for closed immediately. */
494 : static int
495 0 : intro_circ_is_ok(const origin_circuit_t *circ)
496 : {
497 0 : int ret = 0;
498 :
499 0 : tor_assert(circ);
500 :
501 0 : if (BUG(TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_INTRODUCING &&
502 : TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT &&
503 : TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACKED)) {
504 : ret = -1;
505 : }
506 0 : if (BUG(circ->hs_ident == NULL)) {
507 : ret = -1;
508 : }
509 0 : if (BUG(!hs_ident_intro_circ_is_valid(circ->hs_ident))) {
510 : ret = -1;
511 : }
512 :
513 : /* This can stop the tor daemon but we want that since if we don't have
514 : * anonymity on this circuit, something went really wrong. */
515 0 : assert_circ_anonymity_ok(circ, get_options());
516 0 : return ret;
517 : }
518 :
519 : /** Find a descriptor intro point object that matches the given ident in the
520 : * given descriptor desc. Return NULL if not found. */
521 : static const hs_desc_intro_point_t *
522 2 : find_desc_intro_point_by_ident(const hs_ident_circuit_t *ident,
523 : const hs_descriptor_t *desc)
524 : {
525 2 : const hs_desc_intro_point_t *intro_point = NULL;
526 :
527 2 : tor_assert(ident);
528 2 : tor_assert(desc);
529 :
530 2 : SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
531 : const hs_desc_intro_point_t *, ip) {
532 2 : if (ed25519_pubkey_eq(&ident->intro_auth_pk,
533 2 : &ip->auth_key_cert->signed_key)) {
534 : intro_point = ip;
535 : break;
536 : }
537 0 : } SMARTLIST_FOREACH_END(ip);
538 :
539 2 : return intro_point;
540 : }
541 :
542 : /** Find a descriptor intro point object from the descriptor object desc that
543 : * matches the given legacy identity digest in legacy_id. Return NULL if not
544 : * found. */
545 : static hs_desc_intro_point_t *
546 0 : find_desc_intro_point_by_legacy_id(const char *legacy_id,
547 : const hs_descriptor_t *desc)
548 : {
549 0 : hs_desc_intro_point_t *ret_ip = NULL;
550 :
551 0 : tor_assert(legacy_id);
552 0 : tor_assert(desc);
553 :
554 : /* We will go over every intro point and try to find which one is linked to
555 : * that circuit. Those lists are small so it's not that expensive. */
556 0 : SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
557 : hs_desc_intro_point_t *, ip) {
558 0 : SMARTLIST_FOREACH_BEGIN(ip->link_specifiers,
559 : const link_specifier_t *, lspec) {
560 : /* Not all tor node have an ed25519 identity key so we still rely on the
561 : * legacy identity digest. */
562 0 : if (link_specifier_get_ls_type(lspec) != LS_LEGACY_ID) {
563 0 : continue;
564 : }
565 0 : if (fast_memneq(legacy_id,
566 : link_specifier_getconstarray_un_legacy_id(lspec),
567 : DIGEST_LEN)) {
568 : break;
569 : }
570 : /* Found it. */
571 0 : ret_ip = ip;
572 0 : goto end;
573 0 : } SMARTLIST_FOREACH_END(lspec);
574 0 : } SMARTLIST_FOREACH_END(ip);
575 :
576 0 : end:
577 0 : return ret_ip;
578 : }
579 :
580 : /** Send an INTRODUCE1 cell along the intro circuit and populate the rend
581 : * circuit identifier with the needed key material for the e2e encryption.
582 : * Return 0 on success, -1 if there is a transient error such that an action
583 : * has been taken to recover and -2 if there is a permanent error indicating
584 : * that both circuits were closed. */
585 : static int
586 0 : send_introduce1(origin_circuit_t *intro_circ,
587 : origin_circuit_t *rend_circ)
588 : {
589 0 : int status;
590 0 : char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1];
591 0 : const ed25519_public_key_t *service_identity_pk = NULL;
592 0 : const hs_desc_intro_point_t *ip;
593 :
594 0 : tor_assert(rend_circ);
595 0 : if (intro_circ_is_ok(intro_circ) < 0) {
596 0 : goto perm_err;
597 : }
598 :
599 0 : service_identity_pk = &intro_circ->hs_ident->identity_pk;
600 : /* For logging purposes. There will be a time where the hs_ident will have a
601 : * version number but for now there is none because it's all v3. */
602 0 : hs_build_address(service_identity_pk, HS_VERSION_THREE, onion_address);
603 :
604 0 : log_info(LD_REND, "Sending INTRODUCE1 cell to service %s on circuit %u",
605 : safe_str_client(onion_address), TO_CIRCUIT(intro_circ)->n_circ_id);
606 :
607 : /* 1) Get descriptor from our cache. */
608 0 : const hs_descriptor_t *desc =
609 0 : hs_cache_lookup_as_client(service_identity_pk);
610 0 : if (desc == NULL || !hs_client_any_intro_points_usable(service_identity_pk,
611 : desc)) {
612 0 : log_info(LD_REND, "Request to %s %s. Trying to fetch a new descriptor.",
613 : safe_str_client(onion_address),
614 : (desc) ? "didn't have usable intro points" :
615 : "didn't have a descriptor");
616 0 : hs_client_refetch_hsdesc(service_identity_pk);
617 : /* We just triggered a refetch, make sure every connections are back
618 : * waiting for that descriptor. */
619 0 : flag_all_conn_wait_desc(service_identity_pk);
620 : /* We just asked for a refetch so this is a transient error. */
621 0 : goto tran_err;
622 : }
623 :
624 : /* We need to find which intro point in the descriptor we are connected to
625 : * on intro_circ. */
626 0 : ip = find_desc_intro_point_by_ident(intro_circ->hs_ident, desc);
627 0 : if (ip == NULL) {
628 : /* The following is possible if the descriptor was changed while we had
629 : * this introduction circuit open and waiting for the rendezvous circuit to
630 : * be ready. Which results in this situation where we can't find the
631 : * corresponding intro point within the descriptor of the service. */
632 0 : log_info(LD_REND, "Unable to find introduction point for service %s "
633 : "while trying to send an INTRODUCE1 cell.",
634 : safe_str_client(onion_address));
635 0 : goto perm_err;
636 : }
637 :
638 : /* Send the INTRODUCE1 cell. */
639 0 : if (hs_circ_send_introduce1(intro_circ, rend_circ, ip,
640 0 : &desc->subcredential) < 0) {
641 0 : if (TO_CIRCUIT(intro_circ)->marked_for_close) {
642 : /* If the introduction circuit was closed, we were unable to send the
643 : * cell for some reasons. In any case, the intro circuit has to be
644 : * closed by the above function. We'll return a transient error so tor
645 : * can recover and pick a new intro point. To avoid picking that same
646 : * intro point, we'll note down the intro point failure so it doesn't
647 : * get reused. */
648 0 : hs_cache_client_intro_state_note(service_identity_pk,
649 0 : &intro_circ->hs_ident->intro_auth_pk,
650 : INTRO_POINT_FAILURE_GENERIC);
651 : }
652 : /* It is also possible that the rendezvous circuit was closed due to being
653 : * unable to use the rendezvous point node_t so in that case, we also want
654 : * to recover and let tor pick a new one. */
655 0 : goto tran_err;
656 : }
657 :
658 : /* Cell has been sent successfully. Copy the introduction point
659 : * authentication and encryption key in the rendezvous circuit identifier so
660 : * we can compute the ntor keys when we receive the RENDEZVOUS2 cell. */
661 0 : memcpy(&rend_circ->hs_ident->intro_enc_pk, &ip->enc_key,
662 : sizeof(rend_circ->hs_ident->intro_enc_pk));
663 0 : ed25519_pubkey_copy(&rend_circ->hs_ident->intro_auth_pk,
664 0 : &intro_circ->hs_ident->intro_auth_pk);
665 :
666 : /* Now, we wait for an ACK or NAK on this circuit. */
667 0 : circuit_change_purpose(TO_CIRCUIT(intro_circ),
668 : CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT);
669 : /* Set timestamp_dirty, because circuit_expire_building expects it to
670 : * specify when a circuit entered the _C_INTRODUCE_ACK_WAIT state. */
671 0 : TO_CIRCUIT(intro_circ)->timestamp_dirty = time(NULL);
672 0 : pathbias_count_use_attempt(intro_circ);
673 :
674 : /* Success. */
675 0 : status = 0;
676 0 : goto end;
677 :
678 0 : perm_err:
679 : /* Permanent error: it is possible that the intro circuit was closed prior
680 : * because we weren't able to send the cell. Make sure we don't double close
681 : * it which would result in a warning. */
682 0 : if (!TO_CIRCUIT(intro_circ)->marked_for_close) {
683 0 : circuit_mark_for_close(TO_CIRCUIT(intro_circ), END_CIRC_REASON_INTERNAL);
684 : }
685 0 : circuit_mark_for_close(TO_CIRCUIT(rend_circ), END_CIRC_REASON_INTERNAL);
686 0 : status = -2;
687 0 : goto end;
688 :
689 : tran_err:
690 : status = -1;
691 :
692 0 : end:
693 0 : memwipe(onion_address, 0, sizeof(onion_address));
694 0 : return status;
695 : }
696 :
697 : /** Using the introduction circuit circ, setup the authentication key of the
698 : * intro point this circuit has extended to.
699 : *
700 : * Return 0 if everything went well, otherwise return -1 in the case of errors.
701 : */
702 : static int
703 0 : setup_intro_circ_auth_key(origin_circuit_t *circ)
704 : {
705 0 : const hs_descriptor_t *desc;
706 0 : const hs_desc_intro_point_t *ip;
707 :
708 0 : tor_assert(circ);
709 :
710 0 : desc = hs_cache_lookup_as_client(&circ->hs_ident->identity_pk);
711 0 : if (desc == NULL) {
712 : /* There is a very small race window between the opening of this circuit
713 : * and the client descriptor cache that gets purged (NEWNYM) or the
714 : * cleaned up because it expired. Mark the circuit for close so a new
715 : * descriptor fetch can occur. */
716 0 : goto err;
717 : }
718 :
719 : /* We will go over every intro point and try to find which one is linked to
720 : * that circuit. Those lists are small so it's not that expensive. */
721 0 : ip = find_desc_intro_point_by_legacy_id(
722 0 : circ->build_state->chosen_exit->identity_digest, desc);
723 0 : if (!ip) {
724 : /* Reaching this point means we didn't find any intro point for this
725 : * circuit which is not supposed to happen. */
726 0 : log_info(LD_REND,"Could not match opened intro circuit with intro point.");
727 0 : goto err;
728 : }
729 :
730 : /* We got it, copy its authentication key to the identifier. */
731 0 : ed25519_pubkey_copy(&circ->hs_ident->intro_auth_pk,
732 0 : &ip->auth_key_cert->signed_key);
733 0 : return 0;
734 :
735 0 : err:
736 0 : circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
737 0 : return -1;
738 : }
739 :
740 : /** Called when an introduction circuit has opened. */
741 : static void
742 0 : client_intro_circ_has_opened(origin_circuit_t *circ)
743 : {
744 0 : tor_assert(circ);
745 0 : tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
746 0 : log_info(LD_REND, "Introduction circuit %u has opened. Attaching streams.",
747 : (unsigned int) TO_CIRCUIT(circ)->n_circ_id);
748 :
749 : /* This is an introduction circuit so we'll attach the correct
750 : * authentication key to the circuit identifier so it can be identified
751 : * properly later on. */
752 0 : if (setup_intro_circ_auth_key(circ) < 0) {
753 : return;
754 : }
755 :
756 0 : connection_ap_attach_pending(1);
757 : }
758 :
759 : /** Called when a rendezvous circuit has opened. */
760 : static void
761 0 : client_rendezvous_circ_has_opened(origin_circuit_t *circ)
762 : {
763 0 : tor_assert(circ);
764 0 : tor_assert(TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
765 :
766 0 : const extend_info_t *rp_ei = circ->build_state->chosen_exit;
767 :
768 : /* Check that we didn't accidentally choose a node that does not understand
769 : * the v3 rendezvous protocol */
770 0 : if (rp_ei) {
771 0 : const node_t *rp_node = node_get_by_id(rp_ei->identity_digest);
772 0 : if (rp_node && !node_supports_v3_rendezvous_point(rp_node)) {
773 : /* Even tho we checked that this node supported v3 when we created the
774 : rendezvous circuit, there is a chance that we might think it does
775 : not support v3 anymore. This might happen if we got a new consensus
776 : in the meanwhile, where the relay is still listed but its listed
777 : descriptor digest has changed and hence we can't access its 'ri' or
778 : 'md'. */
779 0 : log_info(LD_REND, "Rendezvous node %s did not support v3 after circuit "
780 : "has opened.", safe_str_client(extend_info_describe(rp_ei)));
781 0 : return;
782 : }
783 : }
784 :
785 0 : log_info(LD_REND, "Rendezvous circuit has opened to %s.",
786 : safe_str_client(extend_info_describe(rp_ei)));
787 :
788 : /* Ignore returned value, nothing we can really do. On failure, the circuit
789 : * will be marked for close. */
790 0 : hs_circ_send_establish_rendezvous(circ);
791 :
792 : /* Register rend circuit in circuitmap if it's still alive. */
793 0 : if (!TO_CIRCUIT(circ)->marked_for_close) {
794 0 : hs_circuitmap_register_rend_circ_client_side(circ,
795 0 : circ->hs_ident->rendezvous_cookie);
796 : }
797 : }
798 :
799 : /** This is an helper function that convert a descriptor intro point object ip
800 : * to a newly allocated extend_info_t object fully initialized. Return NULL if
801 : * we can't convert it for which chances are that we are missing or malformed
802 : * link specifiers. */
803 : STATIC extend_info_t *
804 75 : desc_intro_point_to_extend_info(const hs_desc_intro_point_t *ip)
805 : {
806 75 : extend_info_t *ei;
807 :
808 75 : tor_assert(ip);
809 :
810 : /* Explicitly put the direct connection option to 0 because this is client
811 : * side and there is no such thing as a non anonymous client. */
812 75 : ei = hs_get_extend_info_from_lspecs(ip->link_specifiers, &ip->onion_key, 0);
813 :
814 75 : return ei;
815 : }
816 :
817 : /** Return true iff the intro point ip for the service service_pk is usable.
818 : * This function checks if the intro point is in the client intro state cache
819 : * and checks at the failures. It is considered usable if:
820 : * - No error happened (INTRO_POINT_FAILURE_GENERIC)
821 : * - It is not flagged as timed out (INTRO_POINT_FAILURE_TIMEOUT)
822 : * - The unreachable count is lower than
823 : * MAX_INTRO_POINT_REACHABILITY_FAILURES (INTRO_POINT_FAILURE_UNREACHABLE)
824 : */
825 : static int
826 253 : intro_point_is_usable(const ed25519_public_key_t *service_pk,
827 : const hs_desc_intro_point_t *ip)
828 : {
829 253 : const hs_cache_intro_state_t *state;
830 :
831 253 : tor_assert(service_pk);
832 253 : tor_assert(ip);
833 :
834 506 : state = hs_cache_client_intro_state_find(service_pk,
835 253 : &ip->auth_key_cert->signed_key);
836 253 : if (state == NULL) {
837 : /* This means we've never encountered any problem thus usable. */
838 136 : goto usable;
839 : }
840 117 : if (state->error) {
841 116 : log_info(LD_REND, "Intro point with auth key %s had an error. Not usable",
842 : safe_str_client(ed25519_fmt(&ip->auth_key_cert->signed_key)));
843 116 : goto not_usable;
844 : }
845 1 : if (state->timed_out) {
846 1 : log_info(LD_REND, "Intro point with auth key %s timed out. Not usable",
847 : safe_str_client(ed25519_fmt(&ip->auth_key_cert->signed_key)));
848 1 : goto not_usable;
849 : }
850 0 : if (state->unreachable_count >= MAX_INTRO_POINT_REACHABILITY_FAILURES) {
851 0 : log_info(LD_REND, "Intro point with auth key %s unreachable. Not usable",
852 : safe_str_client(ed25519_fmt(&ip->auth_key_cert->signed_key)));
853 0 : goto not_usable;
854 : }
855 :
856 0 : usable:
857 : return 1;
858 : not_usable:
859 : return 0;
860 : }
861 :
862 : /** Using a descriptor desc, return a newly allocated extend_info_t object of a
863 : * randomly picked introduction point from its list. Return NULL if none are
864 : * usable. */
865 : STATIC extend_info_t *
866 68 : client_get_random_intro(const ed25519_public_key_t *service_pk)
867 : {
868 68 : extend_info_t *ei = NULL, *ei_excluded = NULL;
869 68 : smartlist_t *usable_ips = NULL;
870 68 : const hs_descriptor_t *desc;
871 68 : const hs_desc_encrypted_data_t *enc_data;
872 68 : const or_options_t *options = get_options();
873 : /* Calculate the onion address for logging purposes */
874 68 : char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1];
875 :
876 68 : tor_assert(service_pk);
877 :
878 68 : desc = hs_cache_lookup_as_client(service_pk);
879 : /* Assume the service is v3 if the descriptor is missing. This is ok,
880 : * because we only use the address in log messages */
881 135 : hs_build_address(service_pk,
882 67 : desc ? desc->plaintext_data.version : HS_VERSION_THREE,
883 : onion_address);
884 68 : if (desc == NULL || !hs_client_any_intro_points_usable(service_pk,
885 : desc)) {
886 3 : log_info(LD_REND, "Unable to randomly select an introduction point "
887 : "for service %s because descriptor %s. We can't connect.",
888 : safe_str_client(onion_address),
889 : (desc) ? "doesn't have any usable intro points"
890 : : "is missing (assuming v3 onion address)");
891 2 : goto end;
892 : }
893 :
894 66 : enc_data = &desc->encrypted_data;
895 66 : usable_ips = smartlist_new();
896 66 : smartlist_add_all(usable_ips, enc_data->intro_points);
897 168 : while (smartlist_len(usable_ips) != 0) {
898 167 : int idx;
899 167 : const hs_desc_intro_point_t *ip;
900 :
901 : /* Pick a random intro point and immediately remove it from the usable
902 : * list so we don't pick it again if we have to iterate more. */
903 167 : idx = crypto_rand_int(smartlist_len(usable_ips));
904 167 : ip = smartlist_get(usable_ips, idx);
905 167 : smartlist_del(usable_ips, idx);
906 :
907 : /* We need to make sure we have a usable intro points which is in a good
908 : * state in our cache. */
909 167 : if (!intro_point_is_usable(service_pk, ip)) {
910 97 : continue;
911 : }
912 :
913 : /* Generate an extend info object from the intro point object. */
914 70 : ei = desc_intro_point_to_extend_info(ip);
915 70 : if (ei == NULL) {
916 : /* We can get here for instance if the intro point is a private address
917 : * and we aren't allowed to extend to those. */
918 2 : log_info(LD_REND, "Unable to select introduction point with auth key %s "
919 : "for service %s, because we could not extend to it.",
920 : safe_str_client(ed25519_fmt(&ip->auth_key_cert->signed_key)),
921 : safe_str_client(onion_address));
922 2 : continue;
923 : }
924 :
925 : /* Test the pick against ExcludeNodes. */
926 68 : if (routerset_contains_extendinfo(options->ExcludeNodes, ei)) {
927 : /* If this pick is in the ExcludeNodes list, we keep its reference so if
928 : * we ever end up not being able to pick anything else and StrictNodes is
929 : * unset, we'll use it. */
930 3 : if (ei_excluded) {
931 : /* If something was already here free it. After the loop is gone we
932 : * will examine the last excluded intro point, and that's fine since
933 : * that's random anyway */
934 2 : extend_info_free(ei_excluded);
935 : }
936 3 : ei_excluded = ei;
937 3 : continue;
938 : }
939 :
940 : /* Good pick! Let's go with this. */
941 65 : goto end;
942 : }
943 :
944 : /* Reaching this point means a couple of things. Either we can't use any of
945 : * the intro point listed because the IP address can't be extended to or it
946 : * is listed in the ExcludeNodes list. In the later case, if StrictNodes is
947 : * set, we are forced to not use anything. */
948 1 : ei = ei_excluded;
949 1 : if (options->StrictNodes) {
950 1 : log_warn(LD_REND, "Every introduction point for service %s is in the "
951 : "ExcludeNodes set and StrictNodes is set. We can't connect.",
952 : safe_str_client(onion_address));
953 1 : extend_info_free(ei);
954 1 : ei = NULL;
955 : } else {
956 0 : log_fn(LOG_PROTOCOL_WARN, LD_REND, "Every introduction point for service "
957 : "%s is unusable or we can't extend to it. We can't connect.",
958 : safe_str_client(onion_address));
959 : }
960 :
961 68 : end:
962 68 : smartlist_free(usable_ips);
963 68 : memwipe(onion_address, 0, sizeof(onion_address));
964 68 : return ei;
965 : }
966 :
967 : /** Return true iff all intro points for the given service have timed out. */
968 : static bool
969 4 : intro_points_all_timed_out(const ed25519_public_key_t *service_pk)
970 : {
971 4 : bool ret = false;
972 :
973 4 : tor_assert(service_pk);
974 :
975 4 : const hs_descriptor_t *desc = hs_cache_lookup_as_client(service_pk);
976 4 : if (BUG(!desc)) {
977 : /* We can't introduce without a descriptor so ending up here means somehow
978 : * between the introduction failure and this, the cache entry was removed
979 : * which shouldn't be possible in theory. */
980 0 : goto end;
981 : }
982 :
983 8 : SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
984 : const hs_desc_intro_point_t *, ip) {
985 7 : const hs_cache_intro_state_t *state =
986 14 : hs_cache_client_intro_state_find(service_pk,
987 7 : &ip->auth_key_cert->signed_key);
988 7 : if (!state || !state->timed_out) {
989 : /* No state or if this intro point has not timed out, we are done since
990 : * clearly not all of them have timed out. */
991 3 : goto end;
992 : }
993 4 : } SMARTLIST_FOREACH_END(ip);
994 :
995 : /* Exiting the loop here means that all intro points we've looked at have
996 : * timed out. Note that we can _not_ have a descriptor without intro points
997 : * in the client cache. */
998 : ret = true;
999 :
1000 4 : end:
1001 4 : return ret;
1002 : }
1003 :
1004 : /** Called when a rendezvous circuit has timed out. Every stream attached to
1005 : * the circuit will get set with the SOCKS5_HS_REND_FAILED (0xF3) extended
1006 : * error code so if the connection to the rendezvous point ends up not
1007 : * working, this code could be sent back as a reason. */
1008 : static void
1009 1 : socks_mark_rend_circuit_timed_out(const origin_circuit_t *rend_circ)
1010 : {
1011 1 : tor_assert(rend_circ);
1012 :
1013 : /* For each entry connection attached to this rendezvous circuit, report
1014 : * the error. */
1015 2 : for (edge_connection_t *edge = rend_circ->p_streams; edge;
1016 1 : edge = edge->next_stream) {
1017 1 : entry_connection_t *entry = EDGE_TO_ENTRY_CONN(edge);
1018 1 : if (entry->socks_request) {
1019 1 : entry->socks_request->socks_extended_error_code =
1020 : SOCKS5_HS_REND_FAILED;
1021 : }
1022 : }
1023 1 : }
1024 :
1025 : /** Called when introduction has failed meaning there is no more usable
1026 : * introduction points to be used (either NACKed or failed) for the given
1027 : * entry connection.
1028 : *
1029 : * This function only reports back the SOCKS5_HS_INTRO_FAILED (0xF2) code or
1030 : * SOCKS5_HS_INTRO_TIMEDOUT (0xF7) if all intros have timed out. The caller
1031 : * has to make sure to close the entry connections. */
1032 : static void
1033 4 : socks_mark_introduction_failed(entry_connection_t *conn,
1034 : const ed25519_public_key_t *identity_pk)
1035 : {
1036 4 : socks5_reply_status_t code = SOCKS5_HS_INTRO_FAILED;
1037 :
1038 4 : tor_assert(conn);
1039 4 : tor_assert(conn->socks_request);
1040 4 : tor_assert(identity_pk);
1041 :
1042 4 : if (intro_points_all_timed_out(identity_pk)) {
1043 1 : code = SOCKS5_HS_INTRO_TIMEDOUT;
1044 : }
1045 4 : conn->socks_request->socks_extended_error_code = code;
1046 4 : }
1047 :
1048 : /** For this introduction circuit, we'll look at if we have any usable
1049 : * introduction point left for this service. If so, we'll use the circuit to
1050 : * re-extend to a new intro point. Else, we'll close the circuit and its
1051 : * corresponding rendezvous circuit. Return 0 if we are re-extending else -1
1052 : * if we are closing the circuits.
1053 : *
1054 : * This is called when getting an INTRODUCE_ACK cell with a NACK. */
1055 : static int
1056 0 : close_or_reextend_intro_circ(origin_circuit_t *intro_circ)
1057 : {
1058 0 : int ret = -1;
1059 0 : const hs_descriptor_t *desc;
1060 0 : origin_circuit_t *rend_circ;
1061 :
1062 0 : tor_assert(intro_circ);
1063 :
1064 0 : desc = hs_cache_lookup_as_client(&intro_circ->hs_ident->identity_pk);
1065 0 : if (desc == NULL) {
1066 : /* We can't continue without a descriptor. This is possible if the cache
1067 : * was cleaned up between the intro point established and the reception of
1068 : * the introduce ack. */
1069 0 : goto close;
1070 : }
1071 : /* We still have the descriptor, great! Let's try to see if we can
1072 : * re-extend by looking up if there are any usable intro points. */
1073 0 : if (!hs_client_any_intro_points_usable(&intro_circ->hs_ident->identity_pk,
1074 : desc)) {
1075 0 : goto close;
1076 : }
1077 : /* Try to re-extend now. */
1078 0 : if (hs_client_reextend_intro_circuit(intro_circ) < 0) {
1079 0 : goto close;
1080 : }
1081 : /* Success on re-extending. Don't return an error. */
1082 0 : ret = 0;
1083 0 : goto end;
1084 :
1085 0 : close:
1086 : /* Change the intro circuit purpose before so we don't report an intro point
1087 : * failure again triggering an extra descriptor fetch. The circuit can
1088 : * already be closed on failure to re-extend. */
1089 0 : if (!TO_CIRCUIT(intro_circ)->marked_for_close) {
1090 0 : circuit_change_purpose(TO_CIRCUIT(intro_circ),
1091 : CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
1092 0 : circuit_mark_for_close(TO_CIRCUIT(intro_circ), END_CIRC_REASON_FINISHED);
1093 : }
1094 : /* Close the related rendezvous circuit. */
1095 0 : rend_circ = hs_circuitmap_get_rend_circ_client_side(
1096 0 : intro_circ->hs_ident->rendezvous_cookie);
1097 : /* The rendezvous circuit might have collapsed while the INTRODUCE_ACK was
1098 : * inflight so we can't expect one every time. */
1099 0 : if (rend_circ) {
1100 0 : circuit_mark_for_close(TO_CIRCUIT(rend_circ), END_CIRC_REASON_FINISHED);
1101 : }
1102 :
1103 0 : end:
1104 0 : return ret;
1105 : }
1106 :
1107 : /** Called when we get an INTRODUCE_ACK success status code. Do the appropriate
1108 : * actions for the rendezvous point and finally close intro_circ. */
1109 : static void
1110 0 : handle_introduce_ack_success(origin_circuit_t *intro_circ)
1111 : {
1112 0 : origin_circuit_t *rend_circ = NULL;
1113 :
1114 0 : tor_assert(intro_circ);
1115 :
1116 0 : log_info(LD_REND, "Received INTRODUCE_ACK ack! Informing rendezvous");
1117 :
1118 : /* Get the rendezvous circuit for this rendezvous cookie. */
1119 0 : uint8_t *rendezvous_cookie = intro_circ->hs_ident->rendezvous_cookie;
1120 0 : rend_circ =
1121 0 : hs_circuitmap_get_established_rend_circ_client_side(rendezvous_cookie);
1122 0 : if (rend_circ == NULL) {
1123 0 : log_info(LD_REND, "Can't find any rendezvous circuit. Stopping");
1124 0 : goto end;
1125 : }
1126 :
1127 0 : assert_circ_anonymity_ok(rend_circ, get_options());
1128 :
1129 : /* It is possible to get a RENDEZVOUS2 cell before the INTRODUCE_ACK which
1130 : * means that the circuit will be joined and already transmitting data. In
1131 : * that case, simply skip the purpose change and close the intro circuit
1132 : * like it should be. */
1133 0 : if (TO_CIRCUIT(rend_circ)->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
1134 0 : goto end;
1135 : }
1136 0 : circuit_change_purpose(TO_CIRCUIT(rend_circ),
1137 : CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED);
1138 : /* Set timestamp_dirty, because circuit_expire_building expects it to
1139 : * specify when a circuit entered the
1140 : * CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED state. */
1141 0 : TO_CIRCUIT(rend_circ)->timestamp_dirty = time(NULL);
1142 :
1143 0 : end:
1144 : /* We don't need the intro circuit anymore. It did what it had to do! */
1145 0 : circuit_change_purpose(TO_CIRCUIT(intro_circ),
1146 : CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
1147 0 : circuit_mark_for_close(TO_CIRCUIT(intro_circ), END_CIRC_REASON_FINISHED);
1148 :
1149 : /* XXX: Close pending intro circuits we might have in parallel. */
1150 0 : return;
1151 : }
1152 :
1153 : /** Called when we get an INTRODUCE_ACK failure status code. Depending on our
1154 : * failure cache status, either close the circuit or re-extend to a new
1155 : * introduction point. */
1156 : static void
1157 0 : handle_introduce_ack_bad(origin_circuit_t *circ, int status)
1158 : {
1159 0 : tor_assert(circ);
1160 :
1161 0 : log_info(LD_REND, "Received INTRODUCE_ACK nack by %s. Reason: %u",
1162 : safe_str_client(extend_info_describe(circ->build_state->chosen_exit)),
1163 : status);
1164 :
1165 : /* It's a NAK. The introduction point didn't relay our request. */
1166 0 : circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_INTRODUCING);
1167 :
1168 : /* Note down this failure in the intro point failure cache. Depending on how
1169 : * many times we've tried this intro point, close it or reextend. */
1170 0 : hs_cache_client_intro_state_note(&circ->hs_ident->identity_pk,
1171 0 : &circ->hs_ident->intro_auth_pk,
1172 : INTRO_POINT_FAILURE_GENERIC);
1173 0 : }
1174 :
1175 : /** Called when we get an INTRODUCE_ACK on the intro circuit circ. The encoded
1176 : * cell is in payload of length payload_len. Return 0 on success else a
1177 : * negative value. The circuit is either close or reuse to re-extend to a new
1178 : * introduction point. */
1179 : static int
1180 0 : handle_introduce_ack(origin_circuit_t *circ, const uint8_t *payload,
1181 : size_t payload_len)
1182 : {
1183 0 : int status, ret = -1;
1184 :
1185 0 : tor_assert(circ);
1186 0 : tor_assert(circ->build_state);
1187 0 : tor_assert(circ->build_state->chosen_exit);
1188 0 : assert_circ_anonymity_ok(circ, get_options());
1189 0 : tor_assert(payload);
1190 :
1191 0 : status = hs_cell_parse_introduce_ack(payload, payload_len);
1192 0 : switch (status) {
1193 0 : case TRUNNEL_HS_INTRO_ACK_STATUS_SUCCESS:
1194 0 : ret = 0;
1195 0 : handle_introduce_ack_success(circ);
1196 0 : goto end;
1197 0 : case TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID:
1198 : case TRUNNEL_HS_INTRO_ACK_STATUS_BAD_FORMAT:
1199 : /* It is possible that the intro point can send us an unknown status code
1200 : * for the NACK that we do not know about like a new code for instance.
1201 : * Just fallthrough so we can note down the NACK and re-extend. */
1202 : default:
1203 0 : handle_introduce_ack_bad(circ, status);
1204 : /* We are going to see if we have to close the circuits (IP and RP) or we
1205 : * can re-extend to a new intro point. */
1206 0 : ret = close_or_reextend_intro_circ(circ);
1207 0 : break;
1208 : }
1209 :
1210 0 : end:
1211 0 : return ret;
1212 : }
1213 :
1214 : /** Called when we get a RENDEZVOUS2 cell on the rendezvous circuit circ. The
1215 : * encoded cell is in payload of length payload_len. Return 0 on success or a
1216 : * negative value on error. On error, the circuit is marked for close. */
1217 : STATIC int
1218 1 : handle_rendezvous2(origin_circuit_t *circ, const uint8_t *payload,
1219 : size_t payload_len)
1220 : {
1221 1 : int ret = -1;
1222 1 : curve25519_public_key_t server_pk;
1223 1 : uint8_t auth_mac[DIGEST256_LEN] = {0};
1224 1 : uint8_t handshake_info[CURVE25519_PUBKEY_LEN + sizeof(auth_mac)] = {0};
1225 1 : hs_ntor_rend_cell_keys_t keys;
1226 1 : const hs_ident_circuit_t *ident;
1227 :
1228 1 : tor_assert(circ);
1229 1 : tor_assert(payload);
1230 :
1231 : /* Make things easier. */
1232 1 : ident = circ->hs_ident;
1233 1 : tor_assert(ident);
1234 :
1235 1 : if (hs_cell_parse_rendezvous2(payload, payload_len, handshake_info,
1236 : sizeof(handshake_info)) < 0) {
1237 0 : goto err;
1238 : }
1239 : /* Get from the handshake info the SERVER_PK and AUTH_MAC. */
1240 1 : memcpy(&server_pk, handshake_info, CURVE25519_PUBKEY_LEN);
1241 1 : memcpy(auth_mac, handshake_info + CURVE25519_PUBKEY_LEN, sizeof(auth_mac));
1242 :
1243 : /* Generate the handshake info. */
1244 1 : if (hs_ntor_client_get_rendezvous1_keys(&ident->intro_auth_pk,
1245 1 : &ident->rendezvous_client_kp,
1246 1 : &ident->intro_enc_pk, &server_pk,
1247 : &keys) < 0) {
1248 0 : log_info(LD_REND, "Unable to compute the rendezvous keys.");
1249 0 : goto err;
1250 : }
1251 :
1252 : /* Critical check, make sure that the MAC matches what we got with what we
1253 : * computed just above. */
1254 1 : if (!hs_ntor_client_rendezvous2_mac_is_good(&keys, auth_mac)) {
1255 0 : log_info(LD_REND, "Invalid MAC in RENDEZVOUS2. Rejecting cell.");
1256 0 : goto err;
1257 : }
1258 :
1259 : /* Setup the e2e encryption on the circuit and finalize its state. */
1260 1 : if (hs_circuit_setup_e2e_rend_circ(circ, keys.ntor_key_seed,
1261 : sizeof(keys.ntor_key_seed), 0) < 0) {
1262 0 : log_info(LD_REND, "Unable to setup the e2e encryption.");
1263 0 : goto err;
1264 : }
1265 : /* Success. Hidden service connection finalized! */
1266 1 : ret = 0;
1267 1 : goto end;
1268 :
1269 0 : err:
1270 0 : circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
1271 1 : end:
1272 1 : memwipe(&keys, 0, sizeof(keys));
1273 1 : return ret;
1274 : }
1275 :
1276 : /** Return true iff the client can fetch a descriptor for this service public
1277 : * identity key and status_out if not NULL is untouched. If the client can
1278 : * _not_ fetch the descriptor and if status_out is not NULL, it is set with
1279 : * the fetch status code. */
1280 : static unsigned int
1281 6 : can_client_refetch_desc(const ed25519_public_key_t *identity_pk,
1282 : hs_client_fetch_status_t *status_out)
1283 : {
1284 6 : hs_client_fetch_status_t status;
1285 :
1286 6 : tor_assert(identity_pk);
1287 :
1288 : /* Are we configured to fetch descriptors? */
1289 6 : if (!get_options()->FetchHidServDescriptors) {
1290 1 : log_warn(LD_REND, "We received an onion address for a hidden service "
1291 : "descriptor but we are configured to not fetch.");
1292 1 : status = HS_CLIENT_FETCH_NOT_ALLOWED;
1293 1 : goto cannot;
1294 : }
1295 :
1296 : /* Without a usable consensus we can't do any client actions. It is needed
1297 : * to compute the hashring for a service. */
1298 5 : if (!networkstatus_get_reasonably_live_consensus(approx_time(),
1299 : usable_consensus_flavor())) {
1300 2 : log_info(LD_REND, "Can't fetch descriptor for service %s because we "
1301 : "are missing a live consensus. Stalling connection.",
1302 : safe_str_client(ed25519_fmt(identity_pk)));
1303 2 : status = HS_CLIENT_FETCH_MISSING_INFO;
1304 2 : goto cannot;
1305 : }
1306 :
1307 3 : if (!router_have_minimum_dir_info()) {
1308 1 : log_info(LD_REND, "Can't fetch descriptor for service %s because we "
1309 : "dont have enough descriptors. Stalling connection.",
1310 : safe_str_client(ed25519_fmt(identity_pk)));
1311 1 : status = HS_CLIENT_FETCH_MISSING_INFO;
1312 1 : goto cannot;
1313 : }
1314 :
1315 : /* Check if fetching a desc for this HS is useful to us right now */
1316 : {
1317 2 : const hs_descriptor_t *cached_desc = NULL;
1318 2 : cached_desc = hs_cache_lookup_as_client(identity_pk);
1319 2 : if (cached_desc && hs_client_any_intro_points_usable(identity_pk,
1320 : cached_desc)) {
1321 0 : log_info(LD_GENERAL, "We would fetch a v3 hidden service descriptor "
1322 : "but we already have a usable descriptor.");
1323 0 : status = HS_CLIENT_FETCH_HAVE_DESC;
1324 0 : goto cannot;
1325 : }
1326 : }
1327 :
1328 : /* Don't try to refetch while we have a pending request for it. */
1329 2 : if (directory_request_is_pending(identity_pk)) {
1330 1 : log_info(LD_REND, "Already a pending directory request. Waiting on it.");
1331 1 : status = HS_CLIENT_FETCH_PENDING;
1332 1 : goto cannot;
1333 : }
1334 :
1335 : /* Yes, client can fetch! */
1336 : return 1;
1337 5 : cannot:
1338 5 : if (status_out) {
1339 5 : *status_out = status;
1340 : }
1341 : return 0;
1342 : }
1343 :
1344 : /** Purge the client authorization cache of all ephemeral entries that is the
1345 : * entries that are not flagged with CLIENT_AUTH_FLAG_IS_PERMANENT.
1346 : *
1347 : * This is called from the hs_client_purge_state() used by a SIGNEWNYM. */
1348 : STATIC void
1349 2 : purge_ephemeral_client_auth(void)
1350 : {
1351 4 : DIGEST256MAP_FOREACH_MODIFY(client_auths, key,
1352 : hs_client_service_authorization_t *, auth) {
1353 : /* Cleanup every entry that are _NOT_ permanent that is ephemeral. */
1354 2 : if (!(auth->flags & CLIENT_AUTH_FLAG_IS_PERMANENT)) {
1355 1 : MAP_DEL_CURRENT(key);
1356 2 : client_service_authorization_free(auth);
1357 : }
1358 2 : } DIGESTMAP_FOREACH_END;
1359 :
1360 2 : log_info(LD_REND, "Client onion service ephemeral authorization "
1361 : "cache has been purged.");
1362 2 : }
1363 :
1364 : /** Return the client auth in the map using the service identity public key.
1365 : * Return NULL if it does not exist in the map. */
1366 : static hs_client_service_authorization_t *
1367 18 : find_client_auth(const ed25519_public_key_t *service_identity_pk)
1368 : {
1369 : /* If the map is not allocated, we can assume that we do not have any client
1370 : * auth information. */
1371 18 : if (!client_auths) {
1372 : return NULL;
1373 : }
1374 3 : return digest256map_get(client_auths, service_identity_pk->pubkey);
1375 : }
1376 :
1377 : /** This is called when a descriptor has arrived following a fetch request and
1378 : * has been stored in the client cache. The given entry connections, matching
1379 : * the service identity key, will get attached to the service circuit. */
1380 : static void
1381 4 : client_desc_has_arrived(const smartlist_t *entry_conns)
1382 : {
1383 4 : time_t now = time(NULL);
1384 :
1385 4 : tor_assert(entry_conns);
1386 :
1387 8 : SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
1388 4 : const hs_descriptor_t *desc;
1389 4 : edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
1390 4 : const ed25519_public_key_t *identity_pk =
1391 4 : &edge_conn->hs_ident->identity_pk;
1392 :
1393 : /* We were just called because we stored the descriptor for this service
1394 : * so not finding a descriptor means we have a bigger problem. */
1395 4 : desc = hs_cache_lookup_as_client(identity_pk);
1396 4 : if (BUG(desc == NULL)) {
1397 0 : goto end;
1398 : }
1399 :
1400 4 : if (!hs_client_any_intro_points_usable(identity_pk, desc)) {
1401 4 : log_info(LD_REND, "Hidden service descriptor is unusable. "
1402 : "Closing streams.");
1403 : /* Report the extended socks error code that we were unable to introduce
1404 : * to the service. */
1405 4 : socks_mark_introduction_failed(entry_conn, identity_pk);
1406 :
1407 4 : connection_mark_unattached_ap(entry_conn,
1408 : END_STREAM_REASON_RESOLVEFAILED);
1409 : /* We are unable to use the descriptor so remove the directory request
1410 : * from the cache so the next connection can try again. */
1411 4 : note_connection_attempt_succeeded(edge_conn->hs_ident);
1412 4 : continue;
1413 : }
1414 :
1415 0 : log_info(LD_REND, "Descriptor has arrived. Launching circuits.");
1416 :
1417 : /* Mark connection as waiting for a circuit since we do have a usable
1418 : * descriptor now. */
1419 0 : mark_conn_as_waiting_for_circuit(&edge_conn->base_, now);
1420 4 : } SMARTLIST_FOREACH_END(entry_conn);
1421 :
1422 4 : end:
1423 4 : return;
1424 : }
1425 :
1426 : /** This is called when a descriptor fetch was successful but the descriptor
1427 : * couldn't be decrypted due to missing or bad client authorization. */
1428 : static void
1429 2 : client_desc_missing_bad_client_auth(const smartlist_t *entry_conns,
1430 : hs_desc_decode_status_t status)
1431 : {
1432 2 : tor_assert(entry_conns);
1433 :
1434 4 : SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
1435 2 : socks5_reply_status_t code;
1436 2 : if (status == HS_DESC_DECODE_BAD_CLIENT_AUTH) {
1437 : code = SOCKS5_HS_BAD_CLIENT_AUTH;
1438 1 : } else if (status == HS_DESC_DECODE_NEED_CLIENT_AUTH) {
1439 : code = SOCKS5_HS_MISSING_CLIENT_AUTH;
1440 : } else {
1441 : /* We should not be called with another type of status. Recover by
1442 : * sending a generic error. */
1443 0 : tor_assert_nonfatal_unreached();
1444 0 : code = SOCKS5_GENERAL_ERROR;
1445 : }
1446 2 : entry_conn->socks_request->socks_extended_error_code = code;
1447 2 : connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_MISC);
1448 2 : } SMARTLIST_FOREACH_END(entry_conn);
1449 2 : }
1450 :
1451 : /** Called when we get a 200 directory fetch status code. */
1452 : static void
1453 6 : client_dir_fetch_200(dir_connection_t *dir_conn,
1454 : const smartlist_t *entry_conns, const char *body)
1455 : {
1456 6 : hs_desc_decode_status_t decode_status;
1457 :
1458 6 : tor_assert(dir_conn);
1459 6 : tor_assert(entry_conns);
1460 6 : tor_assert(body);
1461 :
1462 : /* We got something: Try storing it in the cache. */
1463 12 : decode_status = hs_cache_store_as_client(body,
1464 6 : &dir_conn->hs_ident->identity_pk);
1465 6 : switch (decode_status) {
1466 6 : case HS_DESC_DECODE_OK:
1467 : case HS_DESC_DECODE_NEED_CLIENT_AUTH:
1468 : case HS_DESC_DECODE_BAD_CLIENT_AUTH:
1469 6 : log_info(LD_REND, "Stored hidden service descriptor successfully.");
1470 6 : TO_CONN(dir_conn)->purpose = DIR_PURPOSE_HAS_FETCHED_HSDESC;
1471 6 : if (decode_status == HS_DESC_DECODE_OK) {
1472 4 : client_desc_has_arrived(entry_conns);
1473 : } else {
1474 : /* This handles both client auth decode status. */
1475 2 : client_desc_missing_bad_client_auth(entry_conns, decode_status);
1476 3 : log_info(LD_REND, "Stored hidden service descriptor requires "
1477 : "%s client authorization.",
1478 : decode_status == HS_DESC_DECODE_NEED_CLIENT_AUTH ? "missing"
1479 : : "new");
1480 : }
1481 : /* Fire control port RECEIVED event. */
1482 6 : hs_control_desc_event_received(dir_conn->hs_ident,
1483 6 : dir_conn->identity_digest);
1484 6 : hs_control_desc_event_content(dir_conn->hs_ident,
1485 : dir_conn->identity_digest, body);
1486 6 : break;
1487 0 : case HS_DESC_DECODE_ENCRYPTED_ERROR:
1488 : case HS_DESC_DECODE_SUPERENC_ERROR:
1489 : case HS_DESC_DECODE_PLAINTEXT_ERROR:
1490 : case HS_DESC_DECODE_GENERIC_ERROR:
1491 : default:
1492 0 : log_info(LD_REND, "Failed to store hidden service descriptor. "
1493 : "Descriptor decoding status: %d", decode_status);
1494 : /* Fire control port FAILED event. */
1495 0 : hs_control_desc_event_failed(dir_conn->hs_ident,
1496 0 : dir_conn->identity_digest, "BAD_DESC");
1497 0 : hs_control_desc_event_content(dir_conn->hs_ident,
1498 : dir_conn->identity_digest, NULL);
1499 0 : break;
1500 : }
1501 6 : }
1502 :
1503 : /** Called when we get a 404 directory fetch status code. */
1504 : static void
1505 0 : client_dir_fetch_404(dir_connection_t *dir_conn,
1506 : const smartlist_t *entry_conns)
1507 : {
1508 0 : tor_assert(entry_conns);
1509 :
1510 : /* Not there. We'll retry when connection_about_to_close_connection() tries
1511 : * to clean this conn up. */
1512 0 : log_info(LD_REND, "Fetching hidden service v3 descriptor not found: "
1513 : "Retrying at another directory.");
1514 : /* Fire control port FAILED event. */
1515 0 : hs_control_desc_event_failed(dir_conn->hs_ident, dir_conn->identity_digest,
1516 : "NOT_FOUND");
1517 0 : hs_control_desc_event_content(dir_conn->hs_ident, dir_conn->identity_digest,
1518 : NULL);
1519 :
1520 : /* Flag every entry connections that the descriptor was not found. */
1521 0 : SMARTLIST_FOREACH_BEGIN(entry_conns, entry_connection_t *, entry_conn) {
1522 0 : entry_conn->socks_request->socks_extended_error_code =
1523 : SOCKS5_HS_NOT_FOUND;
1524 0 : } SMARTLIST_FOREACH_END(entry_conn);
1525 0 : }
1526 :
1527 : /** Called when we get a 400 directory fetch status code. */
1528 : static void
1529 0 : client_dir_fetch_400(dir_connection_t *dir_conn, const char *reason)
1530 : {
1531 0 : tor_assert(dir_conn);
1532 :
1533 0 : log_warn(LD_REND, "Fetching v3 hidden service descriptor failed: "
1534 : "http status 400 (%s). Dirserver didn't like our "
1535 : "query? Retrying at another directory.",
1536 : escaped(reason));
1537 :
1538 : /* Fire control port FAILED event. */
1539 0 : hs_control_desc_event_failed(dir_conn->hs_ident, dir_conn->identity_digest,
1540 : "QUERY_REJECTED");
1541 0 : hs_control_desc_event_content(dir_conn->hs_ident, dir_conn->identity_digest,
1542 : NULL);
1543 0 : }
1544 :
1545 : /** Called when we get an unexpected directory fetch status code. */
1546 : static void
1547 0 : client_dir_fetch_unexpected(dir_connection_t *dir_conn, const char *reason,
1548 : const int status_code)
1549 : {
1550 0 : tor_assert(dir_conn);
1551 :
1552 0 : log_warn(LD_REND, "Fetching v3 hidden service descriptor failed: "
1553 : "http status %d (%s) response unexpected from HSDir "
1554 : "server %s'. Retrying at another directory.",
1555 : status_code, escaped(reason),
1556 : connection_describe_peer(TO_CONN(dir_conn)));
1557 : /* Fire control port FAILED event. */
1558 0 : hs_control_desc_event_failed(dir_conn->hs_ident, dir_conn->identity_digest,
1559 : "UNEXPECTED");
1560 0 : hs_control_desc_event_content(dir_conn->hs_ident, dir_conn->identity_digest,
1561 : NULL);
1562 0 : }
1563 :
1564 : /** Get the full filename for storing the client auth credentials for the
1565 : * service in <b>onion_address</b>. The base directory is <b>dir</b>.
1566 : * This function never returns NULL. */
1567 : static char *
1568 3 : get_client_auth_creds_filename(const char *onion_address,
1569 : const char *dir)
1570 : {
1571 3 : char *full_fname = NULL;
1572 3 : char *fname;
1573 :
1574 3 : tor_asprintf(&fname, "%s.auth_private", onion_address);
1575 3 : full_fname = hs_path_from_filename(dir, fname);
1576 3 : tor_free(fname);
1577 :
1578 3 : return full_fname;
1579 : }
1580 :
1581 : /** Permanently store the credentials in <b>creds</b> to disk.
1582 : *
1583 : * Return -1 if there was an error while storing the credentials, otherwise
1584 : * return 0.
1585 : */
1586 : static int
1587 4 : store_permanent_client_auth_credentials(
1588 : const hs_client_service_authorization_t *creds)
1589 : {
1590 4 : const or_options_t *options = get_options();
1591 4 : char *full_fname = NULL;
1592 4 : char *file_contents = NULL;
1593 4 : char priv_key_b32[BASE32_NOPAD_LEN(CURVE25519_PUBKEY_LEN)+1];
1594 4 : int retval = -1;
1595 :
1596 4 : tor_assert(creds->flags & CLIENT_AUTH_FLAG_IS_PERMANENT);
1597 :
1598 : /* We need ClientOnionAuthDir to be set, otherwise we can't proceed */
1599 4 : if (!options->ClientOnionAuthDir) {
1600 1 : log_warn(LD_GENERAL, "Can't register permanent client auth credentials "
1601 : "for %s without ClientOnionAuthDir option. Discarding.",
1602 : creds->onion_address);
1603 1 : goto err;
1604 : }
1605 :
1606 : /* Make sure the directory exists and is private enough. */
1607 3 : if (check_private_dir(options->ClientOnionAuthDir, 0, options->User) < 0) {
1608 0 : goto err;
1609 : }
1610 :
1611 : /* Get filename that we should store the credentials */
1612 6 : full_fname = get_client_auth_creds_filename(creds->onion_address,
1613 3 : options->ClientOnionAuthDir);
1614 :
1615 : /* Encode client private key */
1616 3 : base32_encode(priv_key_b32, sizeof(priv_key_b32),
1617 3 : (char*)creds->enc_seckey.secret_key,
1618 : sizeof(creds->enc_seckey.secret_key));
1619 :
1620 : /* Get the full file contents and write it to disk! */
1621 3 : tor_asprintf(&file_contents, "%s:descriptor:x25519:%s",
1622 : creds->onion_address, priv_key_b32);
1623 3 : if (write_str_to_file(full_fname, file_contents, 0) < 0) {
1624 0 : log_warn(LD_GENERAL, "Failed to write client auth creds file for %s!",
1625 : creds->onion_address);
1626 0 : goto err;
1627 : }
1628 :
1629 : retval = 0;
1630 :
1631 4 : err:
1632 4 : tor_free(file_contents);
1633 4 : tor_free(full_fname);
1634 :
1635 4 : return retval;
1636 : }
1637 :
1638 : /** Register the credential <b>creds</b> as part of the client auth subsystem.
1639 : *
1640 : * Takes ownership of <b>creds</b>.
1641 : **/
1642 : hs_client_register_auth_status_t
1643 8 : hs_client_register_auth_credentials(hs_client_service_authorization_t *creds)
1644 : {
1645 8 : ed25519_public_key_t service_identity_pk;
1646 8 : hs_client_service_authorization_t *old_creds = NULL;
1647 8 : hs_client_register_auth_status_t retval = REGISTER_SUCCESS;
1648 :
1649 8 : tor_assert(creds);
1650 :
1651 8 : if (!client_auths) {
1652 3 : client_auths = digest256map_new();
1653 : }
1654 :
1655 8 : if (hs_parse_address(creds->onion_address, &service_identity_pk,
1656 : NULL, NULL) < 0) {
1657 0 : client_service_authorization_free(creds);
1658 0 : return REGISTER_FAIL_BAD_ADDRESS;
1659 : }
1660 :
1661 : /* If we reach this point, the credentials will be stored one way or another:
1662 : * Make them permanent if the user asked us to. */
1663 8 : if (creds->flags & CLIENT_AUTH_FLAG_IS_PERMANENT) {
1664 4 : if (store_permanent_client_auth_credentials(creds) < 0) {
1665 1 : client_service_authorization_free(creds);
1666 1 : return REGISTER_FAIL_PERMANENT_STORAGE;
1667 : }
1668 : }
1669 :
1670 7 : old_creds = digest256map_get(client_auths, service_identity_pk.pubkey);
1671 7 : if (old_creds) {
1672 1 : digest256map_remove(client_auths, service_identity_pk.pubkey);
1673 1 : client_service_authorization_free(old_creds);
1674 1 : retval = REGISTER_SUCCESS_ALREADY_EXISTS;
1675 : }
1676 :
1677 7 : digest256map_set(client_auths, service_identity_pk.pubkey, creds);
1678 :
1679 : /** Now that we set the new credentials, also try to decrypt any cached
1680 : * descriptors. */
1681 7 : if (hs_cache_client_new_auth_parse(&service_identity_pk)) {
1682 0 : retval = REGISTER_SUCCESS_AND_DECRYPTED;
1683 : }
1684 :
1685 : return retval;
1686 : }
1687 :
1688 : /** Load a client authorization file with <b>filename</b> that is stored under
1689 : * the global client auth directory, and return a newly-allocated credentials
1690 : * object if it parsed well. Otherwise, return NULL.
1691 : */
1692 : static hs_client_service_authorization_t *
1693 8 : get_creds_from_client_auth_filename(const char *filename,
1694 : const or_options_t *options)
1695 : {
1696 8 : hs_client_service_authorization_t *auth = NULL;
1697 8 : char *client_key_file_path = NULL;
1698 8 : char *client_key_str = NULL;
1699 :
1700 8 : log_info(LD_REND, "Loading a client authorization key file %s...",
1701 : filename);
1702 :
1703 8 : if (!auth_key_filename_is_valid(filename)) {
1704 2 : log_notice(LD_REND, "Client authorization unrecognized filename %s. "
1705 : "File must end in .auth_private. Ignoring.",
1706 : filename);
1707 2 : goto err;
1708 : }
1709 :
1710 : /* Create a full path for a file. */
1711 6 : client_key_file_path = hs_path_from_filename(options->ClientOnionAuthDir,
1712 : filename);
1713 :
1714 6 : client_key_str = read_file_to_str(client_key_file_path, 0, NULL);
1715 6 : if (!client_key_str) {
1716 0 : log_warn(LD_REND, "The file %s cannot be read.", filename);
1717 0 : goto err;
1718 : }
1719 :
1720 6 : auth = parse_auth_file_content(client_key_str);
1721 6 : if (!auth) {
1722 0 : goto err;
1723 : }
1724 :
1725 6 : err:
1726 8 : tor_free(client_key_str);
1727 8 : tor_free(client_key_file_path);
1728 :
1729 8 : return auth;
1730 : }
1731 :
1732 : /*
1733 : * Remove the file in <b>filename</b> under the global client auth credential
1734 : * storage.
1735 : */
1736 : static void
1737 1 : remove_client_auth_creds_file(const char *filename)
1738 : {
1739 1 : char *creds_file_path = NULL;
1740 1 : const or_options_t *options = get_options();
1741 :
1742 1 : creds_file_path = hs_path_from_filename(options->ClientOnionAuthDir,
1743 : filename);
1744 1 : if (tor_unlink(creds_file_path) != 0) {
1745 0 : log_warn(LD_REND, "Failed to remove client auth file (%s).",
1746 : creds_file_path);
1747 0 : goto end;
1748 : }
1749 :
1750 1 : log_warn(LD_REND, "Successfully removed client auth file (%s).",
1751 : creds_file_path);
1752 :
1753 1 : end:
1754 1 : tor_free(creds_file_path);
1755 1 : }
1756 :
1757 : /**
1758 : * Find the filesystem file corresponding to the permanent client auth
1759 : * credentials in <b>cred</b> and remove it.
1760 : */
1761 : static void
1762 1 : find_and_remove_client_auth_creds_file(
1763 : const hs_client_service_authorization_t *cred)
1764 : {
1765 1 : smartlist_t *file_list = NULL;
1766 1 : const or_options_t *options = get_options();
1767 :
1768 1 : tor_assert(cred->flags & CLIENT_AUTH_FLAG_IS_PERMANENT);
1769 :
1770 1 : if (!options->ClientOnionAuthDir) {
1771 0 : log_warn(LD_REND, "Found permanent credential but no ClientOnionAuthDir "
1772 : "configured. There is no file to be removed.");
1773 0 : goto end;
1774 : }
1775 :
1776 1 : file_list = tor_listdir(options->ClientOnionAuthDir);
1777 1 : if (file_list == NULL) {
1778 0 : log_warn(LD_REND, "Client authorization key directory %s can't be listed.",
1779 : options->ClientOnionAuthDir);
1780 0 : goto end;
1781 : }
1782 :
1783 1 : SMARTLIST_FOREACH_BEGIN(file_list, const char *, filename) {
1784 1 : hs_client_service_authorization_t *tmp_cred = NULL;
1785 :
1786 1 : tmp_cred = get_creds_from_client_auth_filename(filename, options);
1787 1 : if (!tmp_cred) {
1788 0 : continue;
1789 : }
1790 :
1791 : /* Find the right file for this credential */
1792 1 : if (!strcmp(tmp_cred->onion_address, cred->onion_address)) {
1793 : /* Found it! Remove the file! */
1794 1 : remove_client_auth_creds_file(filename);
1795 : /* cleanup and get out of here */
1796 1 : client_service_authorization_free(tmp_cred);
1797 1 : break;
1798 : }
1799 :
1800 0 : client_service_authorization_free(tmp_cred);
1801 0 : } SMARTLIST_FOREACH_END(filename);
1802 :
1803 0 : end:
1804 1 : if (file_list) {
1805 2 : SMARTLIST_FOREACH(file_list, char *, s, tor_free(s));
1806 1 : smartlist_free(file_list);
1807 : }
1808 1 : }
1809 :
1810 : /** Remove client auth credentials for the service <b>hs_address</b>. */
1811 : hs_client_removal_auth_status_t
1812 5 : hs_client_remove_auth_credentials(const char *hsaddress)
1813 : {
1814 5 : ed25519_public_key_t service_identity_pk;
1815 :
1816 5 : if (!client_auths) {
1817 : return REMOVAL_SUCCESS_NOT_FOUND;
1818 : }
1819 :
1820 5 : if (hs_parse_address(hsaddress, &service_identity_pk, NULL, NULL) < 0) {
1821 : return REMOVAL_BAD_ADDRESS;
1822 : }
1823 :
1824 5 : hs_client_service_authorization_t *cred = NULL;
1825 5 : cred = digest256map_remove(client_auths, service_identity_pk.pubkey);
1826 :
1827 : /* digestmap_remove() returns the previously stored data if there were any */
1828 5 : if (cred) {
1829 4 : if (cred->flags & CLIENT_AUTH_FLAG_IS_PERMANENT) {
1830 : /* These creds are stored on disk: remove the corresponding file. */
1831 1 : find_and_remove_client_auth_creds_file(cred);
1832 : }
1833 :
1834 : /* Remove associated descriptor if any. */
1835 4 : hs_cache_remove_as_client(&service_identity_pk);
1836 :
1837 4 : client_service_authorization_free(cred);
1838 4 : return REMOVAL_SUCCESS;
1839 : }
1840 :
1841 : return REMOVAL_SUCCESS_NOT_FOUND;
1842 : }
1843 :
1844 : /** Get the HS client auth map. */
1845 : digest256map_t *
1846 14 : get_hs_client_auths_map(void)
1847 : {
1848 14 : return client_auths;
1849 : }
1850 :
1851 : /* ========== */
1852 : /* Public API */
1853 : /* ========== */
1854 :
1855 : /** Called when a circuit was just cleaned up. This is done right before the
1856 : * circuit is marked for close. */
1857 : void
1858 5 : hs_client_circuit_cleanup_on_close(const circuit_t *circ)
1859 : {
1860 5 : bool has_timed_out;
1861 :
1862 5 : tor_assert(circ);
1863 5 : tor_assert(CIRCUIT_IS_ORIGIN(circ));
1864 :
1865 5 : has_timed_out =
1866 5 : (circ->marked_for_close_orig_reason == END_CIRC_REASON_TIMEOUT);
1867 :
1868 5 : switch (circ->purpose) {
1869 1 : case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
1870 : case CIRCUIT_PURPOSE_C_REND_READY:
1871 : case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
1872 : case CIRCUIT_PURPOSE_C_REND_JOINED:
1873 : /* Report extended SOCKS error code when a rendezvous circuit times out.
1874 : * This MUST be done on_close() because it is possible the entry
1875 : * connection would get closed before the circuit is freed and thus
1876 : * would fail to report the error code. */
1877 1 : if (has_timed_out) {
1878 1 : socks_mark_rend_circuit_timed_out(CONST_TO_ORIGIN_CIRCUIT(circ));
1879 : }
1880 : break;
1881 : default:
1882 : break;
1883 : }
1884 5 : }
1885 :
1886 : /** Called when a circuit was just cleaned up. This is done right before the
1887 : * circuit is freed. */
1888 : void
1889 9 : hs_client_circuit_cleanup_on_free(const circuit_t *circ)
1890 : {
1891 9 : bool has_timed_out;
1892 9 : rend_intro_point_failure_t failure = INTRO_POINT_FAILURE_GENERIC;
1893 9 : const origin_circuit_t *orig_circ = NULL;
1894 :
1895 9 : tor_assert(circ);
1896 9 : tor_assert(CIRCUIT_IS_ORIGIN(circ));
1897 :
1898 9 : orig_circ = CONST_TO_ORIGIN_CIRCUIT(circ);
1899 9 : tor_assert(orig_circ->hs_ident);
1900 :
1901 9 : has_timed_out =
1902 9 : (circ->marked_for_close_orig_reason == END_CIRC_REASON_TIMEOUT);
1903 9 : if (has_timed_out) {
1904 3 : failure = INTRO_POINT_FAILURE_TIMEOUT;
1905 : }
1906 :
1907 9 : switch (circ->purpose) {
1908 1 : case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
1909 1 : log_info(LD_REND, "Failed v3 intro circ for service %s to intro point %s "
1910 : "(awaiting ACK). Failure code: %d",
1911 : safe_str_client(ed25519_fmt(&orig_circ->hs_ident->identity_pk)),
1912 : safe_str_client(build_state_get_exit_nickname(orig_circ->build_state)),
1913 : failure);
1914 1 : hs_cache_client_intro_state_note(&orig_circ->hs_ident->identity_pk,
1915 1 : &orig_circ->hs_ident->intro_auth_pk,
1916 : failure);
1917 1 : break;
1918 5 : case CIRCUIT_PURPOSE_C_INTRODUCING:
1919 5 : if (has_timed_out || !orig_circ->build_state) {
1920 : break;
1921 : }
1922 1 : failure = INTRO_POINT_FAILURE_UNREACHABLE;
1923 1 : log_info(LD_REND, "Failed v3 intro circ for service %s to intro point %s "
1924 : "(while building circuit). Marking as unreachable.",
1925 : safe_str_client(ed25519_fmt(&orig_circ->hs_ident->identity_pk)),
1926 : safe_str_client(build_state_get_exit_nickname(orig_circ->build_state)));
1927 1 : hs_cache_client_intro_state_note(&orig_circ->hs_ident->identity_pk,
1928 1 : &orig_circ->hs_ident->intro_auth_pk,
1929 : failure);
1930 1 : break;
1931 : default:
1932 : break;
1933 : }
1934 9 : }
1935 :
1936 : /** A circuit just finished connecting to a hidden service that the stream
1937 : * <b>conn</b> has been waiting for. Let the HS subsystem know about this. */
1938 : void
1939 1 : hs_client_note_connection_attempt_succeeded(const edge_connection_t *conn)
1940 : {
1941 1 : tor_assert(connection_edge_is_rendezvous_stream(conn));
1942 :
1943 1 : if (conn->hs_ident) { /* It's v3: pass it to the prop224 handler */
1944 1 : note_connection_attempt_succeeded(conn->hs_ident);
1945 1 : return;
1946 : }
1947 : }
1948 :
1949 : /** With the given encoded descriptor in desc_str and the service key in
1950 : * service_identity_pk, decode the descriptor and set the desc pointer with a
1951 : * newly allocated descriptor object.
1952 : *
1953 : * On success, HS_DESC_DECODE_OK is returned and desc is set to the decoded
1954 : * descriptor. On error, desc is set to NULL and a decoding error status is
1955 : * returned depending on what was the issue. */
1956 : hs_desc_decode_status_t
1957 18 : hs_client_decode_descriptor(const char *desc_str,
1958 : const ed25519_public_key_t *service_identity_pk,
1959 : hs_descriptor_t **desc)
1960 : {
1961 18 : hs_desc_decode_status_t ret;
1962 18 : hs_subcredential_t subcredential;
1963 18 : ed25519_public_key_t blinded_pubkey;
1964 18 : hs_client_service_authorization_t *client_auth = NULL;
1965 18 : curve25519_secret_key_t *client_auth_sk = NULL;
1966 :
1967 18 : tor_assert(desc_str);
1968 18 : tor_assert(service_identity_pk);
1969 18 : tor_assert(desc);
1970 :
1971 : /* Check if we have a client authorization for this service in the map. */
1972 18 : client_auth = find_client_auth(service_identity_pk);
1973 18 : if (client_auth) {
1974 3 : client_auth_sk = &client_auth->enc_seckey;
1975 : }
1976 :
1977 : /* Create subcredential for this HS so that we can decrypt */
1978 : {
1979 18 : uint64_t current_time_period = hs_get_time_period_num(0);
1980 18 : hs_build_blinded_pubkey(service_identity_pk, NULL, 0, current_time_period,
1981 : &blinded_pubkey);
1982 18 : hs_get_subcredential(service_identity_pk, &blinded_pubkey, &subcredential);
1983 : }
1984 :
1985 : /* Parse descriptor */
1986 18 : ret = hs_desc_decode_descriptor(desc_str, &subcredential,
1987 : client_auth_sk, desc);
1988 18 : memwipe(&subcredential, 0, sizeof(subcredential));
1989 18 : if (ret != HS_DESC_DECODE_OK) {
1990 7 : goto err;
1991 : }
1992 :
1993 : /* Make sure the descriptor signing key cross certifies with the computed
1994 : * blinded key. Without this validation, anyone knowing the subcredential
1995 : * and onion address can forge a descriptor. */
1996 11 : tor_cert_t *cert = (*desc)->plaintext_data.signing_key_cert;
1997 11 : if (tor_cert_checksig(cert,
1998 : &blinded_pubkey, approx_time()) < 0) {
1999 0 : log_warn(LD_GENERAL, "Descriptor signing key certificate signature "
2000 : "doesn't validate with computed blinded key: %s",
2001 : tor_cert_describe_signature_status(cert));
2002 0 : ret = HS_DESC_DECODE_GENERIC_ERROR;
2003 0 : goto err;
2004 : }
2005 :
2006 : return HS_DESC_DECODE_OK;
2007 : err:
2008 : return ret;
2009 : }
2010 :
2011 : /** Return true iff there are at least one usable intro point in the service
2012 : * descriptor desc. */
2013 : int
2014 71 : hs_client_any_intro_points_usable(const ed25519_public_key_t *service_pk,
2015 : const hs_descriptor_t *desc)
2016 : {
2017 71 : tor_assert(service_pk);
2018 71 : tor_assert(desc);
2019 :
2020 91 : SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
2021 : const hs_desc_intro_point_t *, ip) {
2022 86 : if (intro_point_is_usable(service_pk, ip)) {
2023 66 : goto usable;
2024 : }
2025 20 : } SMARTLIST_FOREACH_END(ip);
2026 :
2027 : return 0;
2028 66 : usable:
2029 66 : return 1;
2030 : }
2031 :
2032 : /** Launch a connection to a hidden service directory to fetch a hidden
2033 : * service descriptor using <b>identity_pk</b> to get the necessary keys.
2034 : *
2035 : * A hs_client_fetch_status_t code is returned. */
2036 : int
2037 6 : hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
2038 : {
2039 6 : hs_client_fetch_status_t status;
2040 :
2041 6 : tor_assert(identity_pk);
2042 :
2043 6 : if (!can_client_refetch_desc(identity_pk, &status)) {
2044 5 : return status;
2045 : }
2046 :
2047 : /* Try to fetch the desc and if we encounter an unrecoverable error, mark
2048 : * the desc as unavailable for now. */
2049 1 : status = fetch_v3_desc(identity_pk);
2050 1 : if (fetch_status_should_close_socks(status)) {
2051 1 : close_all_socks_conns_waiting_for_desc(identity_pk, status,
2052 : END_STREAM_REASON_RESOLVEFAILED);
2053 : /* Remove HSDir fetch attempts so that we can retry later if the user
2054 : * wants us to regardless of if we closed any connections. */
2055 1 : purge_hid_serv_request(identity_pk);
2056 : }
2057 : return status;
2058 : }
2059 :
2060 : /** This is called when we are trying to attach an AP connection to these
2061 : * hidden service circuits from connection_ap_handshake_attach_circuit().
2062 : * Return 0 on success, -1 for a transient error that is actions were
2063 : * triggered to recover or -2 for a permenent error where both circuits will
2064 : * marked for close.
2065 : *
2066 : * The following supports every hidden service version. */
2067 : int
2068 0 : hs_client_send_introduce1(origin_circuit_t *intro_circ,
2069 : origin_circuit_t *rend_circ)
2070 : {
2071 0 : return send_introduce1(intro_circ, rend_circ);
2072 : }
2073 :
2074 : /** Called when the client circuit circ has been established. It can be either
2075 : * an introduction or rendezvous circuit. This function handles all hidden
2076 : * service versions. */
2077 : void
2078 0 : hs_client_circuit_has_opened(origin_circuit_t *circ)
2079 : {
2080 0 : tor_assert(circ);
2081 :
2082 0 : switch (TO_CIRCUIT(circ)->purpose) {
2083 0 : case CIRCUIT_PURPOSE_C_INTRODUCING:
2084 0 : if (circ->hs_ident) {
2085 0 : client_intro_circ_has_opened(circ);
2086 : }
2087 : break;
2088 0 : case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
2089 0 : if (circ->hs_ident) {
2090 0 : client_rendezvous_circ_has_opened(circ);
2091 : }
2092 : break;
2093 0 : default:
2094 0 : tor_assert_nonfatal_unreached();
2095 : }
2096 0 : }
2097 :
2098 : /** Called when we receive a RENDEZVOUS_ESTABLISHED cell. Change the state of
2099 : * the circuit to CIRCUIT_PURPOSE_C_REND_READY. Return 0 on success else a
2100 : * negative value and the circuit marked for close. */
2101 : int
2102 1 : hs_client_receive_rendezvous_acked(origin_circuit_t *circ,
2103 : const uint8_t *payload, size_t payload_len)
2104 : {
2105 1 : tor_assert(circ);
2106 1 : tor_assert(payload);
2107 :
2108 1 : (void) payload_len;
2109 :
2110 1 : if (TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_ESTABLISH_REND) {
2111 0 : log_warn(LD_PROTOCOL, "Got a RENDEZVOUS_ESTABLISHED but we were not "
2112 : "expecting one. Closing circuit.");
2113 0 : goto err;
2114 : }
2115 :
2116 1 : log_info(LD_REND, "Received an RENDEZVOUS_ESTABLISHED. This circuit is "
2117 : "now ready for rendezvous.");
2118 1 : circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_REND_READY);
2119 :
2120 : /* Set timestamp_dirty, because circuit_expire_building expects it to
2121 : * specify when a circuit entered the _C_REND_READY state. */
2122 1 : TO_CIRCUIT(circ)->timestamp_dirty = time(NULL);
2123 :
2124 : /* From a path bias point of view, this circuit is now successfully used.
2125 : * Waiting any longer opens us up to attacks from malicious hidden services.
2126 : * They could induce the client to attempt to connect to their hidden
2127 : * service and never reply to the client's rend requests */
2128 1 : pathbias_mark_use_success(circ);
2129 :
2130 : /* If we already have the introduction circuit built, make sure we send
2131 : * the INTRODUCE cell _now_ */
2132 1 : connection_ap_attach_pending(1);
2133 :
2134 1 : return 0;
2135 0 : err:
2136 0 : circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
2137 0 : return -1;
2138 : }
2139 :
2140 : void
2141 27 : client_service_authorization_free_(hs_client_service_authorization_t *auth)
2142 : {
2143 27 : if (!auth) {
2144 : return;
2145 : }
2146 :
2147 21 : tor_free(auth->client_name);
2148 :
2149 21 : memwipe(auth, 0, sizeof(*auth));
2150 21 : tor_free(auth);
2151 : }
2152 :
2153 : /** Helper for digest256map_free. */
2154 : static void
2155 8 : client_service_authorization_free_void(void *auth)
2156 : {
2157 8 : client_service_authorization_free_(auth);
2158 8 : }
2159 :
2160 : static void
2161 289 : client_service_authorization_free_all(void)
2162 : {
2163 289 : if (!client_auths) {
2164 : return;
2165 : }
2166 11 : digest256map_free(client_auths, client_service_authorization_free_void);
2167 : }
2168 :
2169 : /** Check if the auth key file name is valid or not. Return 1 if valid,
2170 : * otherwise return 0. */
2171 : STATIC int
2172 12 : auth_key_filename_is_valid(const char *filename)
2173 : {
2174 12 : int ret = 1;
2175 12 : const char *valid_extension = ".auth_private";
2176 :
2177 12 : tor_assert(filename);
2178 :
2179 : /* The length of the filename must be greater than the length of the
2180 : * extension and the valid extension must be at the end of filename. */
2181 12 : if (!strcmpend(filename, valid_extension) &&
2182 9 : strlen(filename) != strlen(valid_extension)) {
2183 : ret = 1;
2184 : } else {
2185 4 : ret = 0;
2186 : }
2187 :
2188 12 : return ret;
2189 : }
2190 :
2191 : /** Parse the client auth credentials off a string in <b>client_key_str</b>
2192 : * based on the file format documented in the "Client side configuration"
2193 : * section of rend-spec-v3.txt.
2194 : *
2195 : * Return NULL if there was an error, otherwise return a newly allocated
2196 : * hs_client_service_authorization_t structure.
2197 : */
2198 : STATIC hs_client_service_authorization_t *
2199 13 : parse_auth_file_content(const char *client_key_str)
2200 : {
2201 13 : char *onion_address = NULL;
2202 13 : char *auth_type = NULL;
2203 13 : char *key_type = NULL;
2204 13 : char *seckey_b32 = NULL;
2205 13 : hs_client_service_authorization_t *auth = NULL;
2206 13 : smartlist_t *fields = smartlist_new();
2207 :
2208 13 : tor_assert(client_key_str);
2209 :
2210 13 : smartlist_split_string(fields, client_key_str, ":",
2211 : SPLIT_SKIP_SPACE, 0);
2212 : /* Wrong number of fields. */
2213 13 : if (smartlist_len(fields) != 4) {
2214 1 : goto err;
2215 : }
2216 :
2217 12 : onion_address = smartlist_get(fields, 0);
2218 12 : auth_type = smartlist_get(fields, 1);
2219 12 : key_type = smartlist_get(fields, 2);
2220 12 : seckey_b32 = smartlist_get(fields, 3);
2221 :
2222 : /* Currently, the only supported auth type is "descriptor" and the only
2223 : * supported key type is "x25519". */
2224 12 : if (strcmp(auth_type, "descriptor") || strcmp(key_type, "x25519")) {
2225 2 : goto err;
2226 : }
2227 :
2228 10 : if (strlen(seckey_b32) != BASE32_NOPAD_LEN(CURVE25519_SECKEY_LEN)) {
2229 2 : log_warn(LD_REND, "Client authorization encoded base32 private key "
2230 : "length is invalid: %s", seckey_b32);
2231 2 : goto err;
2232 : }
2233 :
2234 8 : auth = tor_malloc_zero(sizeof(hs_client_service_authorization_t));
2235 8 : if (base32_decode((char *) auth->enc_seckey.secret_key,
2236 : sizeof(auth->enc_seckey.secret_key),
2237 : seckey_b32, strlen(seckey_b32)) !=
2238 : sizeof(auth->enc_seckey.secret_key)) {
2239 0 : log_warn(LD_REND, "Client authorization encoded base32 private key "
2240 : "can't be decoded: %s", seckey_b32);
2241 0 : goto err;
2242 : }
2243 :
2244 8 : if (fast_mem_is_zero((const char*)auth->enc_seckey.secret_key,
2245 : sizeof(auth->enc_seckey.secret_key))) {
2246 1 : log_warn(LD_REND, "Client authorization private key can't be all-zeroes");
2247 1 : goto err;
2248 : }
2249 :
2250 7 : strncpy(auth->onion_address, onion_address, HS_SERVICE_ADDR_LEN_BASE32);
2251 :
2252 : /* We are reading this from the disk, so set the permanent flag anyway. */
2253 7 : auth->flags |= CLIENT_AUTH_FLAG_IS_PERMANENT;
2254 :
2255 : /* Success. */
2256 7 : goto done;
2257 :
2258 6 : err:
2259 6 : client_service_authorization_free(auth);
2260 13 : done:
2261 : /* It is also a good idea to wipe the private key. */
2262 13 : if (seckey_b32) {
2263 12 : memwipe(seckey_b32, 0, strlen(seckey_b32));
2264 : }
2265 13 : tor_assert(fields);
2266 63 : SMARTLIST_FOREACH(fields, char *, s, tor_free(s));
2267 13 : smartlist_free(fields);
2268 13 : return auth;
2269 : }
2270 :
2271 : /** From a set of <b>options</b>, setup every client authorization detail
2272 : * found. Return 0 on success or -1 on failure. If <b>validate_only</b>
2273 : * is set, parse, warn and return as normal, but don't actually change
2274 : * the configuration. */
2275 : int
2276 436 : hs_config_client_authorization(const or_options_t *options,
2277 : int validate_only)
2278 : {
2279 436 : int ret = -1;
2280 436 : digest256map_t *auths = digest256map_new();
2281 436 : smartlist_t *file_list = NULL;
2282 :
2283 436 : tor_assert(options);
2284 :
2285 : /* There is no client auth configured. We can just silently ignore this
2286 : * function. */
2287 436 : if (!options->ClientOnionAuthDir) {
2288 433 : ret = 0;
2289 433 : goto end;
2290 : }
2291 :
2292 : /* Make sure the directory exists and is private enough. */
2293 3 : if (check_private_dir(options->ClientOnionAuthDir, 0, options->User) < 0) {
2294 0 : goto end;
2295 : }
2296 :
2297 3 : file_list = tor_listdir(options->ClientOnionAuthDir);
2298 3 : if (file_list == NULL) {
2299 0 : log_warn(LD_REND, "Client authorization key directory %s can't be listed.",
2300 : options->ClientOnionAuthDir);
2301 0 : goto end;
2302 : }
2303 :
2304 10 : SMARTLIST_FOREACH_BEGIN(file_list, const char *, filename) {
2305 7 : hs_client_service_authorization_t *auth = NULL;
2306 7 : ed25519_public_key_t identity_pk;
2307 :
2308 7 : auth = get_creds_from_client_auth_filename(filename, options);
2309 7 : if (!auth) {
2310 2 : continue;
2311 : }
2312 :
2313 : /* Parse the onion address to get an identity public key and use it
2314 : * as a key of global map in the future. */
2315 5 : if (hs_parse_address(auth->onion_address, &identity_pk,
2316 : NULL, NULL) < 0) {
2317 0 : log_warn(LD_REND, "The onion address \"%s\" is invalid in "
2318 : "file %s", filename, auth->onion_address);
2319 0 : client_service_authorization_free(auth);
2320 0 : continue;
2321 : }
2322 :
2323 5 : if (digest256map_get(auths, identity_pk.pubkey)) {
2324 0 : log_warn(LD_REND, "Duplicate authorization for the same hidden "
2325 : "service address %s.",
2326 : safe_str_client_opts(options, auth->onion_address));
2327 0 : client_service_authorization_free(auth);
2328 0 : goto end;
2329 : }
2330 :
2331 5 : digest256map_set(auths, identity_pk.pubkey, auth);
2332 5 : log_info(LD_REND, "Loaded a client authorization key file %s.",
2333 : filename);
2334 7 : } SMARTLIST_FOREACH_END(filename);
2335 :
2336 : /* Success. */
2337 : ret = 0;
2338 :
2339 3 : end:
2340 436 : if (file_list) {
2341 10 : SMARTLIST_FOREACH(file_list, char *, s, tor_free(s));
2342 3 : smartlist_free(file_list);
2343 : }
2344 :
2345 436 : if (!validate_only && ret == 0) {
2346 7 : client_service_authorization_free_all();
2347 7 : client_auths = auths;
2348 : } else {
2349 429 : digest256map_free(auths, client_service_authorization_free_void);
2350 : }
2351 :
2352 436 : return ret;
2353 : }
2354 :
2355 : /** Called when a descriptor directory fetch is done.
2356 : *
2357 : * Act accordingly on all entry connections depending on the HTTP status code
2358 : * we got. In case of an error, the SOCKS error is set (if ExtendedErrors is
2359 : * set).
2360 : *
2361 : * The reason is a human readable string returned by the directory server
2362 : * which can describe the status of the request. The body is the response
2363 : * content, on 200 code it is the descriptor itself. Finally, the status_code
2364 : * is the HTTP code returned by the directory server. */
2365 : void
2366 6 : hs_client_dir_fetch_done(dir_connection_t *dir_conn, const char *reason,
2367 : const char *body, const int status_code)
2368 : {
2369 6 : smartlist_t *entry_conns;
2370 :
2371 6 : tor_assert(dir_conn);
2372 6 : tor_assert(body);
2373 :
2374 : /* Get all related entry connections. */
2375 6 : entry_conns = find_entry_conns(&dir_conn->hs_ident->identity_pk);
2376 :
2377 6 : switch (status_code) {
2378 6 : case 200:
2379 6 : client_dir_fetch_200(dir_conn, entry_conns, body);
2380 6 : break;
2381 0 : case 404:
2382 0 : client_dir_fetch_404(dir_conn, entry_conns);
2383 0 : break;
2384 0 : case 400:
2385 0 : client_dir_fetch_400(dir_conn, reason);
2386 0 : break;
2387 0 : default:
2388 0 : client_dir_fetch_unexpected(dir_conn, reason, status_code);
2389 0 : break;
2390 : }
2391 :
2392 : /* We don't have ownership of the objects in this list. */
2393 6 : smartlist_free(entry_conns);
2394 6 : }
2395 :
2396 : /** Return a newly allocated extend_info_t for a randomly chosen introduction
2397 : * point for the given edge connection identifier ident. Return NULL if we
2398 : * can't pick any usable introduction points. */
2399 : extend_info_t *
2400 0 : hs_client_get_random_intro_from_edge(const edge_connection_t *edge_conn)
2401 : {
2402 0 : tor_assert(edge_conn);
2403 :
2404 0 : return client_get_random_intro(&edge_conn->hs_ident->identity_pk);
2405 : }
2406 :
2407 : /** Called when get an INTRODUCE_ACK cell on the introduction circuit circ.
2408 : * Return 0 on success else a negative value is returned. The circuit will be
2409 : * closed or reuse to extend again to another intro point. */
2410 : int
2411 0 : hs_client_receive_introduce_ack(origin_circuit_t *circ,
2412 : const uint8_t *payload, size_t payload_len)
2413 : {
2414 0 : int ret = -1;
2415 :
2416 0 : tor_assert(circ);
2417 0 : tor_assert(payload);
2418 :
2419 0 : if (TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
2420 0 : log_warn(LD_PROTOCOL, "Unexpected INTRODUCE_ACK on circuit %u.",
2421 : (unsigned int) TO_CIRCUIT(circ)->n_circ_id);
2422 0 : circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
2423 0 : goto end;
2424 : }
2425 :
2426 0 : ret = handle_introduce_ack(circ, payload, payload_len);
2427 : /* For path bias: This circuit was used successfully. NACK or ACK counts. */
2428 0 : pathbias_mark_use_success(circ);
2429 :
2430 0 : end:
2431 0 : return ret;
2432 : }
2433 :
2434 : /** Called when get a RENDEZVOUS2 cell on the rendezvous circuit circ. Return
2435 : * 0 on success else a negative value is returned. The circuit will be closed
2436 : * on error. */
2437 : int
2438 0 : hs_client_receive_rendezvous2(origin_circuit_t *circ,
2439 : const uint8_t *payload, size_t payload_len)
2440 : {
2441 0 : int ret = -1;
2442 :
2443 0 : tor_assert(circ);
2444 0 : tor_assert(payload);
2445 :
2446 : /* Circuit can possibly be in both state because we could receive a
2447 : * RENDEZVOUS2 cell before the INTRODUCE_ACK has been received. */
2448 0 : if (TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_REND_READY &&
2449 : TO_CIRCUIT(circ)->purpose != CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) {
2450 0 : log_warn(LD_PROTOCOL, "Unexpected RENDEZVOUS2 cell on circuit %u. "
2451 : "Closing circuit.",
2452 : (unsigned int) TO_CIRCUIT(circ)->n_circ_id);
2453 0 : circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
2454 0 : goto end;
2455 : }
2456 :
2457 0 : log_info(LD_REND, "Got RENDEZVOUS2 cell from hidden service on circuit %u.",
2458 : TO_CIRCUIT(circ)->n_circ_id);
2459 :
2460 0 : ret = handle_rendezvous2(circ, payload, payload_len);
2461 :
2462 0 : end:
2463 0 : return ret;
2464 : }
2465 :
2466 : /** Extend the introduction circuit circ to another valid introduction point
2467 : * for the hidden service it is trying to connect to, or mark it and launch a
2468 : * new circuit if we can't extend it. Return 0 on success or possible
2469 : * success. Return -1 and mark the introduction circuit for close on permanent
2470 : * failure.
2471 : *
2472 : * On failure, the caller is responsible for marking the associated rendezvous
2473 : * circuit for close. */
2474 : int
2475 0 : hs_client_reextend_intro_circuit(origin_circuit_t *circ)
2476 : {
2477 0 : int ret = -1;
2478 0 : extend_info_t *ei;
2479 :
2480 0 : tor_assert(circ);
2481 :
2482 0 : ei = client_get_random_intro(&circ->hs_ident->identity_pk);
2483 0 : if (ei == NULL) {
2484 0 : log_warn(LD_REND, "No usable introduction points left. Closing.");
2485 0 : circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
2486 0 : goto end;
2487 : }
2488 :
2489 0 : if (circ->remaining_relay_early_cells) {
2490 0 : log_info(LD_REND, "Re-extending circ %u, this time to %s.",
2491 : (unsigned int) TO_CIRCUIT(circ)->n_circ_id,
2492 : safe_str_client(extend_info_describe(ei)));
2493 0 : ret = circuit_extend_to_new_exit(circ, ei);
2494 0 : if (ret == 0) {
2495 : /* We were able to extend so update the timestamp so we avoid expiring
2496 : * this circuit too early. The intro circuit is short live so the
2497 : * linkability issue is minimized, we just need the circuit to hold a
2498 : * bit longer so we can introduce. */
2499 0 : TO_CIRCUIT(circ)->timestamp_dirty = time(NULL);
2500 : }
2501 : } else {
2502 0 : log_info(LD_REND, "Closing intro circ %u (out of RELAY_EARLY cells).",
2503 : (unsigned int) TO_CIRCUIT(circ)->n_circ_id);
2504 0 : circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
2505 : /* connection_ap_handshake_attach_circuit will launch a new intro circ. */
2506 0 : ret = 0;
2507 : }
2508 :
2509 0 : end:
2510 0 : extend_info_free(ei);
2511 0 : return ret;
2512 : }
2513 :
2514 : /** Close all client introduction circuits related to the given descriptor.
2515 : * This is called with a descriptor that is about to get replaced in the
2516 : * client cache.
2517 : *
2518 : * Even though the introduction point might be exactly the same, we'll rebuild
2519 : * them if needed but the odds are very low that an existing matching
2520 : * introduction circuit exists at that stage. */
2521 : void
2522 4 : hs_client_close_intro_circuits_from_desc(const hs_descriptor_t *desc)
2523 : {
2524 4 : origin_circuit_t *ocirc = NULL;
2525 :
2526 4 : tor_assert(desc);
2527 :
2528 : /* We iterate over all client intro circuits because they aren't kept in the
2529 : * HS circuitmap. That is probably something we want to do one day. */
2530 6 : while ((ocirc = circuit_get_next_intro_circ(ocirc, true))) {
2531 2 : if (ocirc->hs_ident == NULL) {
2532 : /* Not a v3 circuit, ignore it. */
2533 0 : continue;
2534 : }
2535 :
2536 : /* Does it match any IP in the given descriptor? If not, ignore. */
2537 2 : if (find_desc_intro_point_by_ident(ocirc->hs_ident, desc) == NULL) {
2538 0 : continue;
2539 : }
2540 :
2541 : /* We have a match. Close the circuit as consider it expired. */
2542 2 : circuit_mark_for_close(TO_CIRCUIT(ocirc), END_CIRC_REASON_FINISHED);
2543 : }
2544 4 : }
2545 :
2546 : /** Release all the storage held by the client subsystem. */
2547 : void
2548 282 : hs_client_free_all(void)
2549 : {
2550 : /* Purge the hidden service request cache. */
2551 282 : hs_purge_last_hid_serv_requests();
2552 282 : client_service_authorization_free_all();
2553 282 : }
2554 :
2555 : /** Purge all potentially remotely-detectable state held in the hidden
2556 : * service client code. Called on SIGNAL NEWNYM. */
2557 : void
2558 0 : hs_client_purge_state(void)
2559 : {
2560 : /* Cancel all descriptor fetches. Do this first so once done we are sure
2561 : * that our descriptor cache won't modified. */
2562 0 : cancel_descriptor_fetches();
2563 : /* Purge the introduction point state cache. */
2564 0 : hs_cache_client_intro_state_purge();
2565 : /* Purge the descriptor cache. */
2566 0 : hs_cache_purge_as_client();
2567 : /* Purge the last hidden service request cache. */
2568 0 : hs_purge_last_hid_serv_requests();
2569 : /* Purge ephemeral client authorization. */
2570 0 : purge_ephemeral_client_auth();
2571 :
2572 0 : log_info(LD_REND, "Hidden service client state has been purged.");
2573 0 : }
2574 :
2575 : /** Called when our directory information has changed. */
2576 : void
2577 45174 : hs_client_dir_info_changed(void)
2578 : {
2579 : /* We have possibly reached the minimum directory information or new
2580 : * consensus so retry all pending SOCKS connection in
2581 : * AP_CONN_STATE_RENDDESC_WAIT state in order to fetch the descriptor. */
2582 45174 : retry_all_socks_conn_waiting_for_desc();
2583 45174 : }
2584 :
2585 : #ifdef TOR_UNIT_TESTS
2586 :
2587 : STATIC void
2588 1 : set_hs_client_auths_map(digest256map_t *map)
2589 : {
2590 1 : client_auths = map;
2591 1 : }
2592 :
2593 : #endif /* defined(TOR_UNIT_TESTS) */
|