1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2 * Copyright (c) 2007-2013, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
7 * \brief The hidden-service side of rendezvous functionality.
10 #define RENDSERVICE_PRIVATE
13 #include "circuitbuild.h"
14 #include "circuitlist.h"
15 #include "circuituse.h"
17 #include "directory.h"
18 #include "networkstatus.h"
20 #include "rendclient.h"
21 #include "rendcommon.h"
22 #include "rendservice.h"
26 #include "replaycache.h"
27 #include "routerlist.h"
28 #include "routerparse.h"
29 #include "routerset.h"
31 static origin_circuit_t
*find_intro_circuit(rend_intro_point_t
*intro
,
32 const char *pk_digest
);
33 static rend_intro_point_t
*find_intro_point(origin_circuit_t
*circ
);
35 static extend_info_t
*find_rp_for_intro(
36 const rend_intro_cell_t
*intro
,
37 uint8_t *need_free_out
, char **err_msg_out
);
39 static int intro_point_accepted_intro_count(rend_intro_point_t
*intro
);
40 static int intro_point_should_expire_now(rend_intro_point_t
*intro
,
42 struct rend_service_t
;
43 static int rend_service_load_keys(struct rend_service_t
*s
);
44 static int rend_service_load_auth_keys(struct rend_service_t
*s
,
47 static ssize_t
rend_service_parse_intro_for_v0_or_v1(
48 rend_intro_cell_t
*intro
,
52 static ssize_t
rend_service_parse_intro_for_v2(
53 rend_intro_cell_t
*intro
,
57 static ssize_t
rend_service_parse_intro_for_v3(
58 rend_intro_cell_t
*intro
,
63 /** Represents the mapping from a virtual port of a rendezvous service to
64 * a real port on some IP.
66 typedef struct rend_service_port_config_t
{
67 uint16_t virtual_port
;
70 } rend_service_port_config_t
;
72 /** Try to maintain this many intro points per service by default. */
73 #define NUM_INTRO_POINTS_DEFAULT 3
74 /** Maintain no more than this many intro points per hidden service. */
75 #define NUM_INTRO_POINTS_MAX 10
77 /** If we can't build our intro circuits, don't retry for this long. */
78 #define INTRO_CIRC_RETRY_PERIOD (60*5)
79 /** Don't try to build more than this many circuits before giving up
81 #define MAX_INTRO_CIRCS_PER_PERIOD 10
82 /** How many times will a hidden service operator attempt to connect to
83 * a requested rendezvous point before giving up? */
84 #define MAX_REND_FAILURES 30
85 /** How many seconds should we spend trying to connect to a requested
86 * rendezvous point before giving up? */
87 #define MAX_REND_TIMEOUT 30
89 /** How many seconds should we wait for new HS descriptors to reach
90 * our clients before we close an expiring intro point? */
91 #define INTRO_POINT_EXPIRATION_GRACE_PERIOD (5*60)
93 /** Represents a single hidden service running at this OP. */
94 typedef struct rend_service_t
{
95 /* Fields specified in config file */
96 char *directory
; /**< where in the filesystem it stores it */
97 smartlist_t
*ports
; /**< List of rend_service_port_config_t */
98 rend_auth_type_t auth_type
; /**< Client authorization type or 0 if no client
99 * authorization is performed. */
100 smartlist_t
*clients
; /**< List of rend_authorized_client_t's of
101 * clients that may access our service. Can be NULL
102 * if no client authorization is performed. */
104 crypto_pk_t
*private_key
; /**< Permanent hidden-service key. */
105 char service_id
[REND_SERVICE_ID_LEN_BASE32
+1]; /**< Onion address without
107 char pk_digest
[DIGEST_LEN
]; /**< Hash of permanent hidden-service key. */
108 smartlist_t
*intro_nodes
; /**< List of rend_intro_point_t's we have,
109 * or are trying to establish. */
110 time_t intro_period_started
; /**< Start of the current period to build
111 * introduction points. */
112 int n_intro_circuits_launched
; /**< Count of intro circuits we have
113 * established in this period. */
114 unsigned int n_intro_points_wanted
; /**< Number of intro points this
115 * service wants to have open. */
116 rend_service_descriptor_t
*desc
; /**< Current hidden service descriptor. */
117 time_t desc_is_dirty
; /**< Time at which changes to the hidden service
118 * descriptor content occurred, or 0 if it's
120 time_t next_upload_time
; /**< Scheduled next hidden service descriptor
122 /** Replay cache for Diffie-Hellman values of INTRODUCE2 cells, to
123 * detect repeats. Clients may send INTRODUCE1 cells for the same
124 * rendezvous point through two or more different introduction points;
125 * when they do, this keeps us from launching multiple simultaneous attempts
126 * to connect to the same rend point. */
127 replaycache_t
*accepted_intro_dh_parts
;
130 /** A list of rend_service_t's for services run on this OP.
132 static smartlist_t
*rend_service_list
= NULL
;
134 /** Return the number of rendezvous services we have configured. */
136 num_rend_services(void)
138 if (!rend_service_list
)
140 return smartlist_len(rend_service_list
);
143 /** Return a string identifying <b>service</b>, suitable for use in a
144 * log message. The result does not need to be freed, but may be
145 * overwritten by the next call to this function. */
147 rend_service_describe_for_log(rend_service_t
*service
)
149 /* XXX024 Use this function throughout rendservice.c. */
150 /* XXX024 Return a more useful description? */
151 return safe_str_client(service
->service_id
);
154 /** Helper: free storage held by a single service authorized client entry. */
156 rend_authorized_client_free(rend_authorized_client_t
*client
)
160 if (client
->client_key
)
161 crypto_pk_free(client
->client_key
);
162 tor_strclear(client
->client_name
);
163 tor_free(client
->client_name
);
164 memwipe(client
->descriptor_cookie
, 0, sizeof(client
->descriptor_cookie
));
168 /** Helper for strmap_free. */
170 rend_authorized_client_strmap_item_free(void *authorized_client
)
172 rend_authorized_client_free(authorized_client
);
175 /** Release the storage held by <b>service</b>.
178 rend_service_free(rend_service_t
*service
)
183 tor_free(service
->directory
);
184 SMARTLIST_FOREACH(service
->ports
, void*, p
, tor_free(p
));
185 smartlist_free(service
->ports
);
186 if (service
->private_key
)
187 crypto_pk_free(service
->private_key
);
188 if (service
->intro_nodes
) {
189 SMARTLIST_FOREACH(service
->intro_nodes
, rend_intro_point_t
*, intro
,
190 rend_intro_point_free(intro
););
191 smartlist_free(service
->intro_nodes
);
194 rend_service_descriptor_free(service
->desc
);
195 if (service
->clients
) {
196 SMARTLIST_FOREACH(service
->clients
, rend_authorized_client_t
*, c
,
197 rend_authorized_client_free(c
););
198 smartlist_free(service
->clients
);
200 if (service
->accepted_intro_dh_parts
) {
201 replaycache_free(service
->accepted_intro_dh_parts
);
206 /** Release all the storage held in rend_service_list.
209 rend_service_free_all(void)
211 if (!rend_service_list
)
214 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, ptr
,
215 rend_service_free(ptr
));
216 smartlist_free(rend_service_list
);
217 rend_service_list
= NULL
;
220 /** Validate <b>service</b> and add it to rend_service_list if possible.
223 rend_add_service(rend_service_t
*service
)
226 rend_service_port_config_t
*p
;
228 service
->intro_nodes
= smartlist_new();
230 if (service
->auth_type
!= REND_NO_AUTH
&&
231 smartlist_len(service
->clients
) == 0) {
232 log_warn(LD_CONFIG
, "Hidden service (%s) with client authorization but no "
233 "clients; ignoring.",
234 escaped(service
->directory
));
235 rend_service_free(service
);
239 if (!smartlist_len(service
->ports
)) {
240 log_warn(LD_CONFIG
, "Hidden service (%s) with no ports configured; "
242 escaped(service
->directory
));
243 rend_service_free(service
);
246 /* XXX This duplicate check has two problems:
248 * a) It's O(n^2), but the same comment from the bottom of
249 * rend_config_services() should apply.
251 * b) We only compare directory paths as strings, so we can't
252 * detect two distinct paths that specify the same directory
253 * (which can arise from symlinks, case-insensitivity, bind
256 * It also can't detect that two separate Tor instances are trying
257 * to use the same HiddenServiceDir; for that, we would need a
258 * lock file. But this is enough to detect a simple mistake that
259 * at least one person has actually made.
261 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, ptr
,
263 !strcmp(ptr
->directory
, service
->directory
));
265 log_warn(LD_REND
, "Another hidden service is already configured for "
266 "directory %s, ignoring.", service
->directory
);
267 rend_service_free(service
);
270 smartlist_add(rend_service_list
, service
);
271 log_debug(LD_REND
,"Configuring service with directory \"%s\"",
273 for (i
= 0; i
< smartlist_len(service
->ports
); ++i
) {
274 p
= smartlist_get(service
->ports
, i
);
275 log_debug(LD_REND
,"Service maps port %d to %s",
276 p
->virtual_port
, fmt_addrport(&p
->real_addr
, p
->real_port
));
281 /** Parses a real-port to virtual-port mapping and returns a new
282 * rend_service_port_config_t.
284 * The format is: VirtualPort (IP|RealPort|IP:RealPort)?
286 * IP defaults to 127.0.0.1; RealPort defaults to VirtualPort.
288 static rend_service_port_config_t
*
289 parse_port_config(const char *string
)
296 const char *addrport
;
297 rend_service_port_config_t
*result
= NULL
;
299 sl
= smartlist_new();
300 smartlist_split_string(sl
, string
, " ",
301 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
302 if (smartlist_len(sl
) < 1 || smartlist_len(sl
) > 2) {
303 log_warn(LD_CONFIG
, "Bad syntax in hidden service port configuration.");
307 virtport
= (int)tor_parse_long(smartlist_get(sl
,0), 10, 1, 65535, NULL
,NULL
);
309 log_warn(LD_CONFIG
, "Missing or invalid port %s in hidden service port "
310 "configuration", escaped(smartlist_get(sl
,0)));
314 if (smartlist_len(sl
) == 1) {
315 /* No addr:port part; use default. */
317 tor_addr_from_ipv4h(&addr
, 0x7F000001u
); /* 127.0.0.1 */
319 addrport
= smartlist_get(sl
,1);
320 if (strchr(addrport
, ':') || strchr(addrport
, '.')) {
321 if (tor_addr_port_lookup(addrport
, &addr
, &p
)<0) {
322 log_warn(LD_CONFIG
,"Unparseable address in hidden service port "
326 realport
= p
?p
:virtport
;
328 /* No addr:port, no addr -- must be port. */
329 realport
= (int)tor_parse_long(addrport
, 10, 1, 65535, NULL
, NULL
);
331 log_warn(LD_CONFIG
,"Unparseable or out-of-range port %s in hidden "
332 "service port configuration.", escaped(addrport
));
335 tor_addr_from_ipv4h(&addr
, 0x7F000001u
); /* Default to 127.0.0.1 */
339 result
= tor_malloc(sizeof(rend_service_port_config_t
));
340 result
->virtual_port
= virtport
;
341 result
->real_port
= realport
;
342 tor_addr_copy(&result
->real_addr
, &addr
);
344 SMARTLIST_FOREACH(sl
, char *, c
, tor_free(c
));
349 /** Set up rend_service_list, based on the values of HiddenServiceDir and
350 * HiddenServicePort in <b>options</b>. Return 0 on success and -1 on
351 * failure. (If <b>validate_only</b> is set, parse, warn and return as
352 * normal, but don't actually change the configured services.)
355 rend_config_services(const or_options_t
*options
, int validate_only
)
358 rend_service_t
*service
= NULL
;
359 rend_service_port_config_t
*portcfg
;
360 smartlist_t
*old_service_list
= NULL
;
362 if (!validate_only
) {
363 old_service_list
= rend_service_list
;
364 rend_service_list
= smartlist_new();
367 for (line
= options
->RendConfigLines
; line
; line
= line
->next
) {
368 if (!strcasecmp(line
->key
, "HiddenServiceDir")) {
369 if (service
) { /* register the one we just finished parsing */
371 rend_service_free(service
);
373 rend_add_service(service
);
375 service
= tor_malloc_zero(sizeof(rend_service_t
));
376 service
->directory
= tor_strdup(line
->value
);
377 service
->ports
= smartlist_new();
378 service
->intro_period_started
= time(NULL
);
379 service
->n_intro_points_wanted
= NUM_INTRO_POINTS_DEFAULT
;
383 log_warn(LD_CONFIG
, "%s with no preceding HiddenServiceDir directive",
385 rend_service_free(service
);
388 if (!strcasecmp(line
->key
, "HiddenServicePort")) {
389 portcfg
= parse_port_config(line
->value
);
391 rend_service_free(service
);
394 smartlist_add(service
->ports
, portcfg
);
395 } else if (!strcasecmp(line
->key
, "HiddenServiceAuthorizeClient")) {
396 /* Parse auth type and comma-separated list of client names and add a
397 * rend_authorized_client_t for each client to the service's list
398 * of authorized clients. */
399 smartlist_t
*type_names_split
, *clients
;
400 const char *authname
;
402 if (service
->auth_type
!= REND_NO_AUTH
) {
403 log_warn(LD_CONFIG
, "Got multiple HiddenServiceAuthorizeClient "
404 "lines for a single service.");
405 rend_service_free(service
);
408 type_names_split
= smartlist_new();
409 smartlist_split_string(type_names_split
, line
->value
, " ", 0, 2);
410 if (smartlist_len(type_names_split
) < 1) {
411 log_warn(LD_BUG
, "HiddenServiceAuthorizeClient has no value. This "
412 "should have been prevented when parsing the "
414 smartlist_free(type_names_split
);
415 rend_service_free(service
);
418 authname
= smartlist_get(type_names_split
, 0);
419 if (!strcasecmp(authname
, "basic")) {
420 service
->auth_type
= REND_BASIC_AUTH
;
421 } else if (!strcasecmp(authname
, "stealth")) {
422 service
->auth_type
= REND_STEALTH_AUTH
;
424 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains "
425 "unrecognized auth-type '%s'. Only 'basic' or 'stealth' "
427 (char *) smartlist_get(type_names_split
, 0));
428 SMARTLIST_FOREACH(type_names_split
, char *, cp
, tor_free(cp
));
429 smartlist_free(type_names_split
);
430 rend_service_free(service
);
433 service
->clients
= smartlist_new();
434 if (smartlist_len(type_names_split
) < 2) {
435 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains "
436 "auth-type '%s', but no client names.",
437 service
->auth_type
== REND_BASIC_AUTH
? "basic" : "stealth");
438 SMARTLIST_FOREACH(type_names_split
, char *, cp
, tor_free(cp
));
439 smartlist_free(type_names_split
);
442 clients
= smartlist_new();
443 smartlist_split_string(clients
, smartlist_get(type_names_split
, 1),
444 ",", SPLIT_SKIP_SPACE
, 0);
445 SMARTLIST_FOREACH(type_names_split
, char *, cp
, tor_free(cp
));
446 smartlist_free(type_names_split
);
447 /* Remove duplicate client names. */
448 num_clients
= smartlist_len(clients
);
449 smartlist_sort_strings(clients
);
450 smartlist_uniq_strings(clients
);
451 if (smartlist_len(clients
) < num_clients
) {
452 log_info(LD_CONFIG
, "HiddenServiceAuthorizeClient contains %d "
453 "duplicate client name(s); removing.",
454 num_clients
- smartlist_len(clients
));
455 num_clients
= smartlist_len(clients
);
457 SMARTLIST_FOREACH_BEGIN(clients
, const char *, client_name
)
459 rend_authorized_client_t
*client
;
460 size_t len
= strlen(client_name
);
461 if (len
< 1 || len
> REND_CLIENTNAME_MAX_LEN
) {
462 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains an "
463 "illegal client name: '%s'. Length must be "
464 "between 1 and %d characters.",
465 client_name
, REND_CLIENTNAME_MAX_LEN
);
466 SMARTLIST_FOREACH(clients
, char *, cp
, tor_free(cp
));
467 smartlist_free(clients
);
468 rend_service_free(service
);
471 if (strspn(client_name
, REND_LEGAL_CLIENTNAME_CHARACTERS
) != len
) {
472 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains an "
473 "illegal client name: '%s'. Valid "
474 "characters are [A-Za-z0-9+_-].",
476 SMARTLIST_FOREACH(clients
, char *, cp
, tor_free(cp
));
477 smartlist_free(clients
);
478 rend_service_free(service
);
481 client
= tor_malloc_zero(sizeof(rend_authorized_client_t
));
482 client
->client_name
= tor_strdup(client_name
);
483 smartlist_add(service
->clients
, client
);
484 log_debug(LD_REND
, "Adding client name '%s'", client_name
);
486 SMARTLIST_FOREACH_END(client_name
);
487 SMARTLIST_FOREACH(clients
, char *, cp
, tor_free(cp
));
488 smartlist_free(clients
);
489 /* Ensure maximum number of clients. */
490 if ((service
->auth_type
== REND_BASIC_AUTH
&&
491 smartlist_len(service
->clients
) > 512) ||
492 (service
->auth_type
== REND_STEALTH_AUTH
&&
493 smartlist_len(service
->clients
) > 16)) {
494 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains %d "
495 "client authorization entries, but only a "
496 "maximum of %d entries is allowed for "
497 "authorization type '%s'.",
498 smartlist_len(service
->clients
),
499 service
->auth_type
== REND_BASIC_AUTH
? 512 : 16,
500 service
->auth_type
== REND_BASIC_AUTH
? "basic" : "stealth");
501 rend_service_free(service
);
505 tor_assert(!strcasecmp(line
->key
, "HiddenServiceVersion"));
506 if (strcmp(line
->value
, "2")) {
508 "The only supported HiddenServiceVersion is 2.");
509 rend_service_free(service
);
516 rend_service_free(service
);
518 rend_add_service(service
);
521 /* If this is a reload and there were hidden services configured before,
522 * keep the introduction points that are still needed and close the
524 if (old_service_list
&& !validate_only
) {
525 smartlist_t
*surviving_services
= smartlist_new();
528 /* Copy introduction points to new services. */
529 /* XXXX This is O(n^2), but it's only called on reconfigure, so it's
531 SMARTLIST_FOREACH_BEGIN(rend_service_list
, rend_service_t
*, new) {
532 SMARTLIST_FOREACH_BEGIN(old_service_list
, rend_service_t
*, old
) {
533 if (!strcmp(old
->directory
, new->directory
)) {
534 smartlist_add_all(new->intro_nodes
, old
->intro_nodes
);
535 smartlist_clear(old
->intro_nodes
);
536 smartlist_add(surviving_services
, old
);
539 } SMARTLIST_FOREACH_END(old
);
540 } SMARTLIST_FOREACH_END(new);
542 /* Close introduction circuits of services we don't serve anymore. */
543 /* XXXX it would be nicer if we had a nicer abstraction to use here,
544 * so we could just iterate over the list of services to close, but
545 * once again, this isn't critical-path code. */
546 TOR_LIST_FOREACH(circ
, circuit_get_global_list(), head
) {
547 if (!circ
->marked_for_close
&&
548 circ
->state
== CIRCUIT_STATE_OPEN
&&
549 (circ
->purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
||
550 circ
->purpose
== CIRCUIT_PURPOSE_S_INTRO
)) {
551 origin_circuit_t
*oc
= TO_ORIGIN_CIRCUIT(circ
);
553 tor_assert(oc
->rend_data
);
554 SMARTLIST_FOREACH(surviving_services
, rend_service_t
*, ptr
, {
555 if (tor_memeq(ptr
->pk_digest
, oc
->rend_data
->rend_pk_digest
,
563 log_info(LD_REND
, "Closing intro point %s for service %s.",
564 safe_str_client(extend_info_describe(
565 oc
->build_state
->chosen_exit
)),
566 oc
->rend_data
->onion_address
);
567 circuit_mark_for_close(circ
, END_CIRC_REASON_FINISHED
);
568 /* XXXX Is there another reason we should use here? */
571 smartlist_free(surviving_services
);
572 SMARTLIST_FOREACH(old_service_list
, rend_service_t
*, ptr
,
573 rend_service_free(ptr
));
574 smartlist_free(old_service_list
);
580 /** Replace the old value of <b>service</b>-\>desc with one that reflects
581 * the other fields in service.
584 rend_service_update_descriptor(rend_service_t
*service
)
586 rend_service_descriptor_t
*d
;
587 origin_circuit_t
*circ
;
590 rend_service_descriptor_free(service
->desc
);
591 service
->desc
= NULL
;
593 d
= service
->desc
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
594 d
->pk
= crypto_pk_dup_key(service
->private_key
);
595 d
->timestamp
= time(NULL
);
596 d
->timestamp
-= d
->timestamp
% 3600; /* Round down to nearest hour */
597 d
->intro_nodes
= smartlist_new();
598 /* Support intro protocols 2 and 3. */
599 d
->protocols
= (1 << 2) + (1 << 3);
601 for (i
= 0; i
< smartlist_len(service
->intro_nodes
); ++i
) {
602 rend_intro_point_t
*intro_svc
= smartlist_get(service
->intro_nodes
, i
);
603 rend_intro_point_t
*intro_desc
;
605 /* This intro point won't be listed in the descriptor... */
606 intro_svc
->listed_in_last_desc
= 0;
608 if (intro_svc
->time_expiring
!= -1) {
609 /* This intro point is expiring. Don't list it. */
613 circ
= find_intro_circuit(intro_svc
, service
->pk_digest
);
614 if (!circ
|| circ
->base_
.purpose
!= CIRCUIT_PURPOSE_S_INTRO
) {
615 /* This intro point's circuit isn't finished yet. Don't list it. */
619 /* ...unless this intro point is listed in the descriptor. */
620 intro_svc
->listed_in_last_desc
= 1;
622 /* We have an entirely established intro circuit. Publish it in
624 intro_desc
= tor_malloc_zero(sizeof(rend_intro_point_t
));
625 intro_desc
->extend_info
= extend_info_dup(intro_svc
->extend_info
);
626 if (intro_svc
->intro_key
)
627 intro_desc
->intro_key
= crypto_pk_dup_key(intro_svc
->intro_key
);
628 smartlist_add(d
->intro_nodes
, intro_desc
);
630 if (intro_svc
->time_published
== -1) {
631 /* We are publishing this intro point in a descriptor for the
632 * first time -- note the current time in the service's copy of
633 * the intro point. */
634 intro_svc
->time_published
= time(NULL
);
639 /** Load and/or generate private keys for all hidden services, possibly
640 * including keys for client authorization. Return 0 on success, -1 on
643 rend_service_load_all_keys(void)
645 SMARTLIST_FOREACH_BEGIN(rend_service_list
, rend_service_t
*, s
) {
648 log_info(LD_REND
, "Loading hidden-service keys from \"%s\"",
651 if (rend_service_load_keys(s
) < 0)
653 } SMARTLIST_FOREACH_END(s
);
658 /** Load and/or generate private keys for the hidden service <b>s</b>,
659 * possibly including keys for client authorization. Return 0 on success, -1
662 rend_service_load_keys(rend_service_t
*s
)
667 /* Check/create directory */
668 if (check_private_dir(s
->directory
, CPD_CREATE
, get_options()->User
) < 0)
672 if (strlcpy(fname
,s
->directory
,sizeof(fname
)) >= sizeof(fname
) ||
673 strlcat(fname
,PATH_SEPARATOR
"private_key",sizeof(fname
))
675 log_warn(LD_CONFIG
, "Directory name too long to store key file: \"%s\".",
679 s
->private_key
= init_key_from_file(fname
, 1, LOG_ERR
);
683 /* Create service file */
684 if (rend_get_service_id(s
->private_key
, s
->service_id
)<0) {
685 log_warn(LD_BUG
, "Internal error: couldn't encode service ID.");
688 if (crypto_pk_get_digest(s
->private_key
, s
->pk_digest
)<0) {
689 log_warn(LD_BUG
, "Couldn't compute hash of public key.");
692 if (strlcpy(fname
,s
->directory
,sizeof(fname
)) >= sizeof(fname
) ||
693 strlcat(fname
,PATH_SEPARATOR
"hostname",sizeof(fname
))
695 log_warn(LD_CONFIG
, "Directory name too long to store hostname file:"
696 " \"%s\".", s
->directory
);
700 tor_snprintf(buf
, sizeof(buf
),"%s.onion\n", s
->service_id
);
701 if (write_str_to_file(fname
,buf
,0)<0) {
702 log_warn(LD_CONFIG
, "Could not write onion address to hostname file.");
703 memwipe(buf
, 0, sizeof(buf
));
706 memwipe(buf
, 0, sizeof(buf
));
708 /* If client authorization is configured, load or generate keys. */
709 if (s
->auth_type
!= REND_NO_AUTH
) {
710 if (rend_service_load_auth_keys(s
, fname
) < 0)
717 /** Load and/or generate client authorization keys for the hidden service
718 * <b>s</b>, which stores its hostname in <b>hfname</b>. Return 0 on success,
721 rend_service_load_auth_keys(rend_service_t
*s
, const char *hfname
)
725 char *client_keys_str
= NULL
;
726 strmap_t
*parsed_clients
= strmap_new();
728 open_file_t
*open_cfile
= NULL
, *open_hfile
= NULL
;
729 char extended_desc_cookie
[REND_DESC_COOKIE_LEN
+1];
730 char desc_cook_out
[3*REND_DESC_COOKIE_LEN_BASE64
+1];
731 char service_id
[16+1];
734 /* Load client keys and descriptor cookies, if available. */
735 if (tor_snprintf(cfname
, sizeof(cfname
), "%s"PATH_SEPARATOR
"client_keys",
737 log_warn(LD_CONFIG
, "Directory name too long to store client keys "
738 "file: \"%s\".", s
->directory
);
741 client_keys_str
= read_file_to_str(cfname
, RFTS_IGNORE_MISSING
, NULL
);
742 if (client_keys_str
) {
743 if (rend_parse_client_keys(parsed_clients
, client_keys_str
) < 0) {
744 log_warn(LD_CONFIG
, "Previously stored client_keys file could not "
748 log_info(LD_CONFIG
, "Parsed %d previously stored client entries.",
749 strmap_size(parsed_clients
));
753 /* Prepare client_keys and hostname files. */
754 if (!(cfile
= start_writing_to_stdio_file(cfname
,
755 OPEN_FLAGS_REPLACE
| O_TEXT
,
756 0600, &open_cfile
))) {
757 log_warn(LD_CONFIG
, "Could not open client_keys file %s",
762 if (!(hfile
= start_writing_to_stdio_file(hfname
,
763 OPEN_FLAGS_REPLACE
| O_TEXT
,
764 0600, &open_hfile
))) {
765 log_warn(LD_CONFIG
, "Could not open hostname file %s", escaped(hfname
));
769 /* Either use loaded keys for configured clients or generate new
770 * ones if a client is new. */
771 SMARTLIST_FOREACH_BEGIN(s
->clients
, rend_authorized_client_t
*, client
) {
772 rend_authorized_client_t
*parsed
=
773 strmap_get(parsed_clients
, client
->client_name
);
776 /* Copy descriptor cookie from parsed entry or create new one. */
778 memcpy(client
->descriptor_cookie
, parsed
->descriptor_cookie
,
779 REND_DESC_COOKIE_LEN
);
781 crypto_rand(client
->descriptor_cookie
, REND_DESC_COOKIE_LEN
);
783 if (base64_encode(desc_cook_out
, 3*REND_DESC_COOKIE_LEN_BASE64
+1,
784 client
->descriptor_cookie
,
785 REND_DESC_COOKIE_LEN
) < 0) {
786 log_warn(LD_BUG
, "Could not base64-encode descriptor cookie.");
789 /* Copy client key from parsed entry or create new one if required. */
790 if (parsed
&& parsed
->client_key
) {
791 client
->client_key
= crypto_pk_dup_key(parsed
->client_key
);
792 } else if (s
->auth_type
== REND_STEALTH_AUTH
) {
793 /* Create private key for client. */
794 crypto_pk_t
*prkey
= NULL
;
795 if (!(prkey
= crypto_pk_new())) {
796 log_warn(LD_BUG
,"Error constructing client key");
799 if (crypto_pk_generate_key(prkey
)) {
800 log_warn(LD_BUG
,"Error generating client key");
801 crypto_pk_free(prkey
);
804 if (crypto_pk_check_key(prkey
) <= 0) {
805 log_warn(LD_BUG
,"Generated client key seems invalid");
806 crypto_pk_free(prkey
);
809 client
->client_key
= prkey
;
811 /* Add entry to client_keys file. */
812 desc_cook_out
[strlen(desc_cook_out
)-1] = '\0'; /* Remove newline. */
813 written
= tor_snprintf(buf
, sizeof(buf
),
814 "client-name %s\ndescriptor-cookie %s\n",
815 client
->client_name
, desc_cook_out
);
817 log_warn(LD_BUG
, "Could not write client entry.");
820 if (client
->client_key
) {
821 char *client_key_out
= NULL
;
822 if (crypto_pk_write_private_key_to_string(client
->client_key
,
823 &client_key_out
, &len
) != 0) {
824 log_warn(LD_BUG
, "Internal error: "
825 "crypto_pk_write_private_key_to_string() failed.");
828 if (rend_get_service_id(client
->client_key
, service_id
)<0) {
829 log_warn(LD_BUG
, "Internal error: couldn't encode service ID.");
831 * len is string length, not buffer length, but last byte is NUL
834 memwipe(client_key_out
, 0, len
);
835 tor_free(client_key_out
);
838 written
= tor_snprintf(buf
+ written
, sizeof(buf
) - written
,
839 "client-key\n%s", client_key_out
);
840 memwipe(client_key_out
, 0, len
);
841 tor_free(client_key_out
);
843 log_warn(LD_BUG
, "Could not write client entry.");
848 if (fputs(buf
, cfile
) < 0) {
849 log_warn(LD_FS
, "Could not append client entry to file: %s",
854 /* Add line to hostname file. */
855 if (s
->auth_type
== REND_BASIC_AUTH
) {
856 /* Remove == signs (newline has been removed above). */
857 desc_cook_out
[strlen(desc_cook_out
)-2] = '\0';
858 tor_snprintf(buf
, sizeof(buf
),"%s.onion %s # client: %s\n",
859 s
->service_id
, desc_cook_out
, client
->client_name
);
861 memcpy(extended_desc_cookie
, client
->descriptor_cookie
,
862 REND_DESC_COOKIE_LEN
);
863 extended_desc_cookie
[REND_DESC_COOKIE_LEN
] =
864 ((int)s
->auth_type
- 1) << 4;
865 if (base64_encode(desc_cook_out
, 3*REND_DESC_COOKIE_LEN_BASE64
+1,
866 extended_desc_cookie
,
867 REND_DESC_COOKIE_LEN
+1) < 0) {
868 log_warn(LD_BUG
, "Could not base64-encode descriptor cookie.");
871 desc_cook_out
[strlen(desc_cook_out
)-3] = '\0'; /* Remove A= and
873 tor_snprintf(buf
, sizeof(buf
),"%s.onion %s # client: %s\n",
874 service_id
, desc_cook_out
, client
->client_name
);
877 if (fputs(buf
, hfile
)<0) {
878 log_warn(LD_FS
, "Could not append host entry to file: %s",
882 } SMARTLIST_FOREACH_END(client
);
884 finish_writing_to_file(open_cfile
);
885 finish_writing_to_file(open_hfile
);
891 abort_writing_to_file(open_cfile
);
893 abort_writing_to_file(open_hfile
);
895 if (client_keys_str
) {
896 tor_strclear(client_keys_str
);
897 tor_free(client_keys_str
);
899 strmap_free(parsed_clients
, rend_authorized_client_strmap_item_free
);
901 memwipe(cfname
, 0, sizeof(cfname
));
903 /* Clear stack buffers that held key-derived material. */
904 memwipe(buf
, 0, sizeof(buf
));
905 memwipe(desc_cook_out
, 0, sizeof(desc_cook_out
));
906 memwipe(service_id
, 0, sizeof(service_id
));
907 memwipe(extended_desc_cookie
, 0, sizeof(extended_desc_cookie
));
912 /** Return the service whose public key has a digest of <b>digest</b>, or
913 * NULL if no such service exists.
915 static rend_service_t
*
916 rend_service_get_by_pk_digest(const char* digest
)
918 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, s
,
919 if (tor_memeq(s
->pk_digest
,digest
,DIGEST_LEN
))
924 /** Return 1 if any virtual port in <b>service</b> wants a circuit
925 * to have good uptime. Else return 0.
928 rend_service_requires_uptime(rend_service_t
*service
)
931 rend_service_port_config_t
*p
;
933 for (i
=0; i
< smartlist_len(service
->ports
); ++i
) {
934 p
= smartlist_get(service
->ports
, i
);
935 if (smartlist_contains_int_as_string(get_options()->LongLivedPorts
,
942 /** Check client authorization of a given <b>descriptor_cookie</b> for
943 * <b>service</b>. Return 1 for success and 0 for failure. */
945 rend_check_authorization(rend_service_t
*service
,
946 const char *descriptor_cookie
)
948 rend_authorized_client_t
*auth_client
= NULL
;
950 tor_assert(descriptor_cookie
);
951 if (!service
->clients
) {
952 log_warn(LD_BUG
, "Can't check authorization for a service that has no "
953 "authorized clients configured.");
957 /* Look up client authorization by descriptor cookie. */
958 SMARTLIST_FOREACH(service
->clients
, rend_authorized_client_t
*, client
, {
959 if (tor_memeq(client
->descriptor_cookie
, descriptor_cookie
,
960 REND_DESC_COOKIE_LEN
)) {
961 auth_client
= client
;
966 char descriptor_cookie_base64
[3*REND_DESC_COOKIE_LEN_BASE64
];
967 base64_encode(descriptor_cookie_base64
, sizeof(descriptor_cookie_base64
),
968 descriptor_cookie
, REND_DESC_COOKIE_LEN
);
969 log_info(LD_REND
, "No authorization found for descriptor cookie '%s'! "
971 descriptor_cookie_base64
);
975 /* Allow the request. */
976 log_debug(LD_REND
, "Client %s authorized for service %s.",
977 auth_client
->client_name
, service
->service_id
);
981 /** Called when <b>intro</b> will soon be removed from
982 * <b>service</b>'s list of intro points. */
984 rend_service_note_removing_intro_point(rend_service_t
*service
,
985 rend_intro_point_t
*intro
)
987 time_t now
= time(NULL
);
989 /* Don't process an intro point twice here. */
990 if (intro
->rend_service_note_removing_intro_point_called
) {
993 intro
->rend_service_note_removing_intro_point_called
= 1;
996 /* Update service->n_intro_points_wanted based on how long intro
997 * lasted and how many introductions it handled. */
998 if (intro
->time_published
== -1) {
999 /* This intro point was never used. Don't change
1000 * n_intro_points_wanted. */
1002 /* We want to increase the number of introduction points service
1003 * operates if intro was heavily used, or decrease the number of
1004 * intro points if intro was lightly used.
1006 * We consider an intro point's target 'usage' to be
1007 * INTRO_POINT_LIFETIME_INTRODUCTIONS introductions in
1008 * INTRO_POINT_LIFETIME_MIN_SECONDS seconds. To calculate intro's
1009 * fraction of target usage, we divide the fraction of
1010 * _LIFETIME_INTRODUCTIONS introductions that it has handled by
1011 * the fraction of _LIFETIME_MIN_SECONDS for which it existed.
1013 * Then we multiply that fraction of desired usage by a fudge
1014 * factor of 1.5, to decide how many new introduction points
1015 * should ideally replace intro (which is now closed or soon to be
1016 * closed). In theory, assuming that introduction load is
1017 * distributed equally across all intro points and ignoring the
1018 * fact that different intro points are established and closed at
1019 * different times, that number of intro points should bring all
1020 * of our intro points exactly to our target usage.
1022 * Then we clamp that number to a number of intro points we might
1023 * be willing to replace this intro point with and turn it into an
1024 * integer. then we clamp it again to the number of new intro
1025 * points we could establish now, then we adjust
1026 * service->n_intro_points_wanted and let rend_services_introduce
1027 * create the new intro points we want (if any).
1029 const double intro_point_usage
=
1030 intro_point_accepted_intro_count(intro
) /
1031 (double)(now
- intro
->time_published
);
1032 const double intro_point_target_usage
=
1033 INTRO_POINT_LIFETIME_INTRODUCTIONS
/
1034 (double)INTRO_POINT_LIFETIME_MIN_SECONDS
;
1035 const double fractional_n_intro_points_wanted_to_replace_this_one
=
1036 (1.5 * (intro_point_usage
/ intro_point_target_usage
));
1037 unsigned int n_intro_points_wanted_to_replace_this_one
;
1038 unsigned int n_intro_points_wanted_now
;
1039 unsigned int n_intro_points_really_wanted_now
;
1040 int n_intro_points_really_replacing_this_one
;
1042 if (fractional_n_intro_points_wanted_to_replace_this_one
>
1043 NUM_INTRO_POINTS_MAX
) {
1044 n_intro_points_wanted_to_replace_this_one
= NUM_INTRO_POINTS_MAX
;
1045 } else if (fractional_n_intro_points_wanted_to_replace_this_one
< 0) {
1046 n_intro_points_wanted_to_replace_this_one
= 0;
1048 n_intro_points_wanted_to_replace_this_one
= (unsigned)
1049 fractional_n_intro_points_wanted_to_replace_this_one
;
1052 n_intro_points_wanted_now
=
1053 service
->n_intro_points_wanted
+
1054 n_intro_points_wanted_to_replace_this_one
- 1;
1056 if (n_intro_points_wanted_now
< NUM_INTRO_POINTS_DEFAULT
) {
1057 /* XXXX This should be NUM_INTRO_POINTS_MIN instead. Perhaps
1058 * another use of NUM_INTRO_POINTS_DEFAULT should be, too. */
1059 n_intro_points_really_wanted_now
= NUM_INTRO_POINTS_DEFAULT
;
1060 } else if (n_intro_points_wanted_now
> NUM_INTRO_POINTS_MAX
) {
1061 n_intro_points_really_wanted_now
= NUM_INTRO_POINTS_MAX
;
1063 n_intro_points_really_wanted_now
= n_intro_points_wanted_now
;
1066 n_intro_points_really_replacing_this_one
=
1067 n_intro_points_really_wanted_now
- service
->n_intro_points_wanted
+ 1;
1069 log_info(LD_REND
, "Replacing closing intro point for service %s "
1070 "with %d new intro points (wanted %g replacements); "
1071 "service will now try to have %u intro points",
1072 rend_service_describe_for_log(service
),
1073 n_intro_points_really_replacing_this_one
,
1074 fractional_n_intro_points_wanted_to_replace_this_one
,
1075 n_intro_points_really_wanted_now
);
1077 service
->n_intro_points_wanted
= n_intro_points_really_wanted_now
;
1085 /** Respond to an INTRODUCE2 cell by launching a circuit to the chosen
1089 rend_service_introduce(origin_circuit_t
*circuit
, const uint8_t *request
,
1092 /* Global status stuff */
1093 int status
= 0, result
;
1094 const or_options_t
*options
= get_options();
1095 char *err_msg
= NULL
;
1096 const char *stage_descr
= NULL
;
1097 int reason
= END_CIRC_REASON_TORPROTOCOL
;
1098 /* Service/circuit/key stuff we can learn before parsing */
1099 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
1100 rend_service_t
*service
= NULL
;
1101 rend_intro_point_t
*intro_point
= NULL
;
1102 crypto_pk_t
*intro_key
= NULL
;
1104 rend_intro_cell_t
*parsed_req
= NULL
;
1105 /* Rendezvous point */
1106 extend_info_t
*rp
= NULL
;
1108 * We need to look up and construct the extend_info_t for v0 and v1,
1109 * but all the info is in the cell and it's constructed by the parser
1110 * for v2 and v3, so freeing it would be a double-free. Use this to
1111 * keep track of whether we should free it.
1113 uint8_t need_rp_free
= 0;
1114 /* XXX not handled yet */
1115 char buf
[RELAY_PAYLOAD_SIZE
];
1116 char keys
[DIGEST_LEN
+CPATH_KEY_MATERIAL_LEN
]; /* Holds KH, Df, Db, Kf, Kb */
1118 crypto_dh_t
*dh
= NULL
;
1119 origin_circuit_t
*launched
= NULL
;
1120 crypt_path_t
*cpath
= NULL
;
1122 int circ_needs_uptime
;
1123 time_t now
= time(NULL
);
1127 /* Do some initial validation and logging before we parse the cell */
1128 if (circuit
->base_
.purpose
!= CIRCUIT_PURPOSE_S_INTRO
) {
1129 log_warn(LD_PROTOCOL
,
1130 "Got an INTRODUCE2 over a non-introduction circuit %u.",
1131 (unsigned) circuit
->base_
.n_circ_id
);
1135 #ifndef NON_ANONYMOUS_MODE_ENABLED
1136 tor_assert(!(circuit
->build_state
->onehop_tunnel
));
1138 tor_assert(circuit
->rend_data
);
1140 /* We'll use this in a bazillion log messages */
1141 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+1,
1142 circuit
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
1144 /* look up service depending on circuit. */
1146 rend_service_get_by_pk_digest(circuit
->rend_data
->rend_pk_digest
);
1149 "Internal error: Got an INTRODUCE2 cell on an intro "
1150 "circ for an unrecognized service %s.",
1151 escaped(serviceid
));
1155 intro_point
= find_intro_point(circuit
);
1156 if (intro_point
== NULL
) {
1158 "Internal error: Got an INTRODUCE2 cell on an "
1159 "intro circ (for service %s) with no corresponding "
1160 "rend_intro_point_t.",
1161 escaped(serviceid
));
1165 log_info(LD_REND
, "Received INTRODUCE2 cell for service %s on circ %u.",
1166 escaped(serviceid
), (unsigned)circuit
->base_
.n_circ_id
);
1168 /* use intro key instead of service key. */
1169 intro_key
= circuit
->intro_key
;
1174 stage_descr
= "early parsing";
1175 /* Early parsing pass (get pk, ciphertext); type 2 is INTRODUCE2 */
1177 rend_service_begin_parse_intro(request
, request_len
, 2, &err_msg
);
1180 } else if (err_msg
) {
1181 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1182 (unsigned)circuit
->base_
.n_circ_id
);
1186 stage_descr
= "early validation";
1187 /* Early validation of pk/ciphertext part */
1188 result
= rend_service_validate_intro_early(parsed_req
, &err_msg
);
1191 } else if (err_msg
) {
1192 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1193 (unsigned)circuit
->base_
.n_circ_id
);
1197 /* make sure service replay caches are present */
1198 if (!service
->accepted_intro_dh_parts
) {
1199 service
->accepted_intro_dh_parts
=
1200 replaycache_new(REND_REPLAY_TIME_INTERVAL
,
1201 REND_REPLAY_TIME_INTERVAL
);
1204 if (!intro_point
->accepted_intro_rsa_parts
) {
1205 intro_point
->accepted_intro_rsa_parts
= replaycache_new(0, 0);
1208 /* check for replay of PK-encrypted portion. */
1209 replay
= replaycache_add_test_and_elapsed(
1210 intro_point
->accepted_intro_rsa_parts
,
1211 parsed_req
->ciphertext
, parsed_req
->ciphertext_len
,
1216 "Possible replay detected! We received an "
1217 "INTRODUCE2 cell with same PK-encrypted part %d "
1218 "seconds ago. Dropping cell.",
1223 stage_descr
= "decryption";
1224 /* Now try to decrypt it */
1225 result
= rend_service_decrypt_intro(parsed_req
, intro_key
, &err_msg
);
1228 } else if (err_msg
) {
1229 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1230 (unsigned)circuit
->base_
.n_circ_id
);
1234 stage_descr
= "late parsing";
1235 /* Parse the plaintext */
1236 result
= rend_service_parse_intro_plaintext(parsed_req
, &err_msg
);
1239 } else if (err_msg
) {
1240 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1241 (unsigned)circuit
->base_
.n_circ_id
);
1245 stage_descr
= "late validation";
1246 /* Validate the parsed plaintext parts */
1247 result
= rend_service_validate_intro_late(parsed_req
, &err_msg
);
1250 } else if (err_msg
) {
1251 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1252 (unsigned)circuit
->base_
.n_circ_id
);
1257 /* Increment INTRODUCE2 counter */
1258 ++(intro_point
->accepted_introduce2_count
);
1260 /* Find the rendezvous point */
1261 rp
= find_rp_for_intro(parsed_req
, &need_rp_free
, &err_msg
);
1265 /* Check if we'd refuse to talk to this router */
1266 if (options
->StrictNodes
&&
1267 routerset_contains_extendinfo(options
->ExcludeNodes
, rp
)) {
1268 log_warn(LD_REND
, "Client asked to rendezvous at a relay that we "
1269 "exclude, and StrictNodes is set. Refusing service.");
1270 reason
= END_CIRC_REASON_INTERNAL
; /* XXX might leak why we refused */
1274 base16_encode(hexcookie
, 9, (const char *)(parsed_req
->rc
), 4);
1276 /* Check whether there is a past request with the same Diffie-Hellman,
1278 replay
= replaycache_add_test_and_elapsed(
1279 service
->accepted_intro_dh_parts
,
1280 parsed_req
->dh
, DH_KEY_LEN
,
1284 /* A Tor client will send a new INTRODUCE1 cell with the same rend
1285 * cookie and DH public key as its previous one if its intro circ
1286 * times out while in state CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT .
1287 * If we received the first INTRODUCE1 cell (the intro-point relay
1288 * converts it into an INTRODUCE2 cell), we are already trying to
1289 * connect to that rend point (and may have already succeeded);
1290 * drop this cell. */
1291 log_info(LD_REND
, "We received an "
1292 "INTRODUCE2 cell with same first part of "
1293 "Diffie-Hellman handshake %d seconds ago. Dropping "
1299 /* If the service performs client authorization, check included auth data. */
1300 if (service
->clients
) {
1301 if (parsed_req
->version
== 3 && parsed_req
->u
.v3
.auth_len
> 0) {
1302 if (rend_check_authorization(service
,
1303 (const char*)parsed_req
->u
.v3
.auth_data
)) {
1304 log_info(LD_REND
, "Authorization data in INTRODUCE2 cell are valid.");
1306 log_info(LD_REND
, "The authorization data that are contained in "
1307 "the INTRODUCE2 cell are invalid. Dropping cell.");
1308 reason
= END_CIRC_REASON_CONNECTFAILED
;
1312 log_info(LD_REND
, "INTRODUCE2 cell does not contain authentication "
1313 "data, but we require client authorization. Dropping cell.");
1314 reason
= END_CIRC_REASON_CONNECTFAILED
;
1319 /* Try DH handshake... */
1320 dh
= crypto_dh_new(DH_TYPE_REND
);
1321 if (!dh
|| crypto_dh_generate_public(dh
)<0) {
1322 log_warn(LD_BUG
,"Internal error: couldn't build DH state "
1323 "or generate public key.");
1324 reason
= END_CIRC_REASON_INTERNAL
;
1327 if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN
, dh
,
1328 (char *)(parsed_req
->dh
),
1330 DIGEST_LEN
+CPATH_KEY_MATERIAL_LEN
)<0) {
1331 log_warn(LD_BUG
, "Internal error: couldn't complete DH handshake");
1332 reason
= END_CIRC_REASON_INTERNAL
;
1336 circ_needs_uptime
= rend_service_requires_uptime(service
);
1338 /* help predict this next time */
1339 rep_hist_note_used_internal(now
, circ_needs_uptime
, 1);
1341 /* Launch a circuit to alice's chosen rendezvous point.
1343 for (i
=0;i
<MAX_REND_FAILURES
;i
++) {
1344 int flags
= CIRCLAUNCH_NEED_CAPACITY
| CIRCLAUNCH_IS_INTERNAL
;
1345 if (circ_needs_uptime
) flags
|= CIRCLAUNCH_NEED_UPTIME
;
1346 launched
= circuit_launch_by_extend_info(
1347 CIRCUIT_PURPOSE_S_CONNECT_REND
, rp
, flags
);
1352 if (!launched
) { /* give up */
1353 log_warn(LD_REND
, "Giving up launching first hop of circuit to rendezvous "
1354 "point %s for service %s.",
1355 safe_str_client(extend_info_describe(rp
)),
1357 reason
= END_CIRC_REASON_CONNECTFAILED
;
1361 "Accepted intro; launching circuit to %s "
1362 "(cookie %s) for service %s.",
1363 safe_str_client(extend_info_describe(rp
)),
1364 hexcookie
, serviceid
);
1365 tor_assert(launched
->build_state
);
1366 /* Fill in the circuit's state. */
1367 launched
->rend_data
= tor_malloc_zero(sizeof(rend_data_t
));
1368 memcpy(launched
->rend_data
->rend_pk_digest
,
1369 circuit
->rend_data
->rend_pk_digest
,
1371 memcpy(launched
->rend_data
->rend_cookie
, parsed_req
->rc
, REND_COOKIE_LEN
);
1372 strlcpy(launched
->rend_data
->onion_address
, service
->service_id
,
1373 sizeof(launched
->rend_data
->onion_address
));
1375 launched
->build_state
->service_pending_final_cpath_ref
=
1376 tor_malloc_zero(sizeof(crypt_path_reference_t
));
1377 launched
->build_state
->service_pending_final_cpath_ref
->refcount
= 1;
1379 launched
->build_state
->service_pending_final_cpath_ref
->cpath
= cpath
=
1380 tor_malloc_zero(sizeof(crypt_path_t
));
1381 cpath
->magic
= CRYPT_PATH_MAGIC
;
1382 launched
->build_state
->expiry_time
= now
+ MAX_REND_TIMEOUT
;
1384 cpath
->rend_dh_handshake_state
= dh
;
1386 if (circuit_init_cpath_crypto(cpath
,keys
+DIGEST_LEN
,1)<0)
1388 memcpy(cpath
->rend_circ_nonce
, keys
, DIGEST_LEN
);
1395 tor_asprintf(&err_msg
,
1396 "unknown %s error for INTRODUCE2", stage_descr
);
1398 err_msg
= tor_strdup("unknown error for INTRODUCE2");
1402 log_warn(LD_REND
, "%s on circ %u", err_msg
,
1403 (unsigned)circuit
->base_
.n_circ_id
);
1406 if (dh
) crypto_dh_free(dh
);
1408 circuit_mark_for_close(TO_CIRCUIT(launched
), reason
);
1413 memwipe(keys
, 0, sizeof(keys
));
1414 memwipe(buf
, 0, sizeof(buf
));
1415 memwipe(serviceid
, 0, sizeof(serviceid
));
1416 memwipe(hexcookie
, 0, sizeof(hexcookie
));
1418 /* Free the parsed cell */
1420 rend_service_free_intro(parsed_req
);
1424 /* Free rp if we must */
1425 if (need_rp_free
) extend_info_free(rp
);
1430 /** Given a parsed and decrypted INTRODUCE2, find the rendezvous point or
1431 * return NULL and an error string if we can't.
1434 static extend_info_t
*
1435 find_rp_for_intro(const rend_intro_cell_t
*intro
,
1436 uint8_t *need_free_out
, char **err_msg_out
)
1438 extend_info_t
*rp
= NULL
;
1439 char *err_msg
= NULL
;
1440 const char *rp_nickname
= NULL
;
1441 const node_t
*node
= NULL
;
1442 uint8_t need_free
= 0;
1444 if (!intro
|| !need_free_out
) {
1446 err_msg
= tor_strdup("Bad parameters to find_rp_for_intro()");
1451 if (intro
->version
== 0 || intro
->version
== 1) {
1452 if (intro
->version
== 1) rp_nickname
= (const char *)(intro
->u
.v1
.rp
);
1453 else rp_nickname
= (const char *)(intro
->u
.v0
.rp
);
1455 node
= node_get_by_nickname(rp_nickname
, 0);
1458 tor_asprintf(&err_msg
,
1459 "Couldn't find router %s named in INTRODUCE2 cell",
1460 escaped_safe_str_client(rp_nickname
));
1466 rp
= extend_info_from_node(node
, 0);
1469 tor_asprintf(&err_msg
,
1470 "Could build extend_info_t for router %s named "
1471 "in INTRODUCE2 cell",
1472 escaped_safe_str_client(rp_nickname
));
1479 } else if (intro
->version
== 2) {
1480 rp
= intro
->u
.v2
.extend_info
;
1481 } else if (intro
->version
== 3) {
1482 rp
= intro
->u
.v3
.extend_info
;
1485 tor_asprintf(&err_msg
,
1486 "Unknown version %d in INTRODUCE2 cell",
1487 (int)(intro
->version
));
1496 if (err_msg_out
) *err_msg_out
= err_msg
;
1497 else tor_free(err_msg
);
1500 if (rp
&& need_free_out
) *need_free_out
= need_free
;
1505 /** Remove unnecessary parts from a rend_intro_cell_t - the ciphertext if
1506 * already decrypted, the plaintext too if already parsed
1510 rend_service_compact_intro(rend_intro_cell_t
*request
)
1512 if (!request
) return;
1514 if ((request
->plaintext
&& request
->plaintext_len
> 0) ||
1516 tor_free(request
->ciphertext
);
1517 request
->ciphertext_len
= 0;
1520 if (request
->parsed
) {
1521 tor_free(request
->plaintext
);
1522 request
->plaintext_len
= 0;
1526 /** Free a parsed INTRODUCE1 or INTRODUCE2 cell that was allocated by
1527 * rend_service_parse_intro().
1530 rend_service_free_intro(rend_intro_cell_t
*request
)
1533 log_info(LD_BUG
, "rend_service_free_intro() called with NULL request!");
1537 /* Free ciphertext */
1538 tor_free(request
->ciphertext
);
1539 request
->ciphertext_len
= 0;
1541 /* Have plaintext? */
1542 if (request
->plaintext
) {
1543 /* Zero it out just to be safe */
1544 memwipe(request
->plaintext
, 0, request
->plaintext_len
);
1545 tor_free(request
->plaintext
);
1546 request
->plaintext_len
= 0;
1549 /* Have parsed plaintext? */
1550 if (request
->parsed
) {
1551 switch (request
->version
) {
1555 * Nothing more to do; these formats have no further pointers
1560 extend_info_free(request
->u
.v2
.extend_info
);
1561 request
->u
.v2
.extend_info
= NULL
;
1564 if (request
->u
.v3
.auth_data
) {
1565 memwipe(request
->u
.v3
.auth_data
, 0, request
->u
.v3
.auth_len
);
1566 tor_free(request
->u
.v3
.auth_data
);
1569 extend_info_free(request
->u
.v3
.extend_info
);
1570 request
->u
.v3
.extend_info
= NULL
;
1574 "rend_service_free_intro() saw unknown protocol "
1580 /* Zero it out to make sure sensitive stuff doesn't hang around in memory */
1581 memwipe(request
, 0, sizeof(*request
));
1586 /** Parse an INTRODUCE1 or INTRODUCE2 cell into a newly allocated
1587 * rend_intro_cell_t structure. Free it with rend_service_free_intro()
1588 * when finished. The type parameter should be 1 or 2 to indicate whether
1589 * this is INTRODUCE1 or INTRODUCE2. This parses only the non-encrypted
1590 * parts; after this, call rend_service_decrypt_intro() with a key, then
1591 * rend_service_parse_intro_plaintext() to finish parsing. The optional
1592 * err_msg_out parameter is set to a string suitable for log output
1593 * if parsing fails. This function does some validation, but only
1594 * that which depends solely on the contents of the cell and the
1595 * key; it can be unit-tested. Further validation is done in
1596 * rend_service_validate_intro().
1600 rend_service_begin_parse_intro(const uint8_t *request
,
1605 rend_intro_cell_t
*rv
= NULL
;
1606 char *err_msg
= NULL
;
1608 if (!request
|| request_len
<= 0) goto err
;
1609 if (!(type
== 1 || type
== 2)) goto err
;
1611 /* First, check that the cell is long enough to be a sensible INTRODUCE */
1613 /* min key length plus digest length plus nickname length */
1615 (DIGEST_LEN
+ REND_COOKIE_LEN
+ (MAX_NICKNAME_LEN
+ 1) +
1618 tor_asprintf(&err_msg
,
1619 "got a truncated INTRODUCE%d cell",
1625 /* Allocate a new parsed cell structure */
1626 rv
= tor_malloc_zero(sizeof(*rv
));
1631 /* Copy in the ID */
1632 memcpy(rv
->pk
, request
, DIGEST_LEN
);
1634 /* Copy in the ciphertext */
1635 rv
->ciphertext
= tor_malloc(request_len
- DIGEST_LEN
);
1636 memcpy(rv
->ciphertext
, request
+ DIGEST_LEN
, request_len
- DIGEST_LEN
);
1637 rv
->ciphertext_len
= request_len
- DIGEST_LEN
;
1642 if (rv
) rend_service_free_intro(rv
);
1644 if (err_msg_out
&& !err_msg
) {
1645 tor_asprintf(&err_msg
,
1646 "unknown INTRODUCE%d error",
1651 if (err_msg_out
) *err_msg_out
= err_msg
;
1652 else tor_free(err_msg
);
1657 /** Parse the version-specific parts of a v0 or v1 INTRODUCE1 or INTRODUCE2
1662 rend_service_parse_intro_for_v0_or_v1(
1663 rend_intro_cell_t
*intro
,
1665 size_t plaintext_len
,
1668 const char *rp_nickname
, *endptr
;
1669 size_t nickname_field_len
, ver_specific_len
;
1671 if (intro
->version
== 1) {
1672 ver_specific_len
= MAX_HEX_NICKNAME_LEN
+ 2;
1673 rp_nickname
= ((const char *)buf
) + 1;
1674 nickname_field_len
= MAX_HEX_NICKNAME_LEN
+ 1;
1675 } else if (intro
->version
== 0) {
1676 ver_specific_len
= MAX_NICKNAME_LEN
+ 1;
1677 rp_nickname
= (const char *)buf
;
1678 nickname_field_len
= MAX_NICKNAME_LEN
+ 1;
1681 tor_asprintf(err_msg_out
,
1682 "rend_service_parse_intro_for_v0_or_v1() called with "
1683 "bad version %d on INTRODUCE%d cell (this is a bug)",
1685 (int)(intro
->type
));
1689 if (plaintext_len
< ver_specific_len
) {
1691 tor_asprintf(err_msg_out
,
1692 "short plaintext of encrypted part in v1 INTRODUCE%d "
1693 "cell (%lu bytes, needed %lu)",
1695 (unsigned long)plaintext_len
,
1696 (unsigned long)ver_specific_len
);
1700 endptr
= memchr(rp_nickname
, 0, nickname_field_len
);
1701 if (!endptr
|| endptr
== rp_nickname
) {
1703 tor_asprintf(err_msg_out
,
1704 "couldn't find a nul-padded nickname in "
1706 (int)(intro
->type
));
1711 if ((intro
->version
== 0 &&
1712 !is_legal_nickname(rp_nickname
)) ||
1713 (intro
->version
== 1 &&
1714 !is_legal_nickname_or_hexdigest(rp_nickname
))) {
1716 tor_asprintf(err_msg_out
,
1717 "bad nickname in INTRODUCE%d cell",
1718 (int)(intro
->type
));
1723 if (intro
->version
== 1) {
1724 memcpy(intro
->u
.v1
.rp
, rp_nickname
, endptr
- rp_nickname
+ 1);
1726 memcpy(intro
->u
.v0
.rp
, rp_nickname
, endptr
- rp_nickname
+ 1);
1729 return ver_specific_len
;
1735 /** Parse the version-specific parts of a v2 INTRODUCE1 or INTRODUCE2 cell
1739 rend_service_parse_intro_for_v2(
1740 rend_intro_cell_t
*intro
,
1742 size_t plaintext_len
,
1746 extend_info_t
*extend_info
= NULL
;
1747 ssize_t ver_specific_len
;
1750 * We accept version 3 too so that the v3 parser can call this with
1751 * and adjusted buffer for the latter part of a v3 cell, which is
1752 * identical to a v2 cell.
1754 if (!(intro
->version
== 2 ||
1755 intro
->version
== 3)) {
1757 tor_asprintf(err_msg_out
,
1758 "rend_service_parse_intro_for_v2() called with "
1759 "bad version %d on INTRODUCE%d cell (this is a bug)",
1761 (int)(intro
->type
));
1765 /* 7 == version, IP and port, DIGEST_LEN == id, 2 == key length */
1766 if (plaintext_len
< 7 + DIGEST_LEN
+ 2) {
1768 tor_asprintf(err_msg_out
,
1769 "truncated plaintext of encrypted parted of "
1770 "version %d INTRODUCE%d cell",
1772 (int)(intro
->type
));
1778 extend_info
= tor_malloc_zero(sizeof(extend_info_t
));
1779 tor_addr_from_ipv4n(&extend_info
->addr
, get_uint32(buf
+ 1));
1780 extend_info
->port
= ntohs(get_uint16(buf
+ 5));
1781 memcpy(extend_info
->identity_digest
, buf
+ 7, DIGEST_LEN
);
1782 extend_info
->nickname
[0] = '$';
1783 base16_encode(extend_info
->nickname
+ 1, sizeof(extend_info
->nickname
) - 1,
1784 extend_info
->identity_digest
, DIGEST_LEN
);
1785 klen
= ntohs(get_uint16(buf
+ 7 + DIGEST_LEN
));
1787 /* 7 == version, IP and port, DIGEST_LEN == id, 2 == key length */
1788 if (plaintext_len
< 7 + DIGEST_LEN
+ 2 + klen
) {
1790 tor_asprintf(err_msg_out
,
1791 "truncated plaintext of encrypted parted of "
1792 "version %d INTRODUCE%d cell",
1794 (int)(intro
->type
));
1800 extend_info
->onion_key
=
1801 crypto_pk_asn1_decode((const char *)(buf
+ 7 + DIGEST_LEN
+ 2), klen
);
1802 if (!extend_info
->onion_key
) {
1804 tor_asprintf(err_msg_out
,
1805 "error decoding onion key in version %d "
1814 ver_specific_len
= 7+DIGEST_LEN
+2+klen
;
1816 if (intro
->version
== 2) intro
->u
.v2
.extend_info
= extend_info
;
1817 else intro
->u
.v3
.extend_info
= extend_info
;
1819 return ver_specific_len
;
1822 extend_info_free(extend_info
);
1827 /** Parse the version-specific parts of a v3 INTRODUCE1 or INTRODUCE2 cell
1831 rend_service_parse_intro_for_v3(
1832 rend_intro_cell_t
*intro
,
1834 size_t plaintext_len
,
1837 ssize_t adjust
, v2_ver_specific_len
, ts_offset
;
1839 /* This should only be called on v3 cells */
1840 if (intro
->version
!= 3) {
1842 tor_asprintf(err_msg_out
,
1843 "rend_service_parse_intro_for_v3() called with "
1844 "bad version %d on INTRODUCE%d cell (this is a bug)",
1846 (int)(intro
->type
));
1851 * Check that we have at least enough to get auth_len:
1853 * 1 octet for version, 1 for auth_type, 2 for auth_len
1855 if (plaintext_len
< 4) {
1857 tor_asprintf(err_msg_out
,
1858 "truncated plaintext of encrypted parted of "
1859 "version %d INTRODUCE%d cell",
1861 (int)(intro
->type
));
1868 * The rend_client_send_introduction() function over in rendclient.c is
1869 * broken (i.e., fails to match the spec) in such a way that we can't
1870 * change it without breaking the protocol. Specifically, it doesn't
1871 * emit auth_len when auth-type is REND_NO_AUTH, so everything is off
1872 * by two bytes after that. Calculate ts_offset and do everything from
1873 * the timestamp on relative to that to handle this dain bramage.
1876 intro
->u
.v3
.auth_type
= buf
[1];
1877 if (intro
->u
.v3
.auth_type
!= REND_NO_AUTH
) {
1878 intro
->u
.v3
.auth_len
= ntohs(get_uint16(buf
+ 2));
1879 ts_offset
= 4 + intro
->u
.v3
.auth_len
;
1881 intro
->u
.v3
.auth_len
= 0;
1885 /* Check that auth len makes sense for this auth type */
1886 if (intro
->u
.v3
.auth_type
== REND_BASIC_AUTH
||
1887 intro
->u
.v3
.auth_type
== REND_STEALTH_AUTH
) {
1888 if (intro
->u
.v3
.auth_len
!= REND_DESC_COOKIE_LEN
) {
1890 tor_asprintf(err_msg_out
,
1891 "wrong auth data size %d for INTRODUCE%d cell, "
1893 (int)(intro
->u
.v3
.auth_len
),
1895 REND_DESC_COOKIE_LEN
);
1902 /* Check that we actually have everything up through the timestamp */
1903 if (plaintext_len
< (size_t)(ts_offset
)+4) {
1905 tor_asprintf(err_msg_out
,
1906 "truncated plaintext of encrypted parted of "
1907 "version %d INTRODUCE%d cell",
1909 (int)(intro
->type
));
1915 if (intro
->u
.v3
.auth_type
!= REND_NO_AUTH
&&
1916 intro
->u
.v3
.auth_len
> 0) {
1917 /* Okay, we can go ahead and copy auth_data */
1918 intro
->u
.v3
.auth_data
= tor_malloc(intro
->u
.v3
.auth_len
);
1920 * We know we had an auth_len field in this case, so 4 is
1923 memcpy(intro
->u
.v3
.auth_data
, buf
+ 4, intro
->u
.v3
.auth_len
);
1927 * From here on, the format is as in v2, so we call the v2 parser with
1928 * adjusted buffer and length. We are 4 + ts_offset octets in, but the
1929 * v2 parser expects to skip over a version byte at the start, so we
1930 * adjust by 3 + ts_offset.
1932 adjust
= 3 + ts_offset
;
1934 v2_ver_specific_len
=
1935 rend_service_parse_intro_for_v2(intro
,
1936 buf
+ adjust
, plaintext_len
- adjust
,
1939 /* Success in v2 parser */
1940 if (v2_ver_specific_len
>= 0) return v2_ver_specific_len
+ adjust
;
1941 /* Failure in v2 parser; it will have provided an err_msg */
1942 else return v2_ver_specific_len
;
1948 /** Table of parser functions for version-specific parts of an INTRODUCE2
1953 (*intro_version_handlers
[])(
1954 rend_intro_cell_t
*,
1958 { rend_service_parse_intro_for_v0_or_v1
,
1959 rend_service_parse_intro_for_v0_or_v1
,
1960 rend_service_parse_intro_for_v2
,
1961 rend_service_parse_intro_for_v3
};
1963 /** Decrypt the encrypted part of an INTRODUCE1 or INTRODUCE2 cell,
1964 * return 0 if successful, or < 0 and write an error message to
1965 * *err_msg_out if provided.
1969 rend_service_decrypt_intro(
1970 rend_intro_cell_t
*intro
,
1974 char *err_msg
= NULL
;
1975 uint8_t key_digest
[DIGEST_LEN
];
1976 char service_id
[REND_SERVICE_ID_LEN_BASE32
+1];
1978 uint8_t buf
[RELAY_PAYLOAD_SIZE
];
1979 int result
, status
= 0;
1981 if (!intro
|| !key
) {
1984 tor_strdup("rend_service_decrypt_intro() called with bad "
1992 /* Make sure we have ciphertext */
1993 if (!(intro
->ciphertext
) || intro
->ciphertext_len
<= 0) {
1995 tor_asprintf(&err_msg
,
1996 "rend_intro_cell_t was missing ciphertext for "
1998 (int)(intro
->type
));
2004 /* Check that this cell actually matches this service key */
2006 /* first DIGEST_LEN bytes of request is intro or service pk digest */
2007 crypto_pk_get_digest(key
, (char *)key_digest
);
2008 if (tor_memneq(key_digest
, intro
->pk
, DIGEST_LEN
)) {
2010 base32_encode(service_id
, REND_SERVICE_ID_LEN_BASE32
+ 1,
2011 (char*)(intro
->pk
), REND_SERVICE_ID_LEN
);
2012 tor_asprintf(&err_msg
,
2013 "got an INTRODUCE%d cell for the wrong service (%s)",
2015 escaped(service_id
));
2022 /* Make sure the encrypted part is long enough to decrypt */
2024 key_len
= crypto_pk_keysize(key
);
2025 if (intro
->ciphertext_len
< key_len
) {
2027 tor_asprintf(&err_msg
,
2028 "got an INTRODUCE%d cell with a truncated PK-encrypted "
2030 (int)(intro
->type
));
2037 /* Decrypt the encrypted part */
2039 note_crypto_pk_op(REND_SERVER
);
2041 crypto_pk_private_hybrid_decrypt(
2042 key
, (char *)buf
, sizeof(buf
),
2043 (const char *)(intro
->ciphertext
), intro
->ciphertext_len
,
2044 PK_PKCS1_OAEP_PADDING
, 1);
2047 tor_asprintf(&err_msg
,
2048 "couldn't decrypt INTRODUCE%d cell",
2049 (int)(intro
->type
));
2054 intro
->plaintext_len
= result
;
2055 intro
->plaintext
= tor_malloc(intro
->plaintext_len
);
2056 memcpy(intro
->plaintext
, buf
, intro
->plaintext_len
);
2061 if (err_msg_out
&& !err_msg
) {
2062 tor_asprintf(&err_msg
,
2063 "unknown INTRODUCE%d error decrypting encrypted part",
2064 (int)(intro
->type
));
2066 if (status
>= 0) status
= -1;
2069 if (err_msg_out
) *err_msg_out
= err_msg
;
2070 else tor_free(err_msg
);
2072 /* clean up potentially sensitive material */
2073 memwipe(buf
, 0, sizeof(buf
));
2074 memwipe(key_digest
, 0, sizeof(key_digest
));
2075 memwipe(service_id
, 0, sizeof(service_id
));
2080 /** Parse the plaintext of the encrypted part of an INTRODUCE1 or
2081 * INTRODUCE2 cell, return 0 if successful, or < 0 and write an error
2082 * message to *err_msg_out if provided.
2086 rend_service_parse_intro_plaintext(
2087 rend_intro_cell_t
*intro
,
2090 char *err_msg
= NULL
;
2091 ssize_t ver_specific_len
, ver_invariant_len
;
2098 tor_strdup("rend_service_parse_intro_plaintext() called with NULL "
2099 "rend_intro_cell_t");
2106 /* Check that we have plaintext */
2107 if (!(intro
->plaintext
) || intro
->plaintext_len
<= 0) {
2109 err_msg
= tor_strdup("rend_intro_cell_t was missing plaintext");
2115 /* In all formats except v0, the first byte is a version number */
2116 version
= intro
->plaintext
[0];
2118 /* v0 has no version byte (stupid...), so handle it as a fallback */
2119 if (version
> 3) version
= 0;
2121 /* Copy the version into the parsed cell structure */
2122 intro
->version
= version
;
2124 /* Call the version-specific parser from the table */
2126 intro_version_handlers
[version
](intro
,
2127 intro
->plaintext
, intro
->plaintext_len
,
2129 if (ver_specific_len
< 0) {
2134 /** The rendezvous cookie and Diffie-Hellman stuff are version-invariant
2135 * and at the end of the plaintext of the encrypted part of the cell.
2138 ver_invariant_len
= intro
->plaintext_len
- ver_specific_len
;
2139 if (ver_invariant_len
< REND_COOKIE_LEN
+ DH_KEY_LEN
) {
2140 tor_asprintf(&err_msg
,
2141 "decrypted plaintext of INTRODUCE%d cell was truncated (%ld bytes)",
2143 (long)(intro
->plaintext_len
));
2146 } else if (ver_invariant_len
> REND_COOKIE_LEN
+ DH_KEY_LEN
) {
2147 tor_asprintf(&err_msg
,
2148 "decrypted plaintext of INTRODUCE%d cell was too long (%ld bytes)",
2150 (long)(intro
->plaintext_len
));
2154 intro
->plaintext
+ ver_specific_len
,
2157 intro
->plaintext
+ ver_specific_len
+ REND_COOKIE_LEN
,
2161 /* Flag it as being fully parsed */
2167 if (err_msg_out
&& !err_msg
) {
2168 tor_asprintf(&err_msg
,
2169 "unknown INTRODUCE%d error parsing encrypted part",
2170 (int)(intro
->type
));
2172 if (status
>= 0) status
= -1;
2175 if (err_msg_out
) *err_msg_out
= err_msg
;
2176 else tor_free(err_msg
);
2181 /** Do validity checks on a parsed intro cell before decryption; some of
2182 * these are not done in rend_service_begin_parse_intro() itself because
2183 * they depend on a lot of other state and would make it hard to unit test.
2184 * Returns >= 0 if successful or < 0 if the intro cell is invalid, and
2185 * optionally writes out an error message for logging. If an err_msg
2186 * pointer is provided, it is the caller's responsibility to free any
2191 rend_service_validate_intro_early(const rend_intro_cell_t
*intro
,
2199 tor_strdup("NULL intro cell passed to "
2200 "rend_service_validate_intro_early()");
2212 /** Do validity checks on a parsed intro cell after decryption; some of
2213 * these are not done in rend_service_parse_intro_plaintext() itself because
2214 * they depend on a lot of other state and would make it hard to unit test.
2215 * Returns >= 0 if successful or < 0 if the intro cell is invalid, and
2216 * optionally writes out an error message for logging. If an err_msg
2217 * pointer is provided, it is the caller's responsibility to free any
2222 rend_service_validate_intro_late(const rend_intro_cell_t
*intro
,
2230 tor_strdup("NULL intro cell passed to "
2231 "rend_service_validate_intro_late()");
2237 if (intro
->version
== 3 && intro
->parsed
) {
2238 if (!(intro
->u
.v3
.auth_type
== REND_NO_AUTH
||
2239 intro
->u
.v3
.auth_type
== REND_BASIC_AUTH
||
2240 intro
->u
.v3
.auth_type
== REND_STEALTH_AUTH
)) {
2241 /* This is an informative message, not an error, as in the old code */
2243 tor_asprintf(err_msg_out
,
2244 "unknown authorization type %d",
2245 intro
->u
.v3
.auth_type
);
2253 /** Called when we fail building a rendezvous circuit at some point other
2254 * than the last hop: launches a new circuit to the same rendezvous point.
2257 rend_service_relaunch_rendezvous(origin_circuit_t
*oldcirc
)
2259 origin_circuit_t
*newcirc
;
2260 cpath_build_state_t
*newstate
, *oldstate
;
2262 tor_assert(oldcirc
->base_
.purpose
== CIRCUIT_PURPOSE_S_CONNECT_REND
);
2264 /* Don't relaunch the same rend circ twice. */
2265 if (oldcirc
->hs_service_side_rend_circ_has_been_relaunched
) {
2266 log_info(LD_REND
, "Rendezvous circuit to %s has already been relaunched; "
2267 "not relaunching it again.",
2268 oldcirc
->build_state
?
2269 safe_str(extend_info_describe(oldcirc
->build_state
->chosen_exit
))
2273 oldcirc
->hs_service_side_rend_circ_has_been_relaunched
= 1;
2275 if (!oldcirc
->build_state
||
2276 oldcirc
->build_state
->failure_count
> MAX_REND_FAILURES
||
2277 oldcirc
->build_state
->expiry_time
< time(NULL
)) {
2279 "Attempt to build circuit to %s for rendezvous has failed "
2280 "too many times or expired; giving up.",
2281 oldcirc
->build_state
?
2282 safe_str(extend_info_describe(oldcirc
->build_state
->chosen_exit
))
2287 oldstate
= oldcirc
->build_state
;
2288 tor_assert(oldstate
);
2290 if (oldstate
->service_pending_final_cpath_ref
== NULL
) {
2291 log_info(LD_REND
,"Skipping relaunch of circ that failed on its first hop. "
2292 "Initiator will retry.");
2296 log_info(LD_REND
,"Reattempting rendezvous circuit to '%s'",
2297 safe_str(extend_info_describe(oldstate
->chosen_exit
)));
2299 newcirc
= circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND
,
2300 oldstate
->chosen_exit
,
2301 CIRCLAUNCH_NEED_CAPACITY
|CIRCLAUNCH_IS_INTERNAL
);
2304 log_warn(LD_REND
,"Couldn't relaunch rendezvous circuit to '%s'.",
2305 safe_str(extend_info_describe(oldstate
->chosen_exit
)));
2308 newstate
= newcirc
->build_state
;
2309 tor_assert(newstate
);
2310 newstate
->failure_count
= oldstate
->failure_count
+1;
2311 newstate
->expiry_time
= oldstate
->expiry_time
;
2312 newstate
->service_pending_final_cpath_ref
=
2313 oldstate
->service_pending_final_cpath_ref
;
2314 ++(newstate
->service_pending_final_cpath_ref
->refcount
);
2316 newcirc
->rend_data
= rend_data_dup(oldcirc
->rend_data
);
2319 /** Launch a circuit to serve as an introduction point for the service
2320 * <b>service</b> at the introduction point <b>nickname</b>
2323 rend_service_launch_establish_intro(rend_service_t
*service
,
2324 rend_intro_point_t
*intro
)
2326 origin_circuit_t
*launched
;
2329 "Launching circuit to introduction point %s for service %s",
2330 safe_str_client(extend_info_describe(intro
->extend_info
)),
2331 service
->service_id
);
2333 rep_hist_note_used_internal(time(NULL
), 1, 0);
2335 ++service
->n_intro_circuits_launched
;
2336 launched
= circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
,
2338 CIRCLAUNCH_NEED_UPTIME
|CIRCLAUNCH_IS_INTERNAL
);
2342 "Can't launch circuit to establish introduction at %s.",
2343 safe_str_client(extend_info_describe(intro
->extend_info
)));
2347 if (tor_memneq(intro
->extend_info
->identity_digest
,
2348 launched
->build_state
->chosen_exit
->identity_digest
, DIGEST_LEN
)) {
2349 char cann
[HEX_DIGEST_LEN
+1], orig
[HEX_DIGEST_LEN
+1];
2350 base16_encode(cann
, sizeof(cann
),
2351 launched
->build_state
->chosen_exit
->identity_digest
,
2353 base16_encode(orig
, sizeof(orig
),
2354 intro
->extend_info
->identity_digest
, DIGEST_LEN
);
2355 log_info(LD_REND
, "The intro circuit we just cannibalized ends at $%s, "
2356 "but we requested an intro circuit to $%s. Updating "
2357 "our service.", cann
, orig
);
2358 extend_info_free(intro
->extend_info
);
2359 intro
->extend_info
= extend_info_dup(launched
->build_state
->chosen_exit
);
2362 launched
->rend_data
= tor_malloc_zero(sizeof(rend_data_t
));
2363 strlcpy(launched
->rend_data
->onion_address
, service
->service_id
,
2364 sizeof(launched
->rend_data
->onion_address
));
2365 memcpy(launched
->rend_data
->rend_pk_digest
, service
->pk_digest
, DIGEST_LEN
);
2366 launched
->intro_key
= crypto_pk_dup_key(intro
->intro_key
);
2367 if (launched
->base_
.state
== CIRCUIT_STATE_OPEN
)
2368 rend_service_intro_has_opened(launched
);
2372 /** Return the number of introduction points that are or have been
2373 * established for the given service address in <b>query</b>. */
2375 count_established_intro_points(const char *query
)
2379 TOR_LIST_FOREACH(circ
, circuit_get_global_list(), head
) {
2380 if (!circ
->marked_for_close
&&
2381 circ
->state
== CIRCUIT_STATE_OPEN
&&
2382 (circ
->purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
||
2383 circ
->purpose
== CIRCUIT_PURPOSE_S_INTRO
)) {
2384 origin_circuit_t
*oc
= TO_ORIGIN_CIRCUIT(circ
);
2385 if (oc
->rend_data
&&
2386 !rend_cmp_service_ids(query
, oc
->rend_data
->onion_address
))
2393 /** Called when we're done building a circuit to an introduction point:
2394 * sends a RELAY_ESTABLISH_INTRO cell.
2397 rend_service_intro_has_opened(origin_circuit_t
*circuit
)
2399 rend_service_t
*service
;
2402 char buf
[RELAY_PAYLOAD_SIZE
];
2403 char auth
[DIGEST_LEN
+ 9];
2404 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
2405 int reason
= END_CIRC_REASON_TORPROTOCOL
;
2406 crypto_pk_t
*intro_key
;
2408 tor_assert(circuit
->base_
.purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
);
2409 #ifndef NON_ANONYMOUS_MODE_ENABLED
2410 tor_assert(!(circuit
->build_state
->onehop_tunnel
));
2412 tor_assert(circuit
->cpath
);
2413 tor_assert(circuit
->rend_data
);
2415 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+1,
2416 circuit
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
2418 service
= rend_service_get_by_pk_digest(
2419 circuit
->rend_data
->rend_pk_digest
);
2421 log_warn(LD_REND
, "Unrecognized service ID %s on introduction circuit %u.",
2422 serviceid
, (unsigned)circuit
->base_
.n_circ_id
);
2423 reason
= END_CIRC_REASON_NOSUCHSERVICE
;
2427 /* If we already have enough introduction circuits for this service,
2428 * redefine this one as a general circuit or close it, depending. */
2429 if (count_established_intro_points(serviceid
) >
2430 (int)service
->n_intro_points_wanted
) { /* XXX023 remove cast */
2431 const or_options_t
*options
= get_options();
2432 if (options
->ExcludeNodes
) {
2433 /* XXXX in some future version, we can test whether the transition is
2434 allowed or not given the actual nodes in the circuit. But for now,
2435 this case, we might as well close the thing. */
2436 log_info(LD_CIRC
|LD_REND
, "We have just finished an introduction "
2437 "circuit, but we already have enough. Closing it.");
2438 reason
= END_CIRC_REASON_NONE
;
2441 tor_assert(circuit
->build_state
->is_internal
);
2442 log_info(LD_CIRC
|LD_REND
, "We have just finished an introduction "
2443 "circuit, but we already have enough. Redefining purpose to "
2444 "general; leaving as internal.");
2446 circuit_change_purpose(TO_CIRCUIT(circuit
), CIRCUIT_PURPOSE_C_GENERAL
);
2449 rend_data_t
*rend_data
= circuit
->rend_data
;
2450 circuit
->rend_data
= NULL
;
2451 rend_data_free(rend_data
);
2454 crypto_pk_t
*intro_key
= circuit
->intro_key
;
2455 circuit
->intro_key
= NULL
;
2456 crypto_pk_free(intro_key
);
2459 circuit_has_opened(circuit
);
2465 "Established circuit %u as introduction point for service %s",
2466 (unsigned)circuit
->base_
.n_circ_id
, serviceid
);
2468 /* Use the intro key instead of the service key in ESTABLISH_INTRO. */
2469 intro_key
= circuit
->intro_key
;
2470 /* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
2471 r
= crypto_pk_asn1_encode(intro_key
, buf
+2,
2472 RELAY_PAYLOAD_SIZE
-2);
2474 log_warn(LD_BUG
, "Internal error; failed to establish intro point.");
2475 reason
= END_CIRC_REASON_INTERNAL
;
2479 set_uint16(buf
, htons((uint16_t)len
));
2481 memcpy(auth
, circuit
->cpath
->prev
->rend_circ_nonce
, DIGEST_LEN
);
2482 memcpy(auth
+DIGEST_LEN
, "INTRODUCE", 9);
2483 if (crypto_digest(buf
+len
, auth
, DIGEST_LEN
+9))
2486 note_crypto_pk_op(REND_SERVER
);
2487 r
= crypto_pk_private_sign_digest(intro_key
, buf
+len
, sizeof(buf
)-len
,
2490 log_warn(LD_BUG
, "Internal error: couldn't sign introduction request.");
2491 reason
= END_CIRC_REASON_INTERNAL
;
2496 if (relay_send_command_from_edge(0, TO_CIRCUIT(circuit
),
2497 RELAY_COMMAND_ESTABLISH_INTRO
,
2498 buf
, len
, circuit
->cpath
->prev
)<0) {
2499 log_info(LD_GENERAL
,
2500 "Couldn't send introduction request for service %s on circuit %u",
2501 serviceid
, (unsigned)circuit
->base_
.n_circ_id
);
2502 reason
= END_CIRC_REASON_INTERNAL
;
2506 /* We've attempted to use this circuit */
2507 pathbias_count_use_attempt(circuit
);
2512 circuit_mark_for_close(TO_CIRCUIT(circuit
), reason
);
2514 memwipe(buf
, 0, sizeof(buf
));
2515 memwipe(auth
, 0, sizeof(auth
));
2516 memwipe(serviceid
, 0, sizeof(serviceid
));
2521 /** Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a
2522 * live introduction point, and note that the service descriptor is
2523 * now out-of-date. */
2525 rend_service_intro_established(origin_circuit_t
*circuit
,
2526 const uint8_t *request
,
2529 rend_service_t
*service
;
2530 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
2534 if (circuit
->base_
.purpose
!= CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
) {
2535 log_warn(LD_PROTOCOL
,
2536 "received INTRO_ESTABLISHED cell on non-intro circuit.");
2539 tor_assert(circuit
->rend_data
);
2540 service
= rend_service_get_by_pk_digest(
2541 circuit
->rend_data
->rend_pk_digest
);
2543 log_warn(LD_REND
, "Unknown service on introduction circuit %u.",
2544 (unsigned)circuit
->base_
.n_circ_id
);
2547 service
->desc_is_dirty
= time(NULL
);
2548 circuit_change_purpose(TO_CIRCUIT(circuit
), CIRCUIT_PURPOSE_S_INTRO
);
2550 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+ 1,
2551 circuit
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
2553 "Received INTRO_ESTABLISHED cell on circuit %u for service %s",
2554 (unsigned)circuit
->base_
.n_circ_id
, serviceid
);
2556 /* Getting a valid INTRODUCE_ESTABLISHED means we've successfully
2558 pathbias_mark_use_success(circuit
);
2562 circuit_mark_for_close(TO_CIRCUIT(circuit
), END_CIRC_REASON_TORPROTOCOL
);
2566 /** Called once a circuit to a rendezvous point is established: sends a
2567 * RELAY_COMMAND_RENDEZVOUS1 cell.
2570 rend_service_rendezvous_has_opened(origin_circuit_t
*circuit
)
2572 rend_service_t
*service
;
2573 char buf
[RELAY_PAYLOAD_SIZE
];
2575 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
2579 tor_assert(circuit
->base_
.purpose
== CIRCUIT_PURPOSE_S_CONNECT_REND
);
2580 tor_assert(circuit
->cpath
);
2581 tor_assert(circuit
->build_state
);
2582 #ifndef NON_ANONYMOUS_MODE_ENABLED
2583 tor_assert(!(circuit
->build_state
->onehop_tunnel
));
2585 tor_assert(circuit
->rend_data
);
2587 /* Declare the circuit dirty to avoid reuse, and for path-bias */
2588 if (!circuit
->base_
.timestamp_dirty
)
2589 circuit
->base_
.timestamp_dirty
= time(NULL
);
2591 /* This may be redundant */
2592 pathbias_count_use_attempt(circuit
);
2594 hop
= circuit
->build_state
->service_pending_final_cpath_ref
->cpath
;
2596 base16_encode(hexcookie
,9,circuit
->rend_data
->rend_cookie
,4);
2597 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+1,
2598 circuit
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
2601 "Done building circuit %u to rendezvous with "
2602 "cookie %s for service %s",
2603 (unsigned)circuit
->base_
.n_circ_id
, hexcookie
, serviceid
);
2605 /* Clear the 'in-progress HS circ has timed out' flag for
2606 * consistency with what happens on the client side; this line has
2607 * no effect on Tor's behaviour. */
2608 circuit
->hs_circ_has_timed_out
= 0;
2610 /* If hop is NULL, another rend circ has already connected to this
2611 * rend point. Close this circ. */
2613 log_info(LD_REND
, "Another rend circ has already reached this rend point; "
2614 "closing this rend circ.");
2615 reason
= END_CIRC_REASON_NONE
;
2619 /* Remove our final cpath element from the reference, so that no
2620 * other circuit will try to use it. Store it in
2621 * pending_final_cpath for now to ensure that it will be freed if
2622 * our rendezvous attempt fails. */
2623 circuit
->build_state
->pending_final_cpath
= hop
;
2624 circuit
->build_state
->service_pending_final_cpath_ref
->cpath
= NULL
;
2626 service
= rend_service_get_by_pk_digest(
2627 circuit
->rend_data
->rend_pk_digest
);
2629 log_warn(LD_GENERAL
, "Internal error: unrecognized service ID on "
2630 "rendezvous circuit.");
2631 reason
= END_CIRC_REASON_INTERNAL
;
2635 /* All we need to do is send a RELAY_RENDEZVOUS1 cell... */
2636 memcpy(buf
, circuit
->rend_data
->rend_cookie
, REND_COOKIE_LEN
);
2637 if (crypto_dh_get_public(hop
->rend_dh_handshake_state
,
2638 buf
+REND_COOKIE_LEN
, DH_KEY_LEN
)<0) {
2639 log_warn(LD_GENERAL
,"Couldn't get DH public key.");
2640 reason
= END_CIRC_REASON_INTERNAL
;
2643 memcpy(buf
+REND_COOKIE_LEN
+DH_KEY_LEN
, hop
->rend_circ_nonce
,
2647 if (relay_send_command_from_edge(0, TO_CIRCUIT(circuit
),
2648 RELAY_COMMAND_RENDEZVOUS1
,
2649 buf
, REND_COOKIE_LEN
+DH_KEY_LEN
+DIGEST_LEN
,
2650 circuit
->cpath
->prev
)<0) {
2651 log_warn(LD_GENERAL
, "Couldn't send RENDEZVOUS1 cell.");
2652 reason
= END_CIRC_REASON_INTERNAL
;
2656 crypto_dh_free(hop
->rend_dh_handshake_state
);
2657 hop
->rend_dh_handshake_state
= NULL
;
2659 /* Append the cpath entry. */
2660 hop
->state
= CPATH_STATE_OPEN
;
2661 /* set the windows to default. these are the windows
2662 * that bob thinks alice has.
2664 hop
->package_window
= circuit_initial_package_window();
2665 hop
->deliver_window
= CIRCWINDOW_START
;
2667 onion_append_to_cpath(&circuit
->cpath
, hop
);
2668 circuit
->build_state
->pending_final_cpath
= NULL
; /* prevent double-free */
2670 /* Change the circuit purpose. */
2671 circuit_change_purpose(TO_CIRCUIT(circuit
), CIRCUIT_PURPOSE_S_REND_JOINED
);
2676 circuit_mark_for_close(TO_CIRCUIT(circuit
), reason
);
2678 memwipe(buf
, 0, sizeof(buf
));
2679 memwipe(serviceid
, 0, sizeof(serviceid
));
2680 memwipe(hexcookie
, 0, sizeof(hexcookie
));
2686 * Manage introduction points
2689 /** Return the (possibly non-open) introduction circuit ending at
2690 * <b>intro</b> for the service whose public key is <b>pk_digest</b>.
2691 * (<b>desc_version</b> is ignored). Return NULL if no such service is
2694 static origin_circuit_t
*
2695 find_intro_circuit(rend_intro_point_t
*intro
, const char *pk_digest
)
2697 origin_circuit_t
*circ
= NULL
;
2700 while ((circ
= circuit_get_next_by_pk_and_purpose(circ
,pk_digest
,
2701 CIRCUIT_PURPOSE_S_INTRO
))) {
2702 if (tor_memeq(circ
->build_state
->chosen_exit
->identity_digest
,
2703 intro
->extend_info
->identity_digest
, DIGEST_LEN
) &&
2710 while ((circ
= circuit_get_next_by_pk_and_purpose(circ
,pk_digest
,
2711 CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
))) {
2712 if (tor_memeq(circ
->build_state
->chosen_exit
->identity_digest
,
2713 intro
->extend_info
->identity_digest
, DIGEST_LEN
) &&
2721 /** Return a pointer to the rend_intro_point_t corresponding to the
2722 * service-side introduction circuit <b>circ</b>. */
2723 static rend_intro_point_t
*
2724 find_intro_point(origin_circuit_t
*circ
)
2726 const char *serviceid
;
2727 rend_service_t
*service
= NULL
;
2729 tor_assert(TO_CIRCUIT(circ
)->purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
||
2730 TO_CIRCUIT(circ
)->purpose
== CIRCUIT_PURPOSE_S_INTRO
);
2731 tor_assert(circ
->rend_data
);
2732 serviceid
= circ
->rend_data
->onion_address
;
2734 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, s
,
2735 if (tor_memeq(s
->service_id
, serviceid
, REND_SERVICE_ID_LEN_BASE32
)) {
2740 if (service
== NULL
) return NULL
;
2742 SMARTLIST_FOREACH(service
->intro_nodes
, rend_intro_point_t
*, intro_point
,
2743 if (crypto_pk_eq_keys(intro_point
->intro_key
, circ
->intro_key
)) {
2750 /** Determine the responsible hidden service directories for the
2751 * rend_encoded_v2_service_descriptor_t's in <b>descs</b> and upload them;
2752 * <b>service_id</b> and <b>seconds_valid</b> are only passed for logging
2755 directory_post_to_hs_dir(rend_service_descriptor_t
*renddesc
,
2756 smartlist_t
*descs
, const char *service_id
,
2759 int i
, j
, failed_upload
= 0;
2760 smartlist_t
*responsible_dirs
= smartlist_new();
2761 smartlist_t
*successful_uploads
= smartlist_new();
2762 routerstatus_t
*hs_dir
;
2763 for (i
= 0; i
< smartlist_len(descs
); i
++) {
2764 rend_encoded_v2_service_descriptor_t
*desc
= smartlist_get(descs
, i
);
2765 /* Determine responsible dirs. */
2766 if (hid_serv_get_responsible_directories(responsible_dirs
,
2767 desc
->desc_id
) < 0) {
2768 log_warn(LD_REND
, "Could not determine the responsible hidden service "
2769 "directories to post descriptors to.");
2770 smartlist_free(responsible_dirs
);
2771 smartlist_free(successful_uploads
);
2774 for (j
= 0; j
< smartlist_len(responsible_dirs
); j
++) {
2775 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
2778 hs_dir
= smartlist_get(responsible_dirs
, j
);
2779 if (smartlist_contains_digest(renddesc
->successful_uploads
,
2780 hs_dir
->identity_digest
))
2781 /* Don't upload descriptor if we succeeded in doing so last time. */
2783 node
= node_get_by_id(hs_dir
->identity_digest
);
2784 if (!node
|| !node_has_descriptor(node
)) {
2785 log_info(LD_REND
, "Not launching upload for for v2 descriptor to "
2786 "hidden service directory %s; we don't have its "
2787 "router descriptor. Queuing for later upload.",
2788 safe_str_client(routerstatus_describe(hs_dir
)));
2792 /* Send publish request. */
2793 directory_initiate_command_routerstatus(hs_dir
,
2794 DIR_PURPOSE_UPLOAD_RENDDESC_V2
,
2795 ROUTER_PURPOSE_GENERAL
,
2796 DIRIND_ANONYMOUS
, NULL
,
2798 strlen(desc
->desc_str
), 0);
2799 base32_encode(desc_id_base32
, sizeof(desc_id_base32
),
2800 desc
->desc_id
, DIGEST_LEN
);
2801 hs_dir_ip
= tor_dup_ip(hs_dir
->addr
);
2802 log_info(LD_REND
, "Launching upload for v2 descriptor for "
2803 "service '%s' with descriptor ID '%s' with validity "
2804 "of %d seconds to hidden service directory '%s' on "
2806 safe_str_client(service_id
),
2807 safe_str_client(desc_id_base32
),
2812 tor_free(hs_dir_ip
);
2813 /* Remember successful upload to this router for next time. */
2814 if (!smartlist_contains_digest(successful_uploads
,
2815 hs_dir
->identity_digest
))
2816 smartlist_add(successful_uploads
, hs_dir
->identity_digest
);
2818 smartlist_clear(responsible_dirs
);
2820 if (!failed_upload
) {
2821 if (renddesc
->successful_uploads
) {
2822 SMARTLIST_FOREACH(renddesc
->successful_uploads
, char *, c
, tor_free(c
););
2823 smartlist_free(renddesc
->successful_uploads
);
2824 renddesc
->successful_uploads
= NULL
;
2826 renddesc
->all_uploads_performed
= 1;
2828 /* Remember which routers worked this time, so that we don't upload the
2829 * descriptor to them again. */
2830 if (!renddesc
->successful_uploads
)
2831 renddesc
->successful_uploads
= smartlist_new();
2832 SMARTLIST_FOREACH(successful_uploads
, const char *, c
, {
2833 if (!smartlist_contains_digest(renddesc
->successful_uploads
, c
)) {
2834 char *hsdir_id
= tor_memdup(c
, DIGEST_LEN
);
2835 smartlist_add(renddesc
->successful_uploads
, hsdir_id
);
2839 smartlist_free(responsible_dirs
);
2840 smartlist_free(successful_uploads
);
2843 /** Encode and sign an up-to-date service descriptor for <b>service</b>,
2844 * and upload it/them to the responsible hidden service directories.
2847 upload_service_descriptor(rend_service_t
*service
)
2849 time_t now
= time(NULL
);
2851 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
2854 rendpostperiod
= get_options()->RendPostPeriod
;
2856 /* Upload descriptor? */
2857 if (get_options()->PublishHidServDescriptors
) {
2858 networkstatus_t
*c
= networkstatus_get_latest_consensus();
2859 if (c
&& smartlist_len(c
->routerstatus_list
) > 0) {
2860 int seconds_valid
, i
, j
, num_descs
;
2861 smartlist_t
*descs
= smartlist_new();
2862 smartlist_t
*client_cookies
= smartlist_new();
2863 /* Either upload a single descriptor (including replicas) or one
2864 * descriptor for each authorized client in case of authorization
2865 * type 'stealth'. */
2866 num_descs
= service
->auth_type
== REND_STEALTH_AUTH
?
2867 smartlist_len(service
->clients
) : 1;
2868 for (j
= 0; j
< num_descs
; j
++) {
2869 crypto_pk_t
*client_key
= NULL
;
2870 rend_authorized_client_t
*client
= NULL
;
2871 smartlist_clear(client_cookies
);
2872 switch (service
->auth_type
) {
2874 /* Do nothing here. */
2876 case REND_BASIC_AUTH
:
2877 SMARTLIST_FOREACH(service
->clients
, rend_authorized_client_t
*,
2878 cl
, smartlist_add(client_cookies
, cl
->descriptor_cookie
));
2880 case REND_STEALTH_AUTH
:
2881 client
= smartlist_get(service
->clients
, j
);
2882 client_key
= client
->client_key
;
2883 smartlist_add(client_cookies
, client
->descriptor_cookie
);
2886 /* Encode the current descriptor. */
2887 seconds_valid
= rend_encode_v2_descriptors(descs
, service
->desc
,
2892 if (seconds_valid
< 0) {
2893 log_warn(LD_BUG
, "Internal error: couldn't encode service "
2894 "descriptor; not uploading.");
2895 smartlist_free(descs
);
2896 smartlist_free(client_cookies
);
2899 /* Post the current descriptors to the hidden service directories. */
2900 rend_get_service_id(service
->desc
->pk
, serviceid
);
2901 log_info(LD_REND
, "Launching upload for hidden service %s",
2903 directory_post_to_hs_dir(service
->desc
, descs
, serviceid
,
2905 /* Free memory for descriptors. */
2906 for (i
= 0; i
< smartlist_len(descs
); i
++)
2907 rend_encoded_v2_service_descriptor_free(smartlist_get(descs
, i
));
2908 smartlist_clear(descs
);
2909 /* Update next upload time. */
2910 if (seconds_valid
- REND_TIME_PERIOD_OVERLAPPING_V2_DESCS
2912 service
->next_upload_time
= now
+ rendpostperiod
;
2913 else if (seconds_valid
< REND_TIME_PERIOD_OVERLAPPING_V2_DESCS
)
2914 service
->next_upload_time
= now
+ seconds_valid
+ 1;
2916 service
->next_upload_time
= now
+ seconds_valid
-
2917 REND_TIME_PERIOD_OVERLAPPING_V2_DESCS
+ 1;
2918 /* Post also the next descriptors, if necessary. */
2919 if (seconds_valid
< REND_TIME_PERIOD_OVERLAPPING_V2_DESCS
) {
2920 seconds_valid
= rend_encode_v2_descriptors(descs
, service
->desc
,
2925 if (seconds_valid
< 0) {
2926 log_warn(LD_BUG
, "Internal error: couldn't encode service "
2927 "descriptor; not uploading.");
2928 smartlist_free(descs
);
2929 smartlist_free(client_cookies
);
2932 directory_post_to_hs_dir(service
->desc
, descs
, serviceid
,
2934 /* Free memory for descriptors. */
2935 for (i
= 0; i
< smartlist_len(descs
); i
++)
2936 rend_encoded_v2_service_descriptor_free(smartlist_get(descs
, i
));
2937 smartlist_clear(descs
);
2940 smartlist_free(descs
);
2941 smartlist_free(client_cookies
);
2943 log_info(LD_REND
, "Successfully uploaded v2 rend descriptors!");
2947 /* If not uploaded, try again in one minute. */
2949 service
->next_upload_time
= now
+ 60;
2951 /* Unmark dirty flag of this service. */
2952 service
->desc_is_dirty
= 0;
2955 /** Return the number of INTRODUCE2 cells this hidden service has received
2956 * from this intro point. */
2958 intro_point_accepted_intro_count(rend_intro_point_t
*intro
)
2960 return intro
->accepted_introduce2_count
;
2963 /** Return non-zero iff <b>intro</b> should 'expire' now (i.e. we
2964 * should stop publishing it in new descriptors and eventually close
2967 intro_point_should_expire_now(rend_intro_point_t
*intro
,
2970 tor_assert(intro
!= NULL
);
2972 if (intro
->time_published
== -1) {
2973 /* Don't expire an intro point if we haven't even published it yet. */
2977 if (intro
->time_expiring
!= -1) {
2978 /* We've already started expiring this intro point. *Don't* let
2979 * this function's result 'flap'. */
2983 if (intro_point_accepted_intro_count(intro
) >=
2984 INTRO_POINT_LIFETIME_INTRODUCTIONS
) {
2985 /* This intro point has been used too many times. Expire it now. */
2989 if (intro
->time_to_expire
== -1) {
2990 /* This intro point has been published, but we haven't picked an
2991 * expiration time for it. Pick one now. */
2992 int intro_point_lifetime_seconds
=
2993 INTRO_POINT_LIFETIME_MIN_SECONDS
+
2994 crypto_rand_int(INTRO_POINT_LIFETIME_MAX_SECONDS
-
2995 INTRO_POINT_LIFETIME_MIN_SECONDS
);
2997 /* Start the expiration timer now, rather than when the intro
2998 * point was first published. There shouldn't be much of a time
3000 intro
->time_to_expire
= now
+ intro_point_lifetime_seconds
;
3005 /* This intro point has a time to expire set already. Use it. */
3006 return (now
>= intro
->time_to_expire
);
3009 /** For every service, check how many intro points it currently has, and:
3010 * - Pick new intro points as necessary.
3011 * - Launch circuits to any new intro points.
3014 rend_services_introduce(void)
3018 rend_service_t
*service
;
3019 rend_intro_point_t
*intro
;
3020 int intro_point_set_changed
, prev_intro_nodes
;
3021 unsigned int n_intro_points_unexpired
;
3022 unsigned int n_intro_points_to_open
;
3023 smartlist_t
*intro_nodes
;
3025 const or_options_t
*options
= get_options();
3027 intro_nodes
= smartlist_new();
3030 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
3031 smartlist_clear(intro_nodes
);
3032 service
= smartlist_get(rend_service_list
, i
);
3034 tor_assert(service
);
3036 /* intro_point_set_changed becomes non-zero iff the set of intro
3037 * points to be published in service's descriptor has changed. */
3038 intro_point_set_changed
= 0;
3040 /* n_intro_points_unexpired collects the number of non-expiring
3041 * intro points we have, so that we know how many new intro
3042 * circuits we need to launch for this service. */
3043 n_intro_points_unexpired
= 0;
3045 if (now
> service
->intro_period_started
+INTRO_CIRC_RETRY_PERIOD
) {
3046 /* One period has elapsed; we can try building circuits again. */
3047 service
->intro_period_started
= now
;
3048 service
->n_intro_circuits_launched
= 0;
3049 } else if (service
->n_intro_circuits_launched
>=
3050 MAX_INTRO_CIRCS_PER_PERIOD
) {
3051 /* We have failed too many times in this period; wait for the next
3052 * one before we try again. */
3056 /* Find out which introduction points we have in progress for this
3058 SMARTLIST_FOREACH_BEGIN(service
->intro_nodes
, rend_intro_point_t
*,
3060 origin_circuit_t
*intro_circ
=
3061 find_intro_circuit(intro
, service
->pk_digest
);
3063 if (intro
->time_expiring
+ INTRO_POINT_EXPIRATION_GRACE_PERIOD
> now
) {
3064 /* This intro point has completely expired. Remove it, and
3065 * mark the circuit for close if it's still alive. */
3066 if (intro_circ
!= NULL
&&
3067 intro_circ
->base_
.purpose
!= CIRCUIT_PURPOSE_PATH_BIAS_TESTING
) {
3068 circuit_mark_for_close(TO_CIRCUIT(intro_circ
),
3069 END_CIRC_REASON_FINISHED
);
3071 rend_intro_point_free(intro
);
3072 intro
= NULL
; /* SMARTLIST_DEL_CURRENT takes a name, not a value. */
3073 SMARTLIST_DEL_CURRENT(service
->intro_nodes
, intro
);
3074 /* We don't need to set intro_point_set_changed here, because
3075 * this intro point wouldn't have been published in a current
3076 * descriptor anyway. */
3080 node
= node_get_by_id(intro
->extend_info
->identity_digest
);
3081 if (!node
|| !intro_circ
) {
3082 int removing_this_intro_point_changes_the_intro_point_set
= 1;
3083 log_info(LD_REND
, "Giving up on %s as intro point for %s"
3084 " (circuit disappeared).",
3085 safe_str_client(extend_info_describe(intro
->extend_info
)),
3086 safe_str_client(service
->service_id
));
3087 rend_service_note_removing_intro_point(service
, intro
);
3088 if (intro
->time_expiring
!= -1) {
3089 log_info(LD_REND
, "We were already expiring the intro point; "
3090 "no need to mark the HS descriptor as dirty over this.");
3091 removing_this_intro_point_changes_the_intro_point_set
= 0;
3092 } else if (intro
->listed_in_last_desc
) {
3093 log_info(LD_REND
, "The intro point we are giving up on was "
3094 "included in the last published descriptor. "
3095 "Marking current descriptor as dirty.");
3096 service
->desc_is_dirty
= now
;
3098 rend_intro_point_free(intro
);
3099 intro
= NULL
; /* SMARTLIST_DEL_CURRENT takes a name, not a value. */
3100 SMARTLIST_DEL_CURRENT(service
->intro_nodes
, intro
);
3101 if (removing_this_intro_point_changes_the_intro_point_set
)
3102 intro_point_set_changed
= 1;
3105 if (intro
!= NULL
&& intro_point_should_expire_now(intro
, now
)) {
3106 log_info(LD_REND
, "Expiring %s as intro point for %s.",
3107 safe_str_client(extend_info_describe(intro
->extend_info
)),
3108 safe_str_client(service
->service_id
));
3110 rend_service_note_removing_intro_point(service
, intro
);
3112 /* The polite (and generally Right) way to expire an intro
3113 * point is to establish a new one to replace it, publish a
3114 * new descriptor that doesn't list any expiring intro points,
3115 * and *then*, once our upload attempts for the new descriptor
3116 * have ended (whether in success or failure), close the
3117 * expiring intro points.
3119 * Unfortunately, we can't find out when the new descriptor
3120 * has actually been uploaded, so we'll have to settle for a
3121 * five-minute timer. Start it. XXXX024 This sucks. */
3122 intro
->time_expiring
= now
;
3124 intro_point_set_changed
= 1;
3127 if (intro
!= NULL
&& intro
->time_expiring
== -1)
3128 ++n_intro_points_unexpired
;
3131 smartlist_add(intro_nodes
, (void*)node
);
3132 } SMARTLIST_FOREACH_END(intro
);
3134 if (!intro_point_set_changed
&&
3135 (n_intro_points_unexpired
>= service
->n_intro_points_wanted
)) {
3139 /* Remember how many introduction circuits we started with.
3141 * prev_intro_nodes serves a different purpose than
3142 * n_intro_points_unexpired -- this variable tells us where our
3143 * previously-created intro points end and our new ones begin in
3144 * the intro-point list, so we don't have to launch the circuits
3145 * at the same time as we create the intro points they correspond
3146 * to. XXXX This is daft. */
3147 prev_intro_nodes
= smartlist_len(service
->intro_nodes
);
3149 /* We have enough directory information to start establishing our
3150 * intro points. We want to end up with n_intro_points_wanted
3151 * intro points, but if we're just starting, we launch two extra
3152 * circuits and use the first n_intro_points_wanted that complete.
3154 * The ones after the first three will be converted to 'general'
3155 * internal circuits in rend_service_intro_has_opened(), and then
3156 * we'll drop them from the list of intro points next time we
3157 * go through the above "find out which introduction points we have
3158 * in progress" loop. */
3159 n_intro_points_to_open
= (service
->n_intro_points_wanted
+
3160 (prev_intro_nodes
== 0 ? 2 : 0));
3161 for (j
= (int)n_intro_points_unexpired
;
3162 j
< (int)n_intro_points_to_open
;
3163 ++j
) { /* XXXX remove casts */
3164 router_crn_flags_t flags
= CRN_NEED_UPTIME
|CRN_NEED_DESC
;
3165 if (get_options()->AllowInvalid_
& ALLOW_INVALID_INTRODUCTION
)
3166 flags
|= CRN_ALLOW_INVALID
;
3167 node
= router_choose_random_node(intro_nodes
,
3168 options
->ExcludeNodes
, flags
);
3171 "Could only establish %d introduction points for %s; "
3173 smartlist_len(service
->intro_nodes
), service
->service_id
,
3174 n_intro_points_to_open
);
3177 intro_point_set_changed
= 1;
3178 smartlist_add(intro_nodes
, (void*)node
);
3179 intro
= tor_malloc_zero(sizeof(rend_intro_point_t
));
3180 intro
->extend_info
= extend_info_from_node(node
, 0);
3181 intro
->intro_key
= crypto_pk_new();
3182 tor_assert(!crypto_pk_generate_key(intro
->intro_key
));
3183 intro
->time_published
= -1;
3184 intro
->time_to_expire
= -1;
3185 intro
->time_expiring
= -1;
3186 smartlist_add(service
->intro_nodes
, intro
);
3187 log_info(LD_REND
, "Picked router %s as an intro point for %s.",
3188 safe_str_client(node_describe(node
)),
3189 safe_str_client(service
->service_id
));
3192 /* If there's no need to launch new circuits, stop here. */
3193 if (!intro_point_set_changed
)
3196 /* Establish new introduction points. */
3197 for (j
=prev_intro_nodes
; j
< smartlist_len(service
->intro_nodes
); ++j
) {
3198 intro
= smartlist_get(service
->intro_nodes
, j
);
3199 r
= rend_service_launch_establish_intro(service
, intro
);
3201 log_warn(LD_REND
, "Error launching circuit to node %s for service %s.",
3202 safe_str_client(extend_info_describe(intro
->extend_info
)),
3203 safe_str_client(service
->service_id
));
3207 smartlist_free(intro_nodes
);
3210 /** Regenerate and upload rendezvous service descriptors for all
3211 * services, if necessary. If the descriptor has been dirty enough
3212 * for long enough, definitely upload; else only upload when the
3213 * periodic timeout has expired.
3215 * For the first upload, pick a random time between now and two periods
3216 * from now, and pick it independently for each service.
3219 rend_consider_services_upload(time_t now
)
3222 rend_service_t
*service
;
3223 int rendpostperiod
= get_options()->RendPostPeriod
;
3225 if (!get_options()->PublishHidServDescriptors
)
3228 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
3229 service
= smartlist_get(rend_service_list
, i
);
3230 if (!service
->next_upload_time
) { /* never been uploaded yet */
3231 /* The fixed lower bound of 30 seconds ensures that the descriptor
3232 * is stable before being published. See comment below. */
3233 service
->next_upload_time
=
3234 now
+ 30 + crypto_rand_int(2*rendpostperiod
);
3236 if (service
->next_upload_time
< now
||
3237 (service
->desc_is_dirty
&&
3238 service
->desc_is_dirty
< now
-30)) {
3239 /* if it's time, or if the directory servers have a wrong service
3240 * descriptor and ours has been stable for 30 seconds, upload a
3241 * new one of each format. */
3242 rend_service_update_descriptor(service
);
3243 upload_service_descriptor(service
);
3248 /** True if the list of available router descriptors might have changed so
3249 * that we should have a look whether we can republish previously failed
3250 * rendezvous service descriptors. */
3251 static int consider_republishing_rend_descriptors
= 1;
3253 /** Called when our internal view of the directory has changed, so that we
3254 * might have router descriptors of hidden service directories available that
3255 * we did not have before. */
3257 rend_hsdir_routers_changed(void)
3259 consider_republishing_rend_descriptors
= 1;
3262 /** Consider republication of v2 rendezvous service descriptors that failed
3263 * previously, but without regenerating descriptor contents.
3266 rend_consider_descriptor_republication(void)
3269 rend_service_t
*service
;
3271 if (!consider_republishing_rend_descriptors
)
3273 consider_republishing_rend_descriptors
= 0;
3275 if (!get_options()->PublishHidServDescriptors
)
3278 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
3279 service
= smartlist_get(rend_service_list
, i
);
3280 if (service
->desc
&& !service
->desc
->all_uploads_performed
) {
3281 /* If we failed in uploading a descriptor last time, try again *without*
3282 * updating the descriptor's contents. */
3283 upload_service_descriptor(service
);
3288 /** Log the status of introduction points for all rendezvous services
3289 * at log severity <b>severity</b>.
3292 rend_service_dump_stats(int severity
)
3295 rend_service_t
*service
;
3296 rend_intro_point_t
*intro
;
3297 const char *safe_name
;
3298 origin_circuit_t
*circ
;
3300 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
3301 service
= smartlist_get(rend_service_list
, i
);
3302 tor_log(severity
, LD_GENERAL
, "Service configured in \"%s\":",
3303 service
->directory
);
3304 for (j
=0; j
< smartlist_len(service
->intro_nodes
); ++j
) {
3305 intro
= smartlist_get(service
->intro_nodes
, j
);
3306 safe_name
= safe_str_client(intro
->extend_info
->nickname
);
3308 circ
= find_intro_circuit(intro
, service
->pk_digest
);
3310 tor_log(severity
, LD_GENERAL
, " Intro point %d at %s: no circuit",
3314 tor_log(severity
, LD_GENERAL
, " Intro point %d at %s: circuit is %s",
3315 j
, safe_name
, circuit_state_to_string(circ
->base_
.state
));
3320 /** Given <b>conn</b>, a rendezvous exit stream, look up the hidden service for
3321 * 'circ', and look up the port and address based on conn-\>port.
3322 * Assign the actual conn-\>addr and conn-\>port. Return -1 if failure,
3326 rend_service_set_connection_addr_port(edge_connection_t
*conn
,
3327 origin_circuit_t
*circ
)
3329 rend_service_t
*service
;
3330 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
3331 smartlist_t
*matching_ports
;
3332 rend_service_port_config_t
*chosen_port
;
3334 tor_assert(circ
->base_
.purpose
== CIRCUIT_PURPOSE_S_REND_JOINED
);
3335 tor_assert(circ
->rend_data
);
3336 log_debug(LD_REND
,"beginning to hunt for addr/port");
3337 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+1,
3338 circ
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
3339 service
= rend_service_get_by_pk_digest(
3340 circ
->rend_data
->rend_pk_digest
);
3342 log_warn(LD_REND
, "Couldn't find any service associated with pk %s on "
3343 "rendezvous circuit %u; closing.",
3344 serviceid
, (unsigned)circ
->base_
.n_circ_id
);
3347 matching_ports
= smartlist_new();
3348 SMARTLIST_FOREACH(service
->ports
, rend_service_port_config_t
*, p
,
3350 if (conn
->base_
.port
== p
->virtual_port
) {
3351 smartlist_add(matching_ports
, p
);
3354 chosen_port
= smartlist_choose(matching_ports
);
3355 smartlist_free(matching_ports
);
3357 tor_addr_copy(&conn
->base_
.addr
, &chosen_port
->real_addr
);
3358 conn
->base_
.port
= chosen_port
->real_port
;
3361 log_info(LD_REND
, "No virtual port mapping exists for port %d on service %s",
3362 conn
->base_
.port
,serviceid
);