1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2 * Copyright (c) 2007-2016, 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 "circpathbias.h"
14 #include "circuitbuild.h"
15 #include "circuitlist.h"
16 #include "circuituse.h"
19 #include "directory.h"
21 #include "networkstatus.h"
24 #include "rendclient.h"
25 #include "rendcommon.h"
26 #include "rendservice.h"
30 #include "replaycache.h"
31 #include "routerlist.h"
32 #include "routerparse.h"
33 #include "routerset.h"
35 struct rend_service_t
;
36 static origin_circuit_t
*find_intro_circuit(rend_intro_point_t
*intro
,
37 const char *pk_digest
);
38 static rend_intro_point_t
*find_intro_point(origin_circuit_t
*circ
);
39 static rend_intro_point_t
*find_expiring_intro_point(
40 struct rend_service_t
*service
, origin_circuit_t
*circ
);
42 static extend_info_t
*find_rp_for_intro(
43 const rend_intro_cell_t
*intro
,
46 static int intro_point_accepted_intro_count(rend_intro_point_t
*intro
);
47 static int intro_point_should_expire_now(rend_intro_point_t
*intro
,
49 static int rend_service_derive_key_digests(struct rend_service_t
*s
);
50 static int rend_service_load_keys(struct rend_service_t
*s
);
51 static int rend_service_load_auth_keys(struct rend_service_t
*s
,
53 static struct rend_service_t
*rend_service_get_by_pk_digest(
55 static struct rend_service_t
*rend_service_get_by_service_id(const char *id
);
56 static const char *rend_service_escaped_dir(
57 const struct rend_service_t
*s
);
59 static ssize_t
rend_service_parse_intro_for_v0_or_v1(
60 rend_intro_cell_t
*intro
,
64 static ssize_t
rend_service_parse_intro_for_v2(
65 rend_intro_cell_t
*intro
,
69 static ssize_t
rend_service_parse_intro_for_v3(
70 rend_intro_cell_t
*intro
,
75 /** Represents the mapping from a virtual port of a rendezvous service to
76 * a real port on some IP.
78 struct rend_service_port_config_s
{
79 /* The incoming HS virtual port we're mapping */
80 uint16_t virtual_port
;
81 /* Is this an AF_UNIX port? */
82 unsigned int is_unix_addr
:1;
83 /* The outgoing TCP port to use, if !is_unix_addr */
85 /* The outgoing IPv4 or IPv6 address to use, if !is_unix_addr */
87 /* The socket path to connect to, if is_unix_addr */
88 char unix_addr
[FLEXIBLE_ARRAY_MEMBER
];
91 /** Try to maintain this many intro points per service by default. */
92 #define NUM_INTRO_POINTS_DEFAULT 3
93 /** Maximum number of intro points per service. */
94 #define NUM_INTRO_POINTS_MAX 10
95 /** Number of extra intro points we launch if our set of intro nodes is
96 * empty. See proposal 155, section 4. */
97 #define NUM_INTRO_POINTS_EXTRA 2
99 /** If we can't build our intro circuits, don't retry for this long. */
100 #define INTRO_CIRC_RETRY_PERIOD (60*5)
101 /** Don't try to build more than this many circuits before giving up
103 #define MAX_INTRO_CIRCS_PER_PERIOD 10
104 /** How many times will a hidden service operator attempt to connect to
105 * a requested rendezvous point before giving up? */
106 #define MAX_REND_FAILURES 1
107 /** How many seconds should we spend trying to connect to a requested
108 * rendezvous point before giving up? */
109 #define MAX_REND_TIMEOUT 30
111 /* Hidden service directory file names:
112 * new file names should be added to rend_service_add_filenames_to_list()
113 * for sandboxing purposes. */
114 static const char *private_key_fname
= "private_key";
115 static const char *hostname_fname
= "hostname";
116 static const char *client_keys_fname
= "client_keys";
117 static const char *sos_poison_fname
= "onion_service_non_anonymous";
119 /** Returns a escaped string representation of the service, <b>s</b>.
122 rend_service_escaped_dir(const struct rend_service_t
*s
)
124 return (s
->directory
) ? escaped(s
->directory
) : "[EPHEMERAL]";
127 /** A list of rend_service_t's for services run on this OP.
129 static smartlist_t
*rend_service_list
= NULL
;
131 /** Return the number of rendezvous services we have configured. */
133 num_rend_services(void)
135 if (!rend_service_list
)
137 return smartlist_len(rend_service_list
);
140 /** Helper: free storage held by a single service authorized client entry. */
142 rend_authorized_client_free(rend_authorized_client_t
*client
)
146 if (client
->client_key
)
147 crypto_pk_free(client
->client_key
);
148 if (client
->client_name
)
149 memwipe(client
->client_name
, 0, strlen(client
->client_name
));
150 tor_free(client
->client_name
);
151 memwipe(client
->descriptor_cookie
, 0, sizeof(client
->descriptor_cookie
));
155 /** Helper for strmap_free. */
157 rend_authorized_client_strmap_item_free(void *authorized_client
)
159 rend_authorized_client_free(authorized_client
);
162 /** Release the storage held by <b>service</b>.
165 rend_service_free(rend_service_t
*service
)
170 tor_free(service
->directory
);
171 if (service
->ports
) {
172 SMARTLIST_FOREACH(service
->ports
, rend_service_port_config_t
*, p
,
173 rend_service_port_config_free(p
));
174 smartlist_free(service
->ports
);
176 if (service
->private_key
)
177 crypto_pk_free(service
->private_key
);
178 if (service
->intro_nodes
) {
179 SMARTLIST_FOREACH(service
->intro_nodes
, rend_intro_point_t
*, intro
,
180 rend_intro_point_free(intro
););
181 smartlist_free(service
->intro_nodes
);
183 if (service
->expiring_nodes
) {
184 SMARTLIST_FOREACH(service
->expiring_nodes
, rend_intro_point_t
*, intro
,
185 rend_intro_point_free(intro
););
186 smartlist_free(service
->expiring_nodes
);
189 rend_service_descriptor_free(service
->desc
);
190 if (service
->clients
) {
191 SMARTLIST_FOREACH(service
->clients
, rend_authorized_client_t
*, c
,
192 rend_authorized_client_free(c
););
193 smartlist_free(service
->clients
);
195 if (service
->accepted_intro_dh_parts
) {
196 replaycache_free(service
->accepted_intro_dh_parts
);
201 /** Release all the storage held in rend_service_list.
204 rend_service_free_all(void)
206 if (!rend_service_list
)
209 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, ptr
,
210 rend_service_free(ptr
));
211 smartlist_free(rend_service_list
);
212 rend_service_list
= NULL
;
215 /** Validate <b>service</b> and add it to rend_service_list if possible.
216 * Return 0 on success. On failure, free <b>service</b> and return -1.
219 rend_add_service(rend_service_t
*service
)
222 rend_service_port_config_t
*p
;
224 service
->intro_nodes
= smartlist_new();
225 service
->expiring_nodes
= smartlist_new();
227 if (service
->max_streams_per_circuit
< 0) {
228 log_warn(LD_CONFIG
, "Hidden service (%s) configured with negative max "
229 "streams per circuit; ignoring.",
230 rend_service_escaped_dir(service
));
231 rend_service_free(service
);
235 if (service
->max_streams_close_circuit
< 0 ||
236 service
->max_streams_close_circuit
> 1) {
237 log_warn(LD_CONFIG
, "Hidden service (%s) configured with invalid "
238 "max streams handling; ignoring.",
239 rend_service_escaped_dir(service
));
240 rend_service_free(service
);
244 if (service
->auth_type
!= REND_NO_AUTH
&&
245 smartlist_len(service
->clients
) == 0) {
246 log_warn(LD_CONFIG
, "Hidden service (%s) with client authorization but no "
247 "clients; ignoring.",
248 rend_service_escaped_dir(service
));
249 rend_service_free(service
);
253 if (!smartlist_len(service
->ports
)) {
254 log_warn(LD_CONFIG
, "Hidden service (%s) with no ports configured; "
256 rend_service_escaped_dir(service
));
257 rend_service_free(service
);
261 /* XXX This duplicate check has two problems:
263 * a) It's O(n^2), but the same comment from the bottom of
264 * rend_config_services() should apply.
266 * b) We only compare directory paths as strings, so we can't
267 * detect two distinct paths that specify the same directory
268 * (which can arise from symlinks, case-insensitivity, bind
271 * It also can't detect that two separate Tor instances are trying
272 * to use the same HiddenServiceDir; for that, we would need a
273 * lock file. But this is enough to detect a simple mistake that
274 * at least one person has actually made.
276 if (service
->directory
!= NULL
) { /* Skip dupe for ephemeral services. */
277 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, ptr
,
279 !strcmp(ptr
->directory
, service
->directory
));
281 log_warn(LD_REND
, "Another hidden service is already configured for "
282 "directory %s, ignoring.",
283 rend_service_escaped_dir(service
));
284 rend_service_free(service
);
288 smartlist_add(rend_service_list
, service
);
289 log_debug(LD_REND
,"Configuring service with directory \"%s\"",
291 for (i
= 0; i
< smartlist_len(service
->ports
); ++i
) {
292 p
= smartlist_get(service
->ports
, i
);
293 if (!(p
->is_unix_addr
)) {
295 "Service maps port %d to %s",
297 fmt_addrport(&p
->real_addr
, p
->real_port
));
301 "Service maps port %d to socket at \"%s\"",
302 p
->virtual_port
, p
->unix_addr
);
305 "Service maps port %d to an AF_UNIX socket, but we "
306 "have no AF_UNIX support on this platform. This is "
309 #endif /* defined(HAVE_SYS_UN_H) */
317 /** Return a new rend_service_port_config_t with its path set to
318 * <b>socket_path</b> or empty if <b>socket_path</b> is NULL */
319 static rend_service_port_config_t
*
320 rend_service_port_config_new(const char *socket_path
)
323 return tor_malloc_zero(sizeof(rend_service_port_config_t
) + 1);
325 const size_t pathlen
= strlen(socket_path
) + 1;
326 rend_service_port_config_t
*conf
=
327 tor_malloc_zero(sizeof(rend_service_port_config_t
) + pathlen
);
328 memcpy(conf
->unix_addr
, socket_path
, pathlen
);
329 conf
->is_unix_addr
= 1;
333 /** Parses a real-port to virtual-port mapping separated by the provided
334 * separator and returns a new rend_service_port_config_t, or NULL and an
335 * optional error string on failure.
337 * The format is: VirtualPort SEP (IP|RealPort|IP:RealPort|'socket':path)?
339 * IP defaults to 127.0.0.1; RealPort defaults to VirtualPort.
341 rend_service_port_config_t
*
342 rend_service_parse_port_config(const char *string
, const char *sep
,
350 const char *addrport
;
351 rend_service_port_config_t
*result
= NULL
;
352 unsigned int is_unix_addr
= 0;
353 char *socket_path
= NULL
;
354 char *err_msg
= NULL
;
356 sl
= smartlist_new();
357 smartlist_split_string(sl
, string
, sep
,
358 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
359 if (smartlist_len(sl
) < 1 || smartlist_len(sl
) > 2) {
361 err_msg
= tor_strdup("Bad syntax in hidden service port configuration.");
366 virtport
= (int)tor_parse_long(smartlist_get(sl
,0), 10, 1, 65535, NULL
,NULL
);
369 tor_asprintf(&err_msg
, "Missing or invalid port %s in hidden service "
370 "port configuration", escaped(smartlist_get(sl
,0)));
375 if (smartlist_len(sl
) == 1) {
376 /* No addr:port part; use default. */
378 tor_addr_from_ipv4h(&addr
, 0x7F000001u
); /* 127.0.0.1 */
382 addrport
= smartlist_get(sl
,1);
383 ret
= config_parse_unix_port(addrport
, &socket_path
);
384 if (ret
< 0 && ret
!= -ENOENT
) {
387 err_msg
= tor_strdup("Empty socket path in hidden service port "
394 } else if (strchr(addrport
, ':') || strchr(addrport
, '.')) {
395 /* else try it as an IP:port pair if it has a : or . in it */
396 if (tor_addr_port_lookup(addrport
, &addr
, &p
)<0) {
398 err_msg
= tor_strdup("Unparseable address in hidden service port "
403 realport
= p
?p
:virtport
;
405 /* No addr:port, no addr -- must be port. */
406 realport
= (int)tor_parse_long(addrport
, 10, 1, 65535, NULL
, NULL
);
409 tor_asprintf(&err_msg
, "Unparseable or out-of-range port %s in "
410 "hidden service port configuration.",
415 tor_addr_from_ipv4h(&addr
, 0x7F000001u
); /* Default to 127.0.0.1 */
419 /* Allow room for unix_addr */
420 result
= rend_service_port_config_new(socket_path
);
421 result
->virtual_port
= virtport
;
422 result
->is_unix_addr
= is_unix_addr
;
424 result
->real_port
= realport
;
425 tor_addr_copy(&result
->real_addr
, &addr
);
426 result
->unix_addr
[0] = '\0';
430 if (err_msg_out
) *err_msg_out
= err_msg
;
431 SMARTLIST_FOREACH(sl
, char *, c
, tor_free(c
));
433 if (socket_path
) tor_free(socket_path
);
438 /** Release all storage held in a rend_service_port_config_t. */
440 rend_service_port_config_free(rend_service_port_config_t
*p
)
445 /** Set up rend_service_list, based on the values of HiddenServiceDir and
446 * HiddenServicePort in <b>options</b>. Return 0 on success and -1 on
447 * failure. (If <b>validate_only</b> is set, parse, warn and return as
448 * normal, but don't actually change the configured services.)
451 rend_config_services(const or_options_t
*options
, int validate_only
)
454 rend_service_t
*service
= NULL
;
455 rend_service_port_config_t
*portcfg
;
456 smartlist_t
*old_service_list
= NULL
;
459 if (!validate_only
) {
460 old_service_list
= rend_service_list
;
461 rend_service_list
= smartlist_new();
464 for (line
= options
->RendConfigLines
; line
; line
= line
->next
) {
465 if (!strcasecmp(line
->key
, "HiddenServiceDir")) {
466 if (service
) { /* register the one we just finished parsing */
468 rend_service_free(service
);
470 rend_add_service(service
);
472 service
= tor_malloc_zero(sizeof(rend_service_t
));
473 service
->directory
= tor_strdup(line
->value
);
474 service
->ports
= smartlist_new();
475 service
->intro_period_started
= time(NULL
);
476 service
->n_intro_points_wanted
= NUM_INTRO_POINTS_DEFAULT
;
480 log_warn(LD_CONFIG
, "%s with no preceding HiddenServiceDir directive",
482 rend_service_free(service
);
485 if (!strcasecmp(line
->key
, "HiddenServicePort")) {
486 char *err_msg
= NULL
;
487 portcfg
= rend_service_parse_port_config(line
->value
, " ", &err_msg
);
490 log_warn(LD_CONFIG
, "%s", err_msg
);
492 rend_service_free(service
);
495 tor_assert(!err_msg
);
496 smartlist_add(service
->ports
, portcfg
);
497 } else if (!strcasecmp(line
->key
, "HiddenServiceAllowUnknownPorts")) {
498 service
->allow_unknown_ports
= (int)tor_parse_long(line
->value
,
499 10, 0, 1, &ok
, NULL
);
502 "HiddenServiceAllowUnknownPorts should be 0 or 1, not %s",
504 rend_service_free(service
);
508 "HiddenServiceAllowUnknownPorts=%d for %s",
509 (int)service
->allow_unknown_ports
, service
->directory
);
510 } else if (!strcasecmp(line
->key
,
511 "HiddenServiceDirGroupReadable")) {
512 service
->dir_group_readable
= (int)tor_parse_long(line
->value
,
513 10, 0, 1, &ok
, NULL
);
516 "HiddenServiceDirGroupReadable should be 0 or 1, not %s",
518 rend_service_free(service
);
522 "HiddenServiceDirGroupReadable=%d for %s",
523 service
->dir_group_readable
, service
->directory
);
524 } else if (!strcasecmp(line
->key
, "HiddenServiceMaxStreams")) {
525 service
->max_streams_per_circuit
= (int)tor_parse_long(line
->value
,
526 10, 0, 65535, &ok
, NULL
);
529 "HiddenServiceMaxStreams should be between 0 and %d, not %s",
531 rend_service_free(service
);
535 "HiddenServiceMaxStreams=%d for %s",
536 service
->max_streams_per_circuit
, service
->directory
);
537 } else if (!strcasecmp(line
->key
, "HiddenServiceMaxStreamsCloseCircuit")) {
538 service
->max_streams_close_circuit
= (int)tor_parse_long(line
->value
,
539 10, 0, 1, &ok
, NULL
);
542 "HiddenServiceMaxStreamsCloseCircuit should be 0 or 1, "
545 rend_service_free(service
);
549 "HiddenServiceMaxStreamsCloseCircuit=%d for %s",
550 (int)service
->max_streams_close_circuit
, service
->directory
);
551 } else if (!strcasecmp(line
->key
, "HiddenServiceNumIntroductionPoints")) {
552 service
->n_intro_points_wanted
=
553 (unsigned int) tor_parse_long(line
->value
, 10,
554 NUM_INTRO_POINTS_DEFAULT
,
555 NUM_INTRO_POINTS_MAX
, &ok
, NULL
);
558 "HiddenServiceNumIntroductionPoints "
559 "should be between %d and %d, not %s",
560 NUM_INTRO_POINTS_DEFAULT
, NUM_INTRO_POINTS_MAX
,
562 rend_service_free(service
);
565 log_info(LD_CONFIG
, "HiddenServiceNumIntroductionPoints=%d for %s",
566 service
->n_intro_points_wanted
, service
->directory
);
567 } else if (!strcasecmp(line
->key
, "HiddenServiceAuthorizeClient")) {
568 /* Parse auth type and comma-separated list of client names and add a
569 * rend_authorized_client_t for each client to the service's list
570 * of authorized clients. */
571 smartlist_t
*type_names_split
, *clients
;
572 const char *authname
;
574 if (service
->auth_type
!= REND_NO_AUTH
) {
575 log_warn(LD_CONFIG
, "Got multiple HiddenServiceAuthorizeClient "
576 "lines for a single service.");
577 rend_service_free(service
);
580 type_names_split
= smartlist_new();
581 smartlist_split_string(type_names_split
, line
->value
, " ", 0, 2);
582 if (smartlist_len(type_names_split
) < 1) {
583 log_warn(LD_BUG
, "HiddenServiceAuthorizeClient has no value. This "
584 "should have been prevented when parsing the "
586 smartlist_free(type_names_split
);
587 rend_service_free(service
);
590 authname
= smartlist_get(type_names_split
, 0);
591 if (!strcasecmp(authname
, "basic")) {
592 service
->auth_type
= REND_BASIC_AUTH
;
593 } else if (!strcasecmp(authname
, "stealth")) {
594 service
->auth_type
= REND_STEALTH_AUTH
;
596 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains "
597 "unrecognized auth-type '%s'. Only 'basic' or 'stealth' "
599 (char *) smartlist_get(type_names_split
, 0));
600 SMARTLIST_FOREACH(type_names_split
, char *, cp
, tor_free(cp
));
601 smartlist_free(type_names_split
);
602 rend_service_free(service
);
605 service
->clients
= smartlist_new();
606 if (smartlist_len(type_names_split
) < 2) {
607 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains "
608 "auth-type '%s', but no client names.",
609 service
->auth_type
== REND_BASIC_AUTH
? "basic" : "stealth");
610 SMARTLIST_FOREACH(type_names_split
, char *, cp
, tor_free(cp
));
611 smartlist_free(type_names_split
);
614 clients
= smartlist_new();
615 smartlist_split_string(clients
, smartlist_get(type_names_split
, 1),
616 ",", SPLIT_SKIP_SPACE
, 0);
617 SMARTLIST_FOREACH(type_names_split
, char *, cp
, tor_free(cp
));
618 smartlist_free(type_names_split
);
619 /* Remove duplicate client names. */
620 num_clients
= smartlist_len(clients
);
621 smartlist_sort_strings(clients
);
622 smartlist_uniq_strings(clients
);
623 if (smartlist_len(clients
) < num_clients
) {
624 log_info(LD_CONFIG
, "HiddenServiceAuthorizeClient contains %d "
625 "duplicate client name(s); removing.",
626 num_clients
- smartlist_len(clients
));
627 num_clients
= smartlist_len(clients
);
629 SMARTLIST_FOREACH_BEGIN(clients
, const char *, client_name
)
631 rend_authorized_client_t
*client
;
632 if (!rend_valid_client_name(client_name
)) {
633 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains an "
634 "illegal client name: '%s'. Names must be "
635 "between 1 and %d characters and contain "
636 "only [A-Za-z0-9+_-].",
637 client_name
, REND_CLIENTNAME_MAX_LEN
);
638 SMARTLIST_FOREACH(clients
, char *, cp
, tor_free(cp
));
639 smartlist_free(clients
);
640 rend_service_free(service
);
643 client
= tor_malloc_zero(sizeof(rend_authorized_client_t
));
644 client
->client_name
= tor_strdup(client_name
);
645 smartlist_add(service
->clients
, client
);
646 log_debug(LD_REND
, "Adding client name '%s'", client_name
);
648 SMARTLIST_FOREACH_END(client_name
);
649 SMARTLIST_FOREACH(clients
, char *, cp
, tor_free(cp
));
650 smartlist_free(clients
);
651 /* Ensure maximum number of clients. */
652 if ((service
->auth_type
== REND_BASIC_AUTH
&&
653 smartlist_len(service
->clients
) > 512) ||
654 (service
->auth_type
== REND_STEALTH_AUTH
&&
655 smartlist_len(service
->clients
) > 16)) {
656 log_warn(LD_CONFIG
, "HiddenServiceAuthorizeClient contains %d "
657 "client authorization entries, but only a "
658 "maximum of %d entries is allowed for "
659 "authorization type '%s'.",
660 smartlist_len(service
->clients
),
661 service
->auth_type
== REND_BASIC_AUTH
? 512 : 16,
662 service
->auth_type
== REND_BASIC_AUTH
? "basic" : "stealth");
663 rend_service_free(service
);
667 tor_assert(!strcasecmp(line
->key
, "HiddenServiceVersion"));
668 if (strcmp(line
->value
, "2")) {
670 "The only supported HiddenServiceVersion is 2.");
671 rend_service_free(service
);
677 cpd_check_t check_opts
= CPD_CHECK_MODE_ONLY
|CPD_CHECK
;
678 if (service
->dir_group_readable
) {
679 check_opts
|= CPD_GROUP_READ
;
682 if (check_private_dir(service
->directory
, check_opts
, options
->User
) < 0) {
683 rend_service_free(service
);
688 rend_service_free(service
);
690 rend_add_service(service
);
694 /* If this is a reload and there were hidden services configured before,
695 * keep the introduction points that are still needed and close the
697 if (old_service_list
&& !validate_only
) {
698 smartlist_t
*surviving_services
= smartlist_new();
700 /* Preserve the existing ephemeral services.
702 * This is the ephemeral service equivalent of the "Copy introduction
703 * points to new services" block, except there's no copy required since
704 * the service structure isn't regenerated.
706 * After this is done, all ephemeral services will be:
707 * * Removed from old_service_list, so the equivalent non-ephemeral code
708 * will not attempt to preserve them.
709 * * Added to the new rend_service_list (that previously only had the
710 * services listed in the configuration).
711 * * Added to surviving_services, which is the list of services that
712 * will NOT have their intro point closed.
714 SMARTLIST_FOREACH(old_service_list
, rend_service_t
*, old
, {
715 if (!old
->directory
) {
716 SMARTLIST_DEL_CURRENT(old_service_list
, old
);
717 smartlist_add(surviving_services
, old
);
718 smartlist_add(rend_service_list
, old
);
722 /* Copy introduction points to new services. */
723 /* XXXX This is O(n^2), but it's only called on reconfigure, so it's
725 SMARTLIST_FOREACH_BEGIN(rend_service_list
, rend_service_t
*, new) {
726 SMARTLIST_FOREACH_BEGIN(old_service_list
, rend_service_t
*, old
) {
727 if (new->directory
&& old
->directory
&&
728 !strcmp(old
->directory
, new->directory
)) {
729 smartlist_add_all(new->intro_nodes
, old
->intro_nodes
);
730 smartlist_clear(old
->intro_nodes
);
731 smartlist_add_all(new->expiring_nodes
, old
->expiring_nodes
);
732 smartlist_clear(old
->expiring_nodes
);
733 smartlist_add(surviving_services
, old
);
736 } SMARTLIST_FOREACH_END(old
);
737 } SMARTLIST_FOREACH_END(new);
739 /* Close introduction circuits of services we don't serve anymore. */
740 /* XXXX it would be nicer if we had a nicer abstraction to use here,
741 * so we could just iterate over the list of services to close, but
742 * once again, this isn't critical-path code. */
743 SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t
*, circ
) {
744 if (!circ
->marked_for_close
&&
745 circ
->state
== CIRCUIT_STATE_OPEN
&&
746 (circ
->purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
||
747 circ
->purpose
== CIRCUIT_PURPOSE_S_INTRO
)) {
748 origin_circuit_t
*oc
= TO_ORIGIN_CIRCUIT(circ
);
750 tor_assert(oc
->rend_data
);
751 SMARTLIST_FOREACH(surviving_services
, rend_service_t
*, ptr
, {
752 if (tor_memeq(ptr
->pk_digest
, oc
->rend_data
->rend_pk_digest
,
760 log_info(LD_REND
, "Closing intro point %s for service %s.",
761 safe_str_client(extend_info_describe(
762 oc
->build_state
->chosen_exit
)),
763 oc
->rend_data
->onion_address
);
764 circuit_mark_for_close(circ
, END_CIRC_REASON_FINISHED
);
765 /* XXXX Is there another reason we should use here? */
768 SMARTLIST_FOREACH_END(circ
);
769 smartlist_free(surviving_services
);
770 SMARTLIST_FOREACH(old_service_list
, rend_service_t
*, ptr
,
771 rend_service_free(ptr
));
772 smartlist_free(old_service_list
);
778 /** Add the ephemeral service <b>pk</b>/<b>ports</b> if possible, using
779 * client authorization <b>auth_type</b> and an optional list of
780 * rend_authorized_client_t in <b>auth_clients</b>, with
781 * <b>max_streams_per_circuit</b> streams allowed per rendezvous circuit,
782 * and circuit closure on max streams being exceeded set by
783 * <b>max_streams_close_circuit</b>.
785 * Ownership of pk, ports, and auth_clients is passed to this routine.
786 * Regardless of success/failure, callers should not touch these values
787 * after calling this routine, and may assume that correct cleanup has
788 * been done on failure.
790 * Return an appropriate rend_service_add_ephemeral_status_t.
792 rend_service_add_ephemeral_status_t
793 rend_service_add_ephemeral(crypto_pk_t
*pk
,
795 int max_streams_per_circuit
,
796 int max_streams_close_circuit
,
797 rend_auth_type_t auth_type
,
798 smartlist_t
*auth_clients
,
799 char **service_id_out
)
801 *service_id_out
= NULL
;
802 /* Allocate the service structure, and initialize the key, and key derived
805 rend_service_t
*s
= tor_malloc_zero(sizeof(rend_service_t
));
806 s
->directory
= NULL
; /* This indicates the service is ephemeral. */
808 s
->auth_type
= auth_type
;
809 s
->clients
= auth_clients
;
811 s
->intro_period_started
= time(NULL
);
812 s
->n_intro_points_wanted
= NUM_INTRO_POINTS_DEFAULT
;
813 s
->max_streams_per_circuit
= max_streams_per_circuit
;
814 s
->max_streams_close_circuit
= max_streams_close_circuit
;
815 if (rend_service_derive_key_digests(s
) < 0) {
816 rend_service_free(s
);
817 return RSAE_BADPRIVKEY
;
820 if (!s
->ports
|| smartlist_len(s
->ports
) == 0) {
821 log_warn(LD_CONFIG
, "At least one VIRTPORT/TARGET must be specified.");
822 rend_service_free(s
);
823 return RSAE_BADVIRTPORT
;
825 if (s
->auth_type
!= REND_NO_AUTH
&&
826 (!s
->clients
|| smartlist_len(s
->clients
) == 0)) {
827 log_warn(LD_CONFIG
, "At least one authorized client must be specified.");
828 rend_service_free(s
);
832 /* Enforcing pk/id uniqueness should be done by rend_service_load_keys(), but
833 * it's not, see #14828.
835 if (rend_service_get_by_pk_digest(s
->pk_digest
)) {
836 log_warn(LD_CONFIG
, "Onion Service private key collides with an "
837 "existing service.");
838 rend_service_free(s
);
839 return RSAE_ADDREXISTS
;
841 if (rend_service_get_by_service_id(s
->service_id
)) {
842 log_warn(LD_CONFIG
, "Onion Service id collides with an existing service.");
843 rend_service_free(s
);
844 return RSAE_ADDREXISTS
;
847 /* Initialize the service. */
848 if (rend_add_service(s
)) {
849 return RSAE_INTERNAL
;
851 *service_id_out
= tor_strdup(s
->service_id
);
853 log_debug(LD_CONFIG
, "Added ephemeral Onion Service: %s", s
->service_id
);
857 /** Remove the ephemeral service <b>service_id</b> if possible. Returns 0 on
858 * success, and -1 on failure.
861 rend_service_del_ephemeral(const char *service_id
)
864 if (!rend_valid_service_id(service_id
)) {
865 log_warn(LD_CONFIG
, "Requested malformed Onion Service id for removal.");
868 if ((s
= rend_service_get_by_service_id(service_id
)) == NULL
) {
869 log_warn(LD_CONFIG
, "Requested non-existent Onion Service id for "
874 log_warn(LD_CONFIG
, "Requested non-ephemeral Onion Service for removal.");
878 /* Kill the intro point circuit for the Onion Service, and remove it from
879 * the list. Closing existing connections is the application's problem.
881 * XXX: As with the comment in rend_config_services(), a nice abstraction
882 * would be ideal here, but for now just duplicate the code.
884 SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t
*, circ
) {
885 if (!circ
->marked_for_close
&&
886 (circ
->purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
||
887 circ
->purpose
== CIRCUIT_PURPOSE_S_INTRO
)) {
888 origin_circuit_t
*oc
= TO_ORIGIN_CIRCUIT(circ
);
889 tor_assert(oc
->rend_data
);
890 if (!tor_memeq(s
->pk_digest
, oc
->rend_data
->rend_pk_digest
, DIGEST_LEN
))
892 log_debug(LD_REND
, "Closing intro point %s for service %s.",
893 safe_str_client(extend_info_describe(
894 oc
->build_state
->chosen_exit
)),
895 oc
->rend_data
->onion_address
);
896 circuit_mark_for_close(circ
, END_CIRC_REASON_FINISHED
);
898 } SMARTLIST_FOREACH_END(circ
);
899 smartlist_remove(rend_service_list
, s
);
900 rend_service_free(s
);
902 log_debug(LD_CONFIG
, "Removed ephemeral Onion Service: %s", service_id
);
907 /** Replace the old value of <b>service</b>-\>desc with one that reflects
908 * the other fields in service.
911 rend_service_update_descriptor(rend_service_t
*service
)
913 rend_service_descriptor_t
*d
;
914 origin_circuit_t
*circ
;
917 rend_service_descriptor_free(service
->desc
);
918 service
->desc
= NULL
;
920 d
= service
->desc
= tor_malloc_zero(sizeof(rend_service_descriptor_t
));
921 d
->pk
= crypto_pk_dup_key(service
->private_key
);
922 d
->timestamp
= time(NULL
);
923 d
->timestamp
-= d
->timestamp
% 3600; /* Round down to nearest hour */
924 d
->intro_nodes
= smartlist_new();
925 /* Support intro protocols 2 and 3. */
926 d
->protocols
= (1 << 2) + (1 << 3);
928 for (i
= 0; i
< smartlist_len(service
->intro_nodes
); ++i
) {
929 rend_intro_point_t
*intro_svc
= smartlist_get(service
->intro_nodes
, i
);
930 rend_intro_point_t
*intro_desc
;
932 /* This intro point won't be listed in the descriptor... */
933 intro_svc
->listed_in_last_desc
= 0;
935 circ
= find_intro_circuit(intro_svc
, service
->pk_digest
);
936 if (!circ
|| circ
->base_
.purpose
!= CIRCUIT_PURPOSE_S_INTRO
) {
937 /* This intro point's circuit isn't finished yet. Don't list it. */
941 /* ...unless this intro point is listed in the descriptor. */
942 intro_svc
->listed_in_last_desc
= 1;
944 /* We have an entirely established intro circuit. Publish it in
946 intro_desc
= tor_malloc_zero(sizeof(rend_intro_point_t
));
947 intro_desc
->extend_info
= extend_info_dup(intro_svc
->extend_info
);
948 if (intro_svc
->intro_key
)
949 intro_desc
->intro_key
= crypto_pk_dup_key(intro_svc
->intro_key
);
950 smartlist_add(d
->intro_nodes
, intro_desc
);
952 if (intro_svc
->time_published
== -1) {
953 /* We are publishing this intro point in a descriptor for the
954 * first time -- note the current time in the service's copy of
955 * the intro point. */
956 intro_svc
->time_published
= time(NULL
);
961 /* Allocate and return a string containing the path to file_name in
962 * service->directory. Asserts that service has a directory.
963 * This function will never return NULL.
964 * The caller must free this path. */
966 rend_service_path(const rend_service_t
*service
, const char *file_name
)
968 char *file_path
= NULL
;
970 tor_assert(service
->directory
);
972 /* Can never fail: asserts rather than leaving file_path NULL. */
973 tor_asprintf(&file_path
, "%s%s%s",
974 service
->directory
, PATH_SEPARATOR
, file_name
);
979 /* Allocate and return a string containing the path to the single onion
980 * service poison file in service->directory. Asserts that service has a
982 * The caller must free this path. */
984 rend_service_sos_poison_path(const rend_service_t
*service
)
986 return rend_service_path(service
, sos_poison_fname
);
989 /** Return True if hidden services <b>service> has been poisoned by single
992 service_is_single_onion_poisoned(const rend_service_t
*service
)
994 char *poison_fname
= NULL
;
995 file_status_t fstatus
;
997 if (!service
->directory
) {
1001 poison_fname
= rend_service_sos_poison_path(service
);
1003 fstatus
= file_status(poison_fname
);
1004 tor_free(poison_fname
);
1006 /* If this fname is occupied, the hidden service has been poisoned. */
1007 if (fstatus
== FN_FILE
|| fstatus
== FN_EMPTY
) {
1014 /* Return 1 if the private key file for service exists and has a non-zero size,
1015 * and 0 otherwise. */
1017 rend_service_private_key_exists(const rend_service_t
*service
)
1019 char *private_key_path
= rend_service_path(service
, private_key_fname
);
1020 const file_status_t private_key_status
= file_status(private_key_path
);
1021 tor_free(private_key_path
);
1022 /* Only non-empty regular private key files could have been used before. */
1023 return private_key_status
== FN_FILE
;
1026 /** Check the single onion service poison state of all existing hidden service
1028 * - If each service is poisoned, and we are in Single Onion Mode,
1030 * - If each service is not poisoned, and we are not in Single Onion Mode,
1032 * - Otherwise, the poison state is invalid, and a service that was created in
1033 * one mode is being used in the other, return -1.
1034 * Hidden service directories without keys are not checked for consistency.
1035 * When their keys are created, they will be poisoned (if needed).
1036 * If a <b>service_list</b> is provided, treat it
1037 * as the list of hidden services (used in unittests). */
1039 rend_service_list_verify_single_onion_poison(const smartlist_t
*service_list
,
1040 const or_options_t
*options
)
1042 const smartlist_t
*s_list
;
1043 /* If no special service list is provided, then just use the global one. */
1044 if (!service_list
) {
1045 if (!rend_service_list
) { /* No global HS list. Nothing to see here. */
1049 s_list
= rend_service_list
;
1051 s_list
= service_list
;
1055 SMARTLIST_FOREACH_BEGIN(s_list
, const rend_service_t
*, s
) {
1056 if (service_is_single_onion_poisoned(s
) !=
1057 rend_service_non_anonymous_mode_enabled(options
) &&
1058 rend_service_private_key_exists(s
)) {
1061 } SMARTLIST_FOREACH_END(s
);
1063 return consistent
? 0 : -1;
1066 /*** Helper for rend_service_poison_new_single_onion_dirs(). Add a file to
1067 * this hidden service directory that marks it as a single onion service.
1068 * Tor must be in single onion mode before calling this function.
1069 * Returns 0 when a directory is successfully poisoned, or if it is already
1070 * poisoned. Returns -1 on a failure to read the directory or write the poison
1071 * file, or if there is an existing private key file in the directory. (The
1072 * service should have been poisoned when the key was created.) */
1074 poison_new_single_onion_hidden_service_dir(const rend_service_t
*service
)
1076 /* We must only poison directories if we're in Single Onion mode */
1077 tor_assert(rend_service_non_anonymous_mode_enabled(get_options()));
1081 char *poison_fname
= NULL
;
1083 if (!service
->directory
) {
1084 log_info(LD_REND
, "Ephemeral HS started in non-anonymous mode.");
1088 /* Make sure we're only poisoning new hidden service directories */
1089 if (rend_service_private_key_exists(service
)) {
1090 log_warn(LD_BUG
, "Tried to single onion poison a service directory after "
1091 "the private key was created.");
1095 poison_fname
= rend_service_sos_poison_path(service
);
1097 switch (file_status(poison_fname
)) {
1100 log_warn(LD_FS
, "Can't read single onion poison file \"%s\"",
1103 case FN_FILE
: /* single onion poison file already exists. NOP. */
1104 case FN_EMPTY
: /* single onion poison file already exists. NOP. */
1105 log_debug(LD_FS
, "Tried to re-poison a single onion poisoned file \"%s\"",
1109 fd
= tor_open_cloexec(poison_fname
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600);
1111 log_warn(LD_FS
, "Could not create single onion poison file %s",
1124 tor_free(poison_fname
);
1129 /** We just got launched in Single Onion Mode. That's a non-anoymous
1130 * mode for hidden services; hence we should mark all new hidden service
1131 * directories appropriately so that they are never launched as
1132 * location-private hidden services again. (New directories don't have private
1134 * If a <b>service_list</b> is provided, treat it as the list of hidden
1135 * services (used in unittests).
1136 * Return 0 on success, -1 on fail. */
1138 rend_service_poison_new_single_onion_dirs(const smartlist_t
*service_list
)
1140 /* We must only poison directories if we're in Single Onion mode */
1141 tor_assert(rend_service_non_anonymous_mode_enabled(get_options()));
1143 const smartlist_t
*s_list
;
1144 /* If no special service list is provided, then just use the global one. */
1145 if (!service_list
) {
1146 if (!rend_service_list
) { /* No global HS list. Nothing to see here. */
1150 s_list
= rend_service_list
;
1152 s_list
= service_list
;
1155 SMARTLIST_FOREACH_BEGIN(s_list
, const rend_service_t
*, s
) {
1156 if (!rend_service_private_key_exists(s
)) {
1157 if (poison_new_single_onion_hidden_service_dir(s
) < 0) {
1161 } SMARTLIST_FOREACH_END(s
);
1163 /* The keys for these services are linked to the server IP address */
1164 log_notice(LD_REND
, "The configured onion service directories have been "
1165 "used in single onion mode. They can not be used for anonymous "
1166 "hidden services.");
1171 /** Load and/or generate private keys for all hidden services, possibly
1172 * including keys for client authorization.
1173 * If a <b>service_list</b> is provided, treat it as the list of hidden
1174 * services (used in unittests). Otherwise, require that rend_service_list is
1176 * Return 0 on success, -1 on failure. */
1178 rend_service_load_all_keys(const smartlist_t
*service_list
)
1180 const smartlist_t
*s_list
;
1181 /* If no special service list is provided, then just use the global one. */
1182 if (!service_list
) {
1183 tor_assert(rend_service_list
);
1184 s_list
= rend_service_list
;
1186 s_list
= service_list
;
1189 SMARTLIST_FOREACH_BEGIN(s_list
, rend_service_t
*, s
) {
1192 log_info(LD_REND
, "Loading hidden-service keys from \"%s\"",
1195 if (rend_service_load_keys(s
) < 0)
1197 } SMARTLIST_FOREACH_END(s
);
1202 /** Add to <b>lst</b> every filename used by <b>s</b>. */
1204 rend_service_add_filenames_to_list(smartlist_t
*lst
, const rend_service_t
*s
)
1208 tor_assert(s
->directory
);
1209 smartlist_add(lst
, rend_service_path(s
, private_key_fname
));
1210 smartlist_add(lst
, rend_service_path(s
, hostname_fname
));
1211 smartlist_add(lst
, rend_service_path(s
, client_keys_fname
));
1212 smartlist_add(lst
, rend_service_sos_poison_path(s
));
1215 /** Add to <b>open_lst</b> every filename used by a configured hidden service,
1216 * and to <b>stat_lst</b> every directory used by a configured hidden
1219 rend_services_add_filenames_to_lists(smartlist_t
*open_lst
,
1220 smartlist_t
*stat_lst
)
1222 if (!rend_service_list
)
1224 SMARTLIST_FOREACH_BEGIN(rend_service_list
, rend_service_t
*, s
) {
1226 rend_service_add_filenames_to_list(open_lst
, s
);
1227 smartlist_add(stat_lst
, tor_strdup(s
->directory
));
1229 } SMARTLIST_FOREACH_END(s
);
1232 /** Derive all rend_service_t internal material based on the service's key.
1233 * Returns 0 on sucess, -1 on failure.
1236 rend_service_derive_key_digests(struct rend_service_t
*s
)
1238 if (rend_get_service_id(s
->private_key
, s
->service_id
)<0) {
1239 log_warn(LD_BUG
, "Internal error: couldn't encode service ID.");
1242 if (crypto_pk_get_digest(s
->private_key
, s
->pk_digest
)<0) {
1243 log_warn(LD_BUG
, "Couldn't compute hash of public key.");
1250 /** Load and/or generate private keys for the hidden service <b>s</b>,
1251 * possibly including keys for client authorization. Return 0 on success, -1
1254 rend_service_load_keys(rend_service_t
*s
)
1258 cpd_check_t check_opts
= CPD_CREATE
;
1260 if (s
->dir_group_readable
) {
1261 check_opts
|= CPD_GROUP_READ
;
1263 /* Check/create directory */
1264 if (check_private_dir(s
->directory
, check_opts
, get_options()->User
) < 0) {
1268 if (s
->dir_group_readable
) {
1269 /* Only new dirs created get new opts, also enforce group read. */
1270 if (chmod(s
->directory
, 0750)) {
1271 log_warn(LD_FS
,"Unable to make %s group-readable.", s
->directory
);
1277 fname
= rend_service_path(s
, private_key_fname
);
1278 s
->private_key
= init_key_from_file(fname
, 1, LOG_ERR
, 0);
1280 if (!s
->private_key
)
1283 if (rend_service_derive_key_digests(s
) < 0)
1287 /* Create service file */
1288 fname
= rend_service_path(s
, hostname_fname
);
1290 tor_snprintf(buf
, sizeof(buf
),"%s.onion\n", s
->service_id
);
1291 if (write_str_to_file(fname
,buf
,0)<0) {
1292 log_warn(LD_CONFIG
, "Could not write onion address to hostname file.");
1296 if (s
->dir_group_readable
) {
1297 /* Also verify hostname file created with group read. */
1298 if (chmod(fname
, 0640))
1299 log_warn(LD_FS
,"Unable to make hidden hostname file %s group-readable.",
1304 /* If client authorization is configured, load or generate keys. */
1305 if (s
->auth_type
!= REND_NO_AUTH
) {
1306 if (rend_service_load_auth_keys(s
, fname
) < 0) {
1316 memwipe(buf
, 0, sizeof(buf
));
1321 /** Load and/or generate client authorization keys for the hidden service
1322 * <b>s</b>, which stores its hostname in <b>hfname</b>. Return 0 on success,
1325 rend_service_load_auth_keys(rend_service_t
*s
, const char *hfname
)
1328 char *cfname
= NULL
;
1329 char *client_keys_str
= NULL
;
1330 strmap_t
*parsed_clients
= strmap_new();
1331 FILE *cfile
, *hfile
;
1332 open_file_t
*open_cfile
= NULL
, *open_hfile
= NULL
;
1333 char desc_cook_out
[3*REND_DESC_COOKIE_LEN_BASE64
+1];
1334 char service_id
[16+1];
1337 /* Load client keys and descriptor cookies, if available. */
1338 cfname
= rend_service_path(s
, client_keys_fname
);
1339 client_keys_str
= read_file_to_str(cfname
, RFTS_IGNORE_MISSING
, NULL
);
1340 if (client_keys_str
) {
1341 if (rend_parse_client_keys(parsed_clients
, client_keys_str
) < 0) {
1342 log_warn(LD_CONFIG
, "Previously stored client_keys file could not "
1346 log_info(LD_CONFIG
, "Parsed %d previously stored client entries.",
1347 strmap_size(parsed_clients
));
1351 /* Prepare client_keys and hostname files. */
1352 if (!(cfile
= start_writing_to_stdio_file(cfname
,
1353 OPEN_FLAGS_REPLACE
| O_TEXT
,
1354 0600, &open_cfile
))) {
1355 log_warn(LD_CONFIG
, "Could not open client_keys file %s",
1360 if (!(hfile
= start_writing_to_stdio_file(hfname
,
1361 OPEN_FLAGS_REPLACE
| O_TEXT
,
1362 0600, &open_hfile
))) {
1363 log_warn(LD_CONFIG
, "Could not open hostname file %s", escaped(hfname
));
1367 /* Either use loaded keys for configured clients or generate new
1368 * ones if a client is new. */
1369 SMARTLIST_FOREACH_BEGIN(s
->clients
, rend_authorized_client_t
*, client
) {
1370 rend_authorized_client_t
*parsed
=
1371 strmap_get(parsed_clients
, client
->client_name
);
1374 /* Copy descriptor cookie from parsed entry or create new one. */
1376 memcpy(client
->descriptor_cookie
, parsed
->descriptor_cookie
,
1377 REND_DESC_COOKIE_LEN
);
1379 crypto_rand((char *) client
->descriptor_cookie
, REND_DESC_COOKIE_LEN
);
1381 /* For compatibility with older tor clients, this does not
1382 * truncate the padding characters, unlike rend_auth_encode_cookie. */
1383 if (base64_encode(desc_cook_out
, 3*REND_DESC_COOKIE_LEN_BASE64
+1,
1384 (char *) client
->descriptor_cookie
,
1385 REND_DESC_COOKIE_LEN
, 0) < 0) {
1386 log_warn(LD_BUG
, "Could not base64-encode descriptor cookie.");
1389 /* Copy client key from parsed entry or create new one if required. */
1390 if (parsed
&& parsed
->client_key
) {
1391 client
->client_key
= crypto_pk_dup_key(parsed
->client_key
);
1392 } else if (s
->auth_type
== REND_STEALTH_AUTH
) {
1393 /* Create private key for client. */
1394 crypto_pk_t
*prkey
= NULL
;
1395 if (!(prkey
= crypto_pk_new())) {
1396 log_warn(LD_BUG
,"Error constructing client key");
1399 if (crypto_pk_generate_key(prkey
)) {
1400 log_warn(LD_BUG
,"Error generating client key");
1401 crypto_pk_free(prkey
);
1404 if (crypto_pk_check_key(prkey
) <= 0) {
1405 log_warn(LD_BUG
,"Generated client key seems invalid");
1406 crypto_pk_free(prkey
);
1409 client
->client_key
= prkey
;
1411 /* Add entry to client_keys file. */
1412 written
= tor_snprintf(buf
, sizeof(buf
),
1413 "client-name %s\ndescriptor-cookie %s\n",
1414 client
->client_name
, desc_cook_out
);
1416 log_warn(LD_BUG
, "Could not write client entry.");
1419 if (client
->client_key
) {
1420 char *client_key_out
= NULL
;
1421 if (crypto_pk_write_private_key_to_string(client
->client_key
,
1422 &client_key_out
, &len
) != 0) {
1423 log_warn(LD_BUG
, "Internal error: "
1424 "crypto_pk_write_private_key_to_string() failed.");
1427 if (rend_get_service_id(client
->client_key
, service_id
)<0) {
1428 log_warn(LD_BUG
, "Internal error: couldn't encode service ID.");
1430 * len is string length, not buffer length, but last byte is NUL
1433 memwipe(client_key_out
, 0, len
);
1434 tor_free(client_key_out
);
1437 written
= tor_snprintf(buf
+ written
, sizeof(buf
) - written
,
1438 "client-key\n%s", client_key_out
);
1439 memwipe(client_key_out
, 0, len
);
1440 tor_free(client_key_out
);
1442 log_warn(LD_BUG
, "Could not write client entry.");
1446 strlcpy(service_id
, s
->service_id
, sizeof(service_id
));
1449 if (fputs(buf
, cfile
) < 0) {
1450 log_warn(LD_FS
, "Could not append client entry to file: %s",
1455 /* Add line to hostname file. This is not the same encoding as in
1457 char *encoded_cookie
= rend_auth_encode_cookie(client
->descriptor_cookie
,
1459 if (!encoded_cookie
) {
1460 log_warn(LD_BUG
, "Could not base64-encode descriptor cookie.");
1463 tor_snprintf(buf
, sizeof(buf
), "%s.onion %s # client: %s\n",
1464 service_id
, encoded_cookie
, client
->client_name
);
1465 memwipe(encoded_cookie
, 0, strlen(encoded_cookie
));
1466 tor_free(encoded_cookie
);
1468 if (fputs(buf
, hfile
)<0) {
1469 log_warn(LD_FS
, "Could not append host entry to file: %s",
1473 } SMARTLIST_FOREACH_END(client
);
1475 finish_writing_to_file(open_cfile
);
1476 finish_writing_to_file(open_hfile
);
1482 abort_writing_to_file(open_cfile
);
1484 abort_writing_to_file(open_hfile
);
1486 if (client_keys_str
) {
1487 memwipe(client_keys_str
, 0, strlen(client_keys_str
));
1488 tor_free(client_keys_str
);
1490 strmap_free(parsed_clients
, rend_authorized_client_strmap_item_free
);
1493 memwipe(cfname
, 0, sizeof(cfname
));
1497 /* Clear stack buffers that held key-derived material. */
1498 memwipe(buf
, 0, sizeof(buf
));
1499 memwipe(desc_cook_out
, 0, sizeof(desc_cook_out
));
1500 memwipe(service_id
, 0, sizeof(service_id
));
1505 /** Return the service whose public key has a digest of <b>digest</b>, or
1506 * NULL if no such service exists.
1508 static rend_service_t
*
1509 rend_service_get_by_pk_digest(const char* digest
)
1511 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, s
,
1512 if (tor_memeq(s
->pk_digest
,digest
,DIGEST_LEN
))
1517 /** Return the service whose service id is <b>id</b>, or NULL if no such
1520 static struct rend_service_t
*
1521 rend_service_get_by_service_id(const char *id
)
1523 tor_assert(strlen(id
) == REND_SERVICE_ID_LEN_BASE32
);
1524 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, s
, {
1525 if (tor_memeq(s
->service_id
, id
, REND_SERVICE_ID_LEN_BASE32
))
1531 /** Return 1 if any virtual port in <b>service</b> wants a circuit
1532 * to have good uptime. Else return 0.
1535 rend_service_requires_uptime(rend_service_t
*service
)
1538 rend_service_port_config_t
*p
;
1540 for (i
=0; i
< smartlist_len(service
->ports
); ++i
) {
1541 p
= smartlist_get(service
->ports
, i
);
1542 if (smartlist_contains_int_as_string(get_options()->LongLivedPorts
,
1549 /** Check client authorization of a given <b>descriptor_cookie</b> of
1550 * length <b>cookie_len</b> for <b>service</b>. Return 1 for success
1551 * and 0 for failure. */
1553 rend_check_authorization(rend_service_t
*service
,
1554 const char *descriptor_cookie
,
1557 rend_authorized_client_t
*auth_client
= NULL
;
1558 tor_assert(service
);
1559 tor_assert(descriptor_cookie
);
1560 if (!service
->clients
) {
1561 log_warn(LD_BUG
, "Can't check authorization for a service that has no "
1562 "authorized clients configured.");
1566 if (cookie_len
!= REND_DESC_COOKIE_LEN
) {
1567 log_info(LD_REND
, "Descriptor cookie is %lu bytes, but we expected "
1568 "%lu bytes. Dropping cell.",
1569 (unsigned long)cookie_len
, (unsigned long)REND_DESC_COOKIE_LEN
);
1573 /* Look up client authorization by descriptor cookie. */
1574 SMARTLIST_FOREACH(service
->clients
, rend_authorized_client_t
*, client
, {
1575 if (tor_memeq(client
->descriptor_cookie
, descriptor_cookie
,
1576 REND_DESC_COOKIE_LEN
)) {
1577 auth_client
= client
;
1582 char descriptor_cookie_base64
[3*REND_DESC_COOKIE_LEN_BASE64
];
1583 base64_encode(descriptor_cookie_base64
, sizeof(descriptor_cookie_base64
),
1584 descriptor_cookie
, REND_DESC_COOKIE_LEN
, 0);
1585 log_info(LD_REND
, "No authorization found for descriptor cookie '%s'! "
1587 descriptor_cookie_base64
);
1591 /* Allow the request. */
1592 log_info(LD_REND
, "Client %s authorized for service %s.",
1593 auth_client
->client_name
, service
->service_id
);
1597 /* Can this service make a direct connection to ei?
1598 * It must be a single onion service, and the firewall rules must allow ei. */
1600 rend_service_use_direct_connection(const or_options_t
* options
,
1601 const extend_info_t
* ei
)
1603 /* We'll connect directly all reachable addresses, whether preferred or not.
1604 * The prefer_ipv6 argument to fascist_firewall_allows_address_addr is
1605 * ignored, because pref_only is 0. */
1606 return (rend_service_allow_non_anonymous_connection(options
) &&
1607 fascist_firewall_allows_address_addr(&ei
->addr
, ei
->port
,
1608 FIREWALL_OR_CONNECTION
, 0, 0));
1611 /* Like rend_service_use_direct_connection, but to a node. */
1613 rend_service_use_direct_connection_node(const or_options_t
* options
,
1616 /* We'll connect directly all reachable addresses, whether preferred or not.
1618 return (rend_service_allow_non_anonymous_connection(options
) &&
1619 fascist_firewall_allows_node(node
, FIREWALL_OR_CONNECTION
, 0));
1626 /** Respond to an INTRODUCE2 cell by launching a circuit to the chosen
1630 rend_service_receive_introduction(origin_circuit_t
*circuit
,
1631 const uint8_t *request
,
1634 /* Global status stuff */
1635 int status
= 0, result
;
1636 const or_options_t
*options
= get_options();
1637 char *err_msg
= NULL
;
1638 int err_msg_severity
= LOG_WARN
;
1639 const char *stage_descr
= NULL
;
1640 int reason
= END_CIRC_REASON_TORPROTOCOL
;
1641 /* Service/circuit/key stuff we can learn before parsing */
1642 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
1643 rend_service_t
*service
= NULL
;
1644 rend_intro_point_t
*intro_point
= NULL
;
1645 crypto_pk_t
*intro_key
= NULL
;
1647 rend_intro_cell_t
*parsed_req
= NULL
;
1648 /* Rendezvous point */
1649 extend_info_t
*rp
= NULL
;
1650 /* XXX not handled yet */
1651 char buf
[RELAY_PAYLOAD_SIZE
];
1652 char keys
[DIGEST_LEN
+CPATH_KEY_MATERIAL_LEN
]; /* Holds KH, Df, Db, Kf, Kb */
1654 crypto_dh_t
*dh
= NULL
;
1655 origin_circuit_t
*launched
= NULL
;
1656 crypt_path_t
*cpath
= NULL
;
1658 int circ_needs_uptime
;
1659 time_t now
= time(NULL
);
1663 /* Do some initial validation and logging before we parse the cell */
1664 if (circuit
->base_
.purpose
!= CIRCUIT_PURPOSE_S_INTRO
) {
1665 log_warn(LD_PROTOCOL
,
1666 "Got an INTRODUCE2 over a non-introduction circuit %u.",
1667 (unsigned) circuit
->base_
.n_circ_id
);
1671 assert_circ_anonymity_ok(circuit
, options
);
1672 tor_assert(circuit
->rend_data
);
1674 /* We'll use this in a bazillion log messages */
1675 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+1,
1676 circuit
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
1678 /* look up service depending on circuit. */
1680 rend_service_get_by_pk_digest(circuit
->rend_data
->rend_pk_digest
);
1683 "Internal error: Got an INTRODUCE2 cell on an intro "
1684 "circ for an unrecognized service %s.",
1685 escaped(serviceid
));
1689 intro_point
= find_intro_point(circuit
);
1690 if (intro_point
== NULL
) {
1691 intro_point
= find_expiring_intro_point(service
, circuit
);
1692 if (intro_point
== NULL
) {
1694 "Internal error: Got an INTRODUCE2 cell on an "
1695 "intro circ (for service %s) with no corresponding "
1696 "rend_intro_point_t.",
1697 escaped(serviceid
));
1702 log_info(LD_REND
, "Received INTRODUCE2 cell for service %s on circ %u.",
1703 escaped(serviceid
), (unsigned)circuit
->base_
.n_circ_id
);
1705 /* use intro key instead of service key. */
1706 intro_key
= circuit
->intro_key
;
1711 stage_descr
= "early parsing";
1712 /* Early parsing pass (get pk, ciphertext); type 2 is INTRODUCE2 */
1714 rend_service_begin_parse_intro(request
, request_len
, 2, &err_msg
);
1717 } else if (err_msg
) {
1718 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1719 (unsigned)circuit
->base_
.n_circ_id
);
1723 /* make sure service replay caches are present */
1724 if (!service
->accepted_intro_dh_parts
) {
1725 service
->accepted_intro_dh_parts
=
1726 replaycache_new(REND_REPLAY_TIME_INTERVAL
,
1727 REND_REPLAY_TIME_INTERVAL
);
1730 if (!intro_point
->accepted_intro_rsa_parts
) {
1731 intro_point
->accepted_intro_rsa_parts
= replaycache_new(0, 0);
1734 /* check for replay of PK-encrypted portion. */
1735 replay
= replaycache_add_test_and_elapsed(
1736 intro_point
->accepted_intro_rsa_parts
,
1737 parsed_req
->ciphertext
, parsed_req
->ciphertext_len
,
1742 "Possible replay detected! We received an "
1743 "INTRODUCE2 cell with same PK-encrypted part %d "
1744 "seconds ago. Dropping cell.",
1749 stage_descr
= "decryption";
1750 /* Now try to decrypt it */
1751 result
= rend_service_decrypt_intro(parsed_req
, intro_key
, &err_msg
);
1754 } else if (err_msg
) {
1755 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1756 (unsigned)circuit
->base_
.n_circ_id
);
1760 stage_descr
= "late parsing";
1761 /* Parse the plaintext */
1762 result
= rend_service_parse_intro_plaintext(parsed_req
, &err_msg
);
1765 } else if (err_msg
) {
1766 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1767 (unsigned)circuit
->base_
.n_circ_id
);
1771 stage_descr
= "late validation";
1772 /* Validate the parsed plaintext parts */
1773 result
= rend_service_validate_intro_late(parsed_req
, &err_msg
);
1776 } else if (err_msg
) {
1777 log_info(LD_REND
, "%s on circ %u.", err_msg
,
1778 (unsigned)circuit
->base_
.n_circ_id
);
1783 /* Increment INTRODUCE2 counter */
1784 ++(intro_point
->accepted_introduce2_count
);
1786 /* Find the rendezvous point */
1787 rp
= find_rp_for_intro(parsed_req
, &err_msg
);
1789 err_msg_severity
= LOG_PROTOCOL_WARN
;
1793 /* Check if we'd refuse to talk to this router */
1794 if (options
->StrictNodes
&&
1795 routerset_contains_extendinfo(options
->ExcludeNodes
, rp
)) {
1796 log_warn(LD_REND
, "Client asked to rendezvous at a relay that we "
1797 "exclude, and StrictNodes is set. Refusing service.");
1798 reason
= END_CIRC_REASON_INTERNAL
; /* XXX might leak why we refused */
1802 base16_encode(hexcookie
, 9, (const char *)(parsed_req
->rc
), 4);
1804 /* Check whether there is a past request with the same Diffie-Hellman,
1806 replay
= replaycache_add_test_and_elapsed(
1807 service
->accepted_intro_dh_parts
,
1808 parsed_req
->dh
, DH_KEY_LEN
,
1812 /* A Tor client will send a new INTRODUCE1 cell with the same rend
1813 * cookie and DH public key as its previous one if its intro circ
1814 * times out while in state CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT .
1815 * If we received the first INTRODUCE1 cell (the intro-point relay
1816 * converts it into an INTRODUCE2 cell), we are already trying to
1817 * connect to that rend point (and may have already succeeded);
1818 * drop this cell. */
1819 log_info(LD_REND
, "We received an "
1820 "INTRODUCE2 cell with same first part of "
1821 "Diffie-Hellman handshake %d seconds ago. Dropping "
1827 /* If the service performs client authorization, check included auth data. */
1828 if (service
->clients
) {
1829 if (parsed_req
->version
== 3 && parsed_req
->u
.v3
.auth_len
> 0) {
1830 if (rend_check_authorization(service
,
1831 (const char*)parsed_req
->u
.v3
.auth_data
,
1832 parsed_req
->u
.v3
.auth_len
)) {
1833 log_info(LD_REND
, "Authorization data in INTRODUCE2 cell are valid.");
1835 log_info(LD_REND
, "The authorization data that are contained in "
1836 "the INTRODUCE2 cell are invalid. Dropping cell.");
1837 reason
= END_CIRC_REASON_CONNECTFAILED
;
1841 log_info(LD_REND
, "INTRODUCE2 cell does not contain authentication "
1842 "data, but we require client authorization. Dropping cell.");
1843 reason
= END_CIRC_REASON_CONNECTFAILED
;
1848 /* Try DH handshake... */
1849 dh
= crypto_dh_new(DH_TYPE_REND
);
1850 if (!dh
|| crypto_dh_generate_public(dh
)<0) {
1851 log_warn(LD_BUG
,"Internal error: couldn't build DH state "
1852 "or generate public key.");
1853 reason
= END_CIRC_REASON_INTERNAL
;
1856 if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN
, dh
,
1857 (char *)(parsed_req
->dh
),
1859 DIGEST_LEN
+CPATH_KEY_MATERIAL_LEN
)<0) {
1860 log_warn(LD_BUG
, "Internal error: couldn't complete DH handshake");
1861 reason
= END_CIRC_REASON_INTERNAL
;
1865 circ_needs_uptime
= rend_service_requires_uptime(service
);
1867 /* help predict this next time */
1868 rep_hist_note_used_internal(now
, circ_needs_uptime
, 1);
1870 /* Launch a circuit to the client's chosen rendezvous point.
1872 for (i
=0;i
<MAX_REND_FAILURES
;i
++) {
1873 int flags
= CIRCLAUNCH_NEED_CAPACITY
| CIRCLAUNCH_IS_INTERNAL
;
1874 if (circ_needs_uptime
) flags
|= CIRCLAUNCH_NEED_UPTIME
;
1875 /* A Single Onion Service only uses a direct connection if its
1876 * firewall rules permit direct connections to the address. */
1877 if (rend_service_use_direct_connection(options
, rp
)) {
1878 flags
= flags
| CIRCLAUNCH_ONEHOP_TUNNEL
;
1880 launched
= circuit_launch_by_extend_info(
1881 CIRCUIT_PURPOSE_S_CONNECT_REND
, rp
, flags
);
1886 if (!launched
) { /* give up */
1887 log_warn(LD_REND
, "Giving up launching first hop of circuit to rendezvous "
1888 "point %s for service %s.",
1889 safe_str_client(extend_info_describe(rp
)),
1891 reason
= END_CIRC_REASON_CONNECTFAILED
;
1895 "Accepted intro; launching circuit to %s "
1896 "(cookie %s) for service %s.",
1897 safe_str_client(extend_info_describe(rp
)),
1898 hexcookie
, serviceid
);
1899 tor_assert(launched
->build_state
);
1900 /* Fill in the circuit's state. */
1902 launched
->rend_data
=
1903 rend_data_service_create(service
->service_id
,
1904 circuit
->rend_data
->rend_pk_digest
,
1905 parsed_req
->rc
, service
->auth_type
);
1907 launched
->build_state
->service_pending_final_cpath_ref
=
1908 tor_malloc_zero(sizeof(crypt_path_reference_t
));
1909 launched
->build_state
->service_pending_final_cpath_ref
->refcount
= 1;
1911 launched
->build_state
->service_pending_final_cpath_ref
->cpath
= cpath
=
1912 tor_malloc_zero(sizeof(crypt_path_t
));
1913 cpath
->magic
= CRYPT_PATH_MAGIC
;
1914 launched
->build_state
->expiry_time
= now
+ MAX_REND_TIMEOUT
;
1916 cpath
->rend_dh_handshake_state
= dh
;
1918 if (circuit_init_cpath_crypto(cpath
,keys
+DIGEST_LEN
,1)<0)
1920 memcpy(cpath
->rend_circ_nonce
, keys
, DIGEST_LEN
);
1927 tor_asprintf(&err_msg
,
1928 "unknown %s error for INTRODUCE2", stage_descr
);
1930 err_msg
= tor_strdup("unknown error for INTRODUCE2");
1934 log_fn(err_msg_severity
, LD_REND
, "%s on circ %u", err_msg
,
1935 (unsigned)circuit
->base_
.n_circ_id
);
1938 if (dh
) crypto_dh_free(dh
);
1940 circuit_mark_for_close(TO_CIRCUIT(launched
), reason
);
1945 memwipe(keys
, 0, sizeof(keys
));
1946 memwipe(buf
, 0, sizeof(buf
));
1947 memwipe(serviceid
, 0, sizeof(serviceid
));
1948 memwipe(hexcookie
, 0, sizeof(hexcookie
));
1950 /* Free the parsed cell */
1951 rend_service_free_intro(parsed_req
);
1954 extend_info_free(rp
);
1959 /** Given a parsed and decrypted INTRODUCE2, find the rendezvous point or
1960 * return NULL and an error string if we can't. Return a newly allocated
1961 * extend_info_t* for the rendezvous point. */
1962 static extend_info_t
*
1963 find_rp_for_intro(const rend_intro_cell_t
*intro
,
1966 extend_info_t
*rp
= NULL
;
1967 char *err_msg
= NULL
;
1968 const char *rp_nickname
= NULL
;
1969 const node_t
*node
= NULL
;
1973 err_msg
= tor_strdup("Bad parameters to find_rp_for_intro()");
1978 if (intro
->version
== 0 || intro
->version
== 1) {
1979 rp_nickname
= (const char *)(intro
->u
.v0_v1
.rp
);
1981 node
= node_get_by_nickname(rp_nickname
, 0);
1984 tor_asprintf(&err_msg
,
1985 "Couldn't find router %s named in INTRODUCE2 cell",
1986 escaped_safe_str_client(rp_nickname
));
1992 /* Are we in single onion mode? */
1993 const int allow_direct
= rend_service_allow_non_anonymous_connection(
1995 rp
= extend_info_from_node(node
, allow_direct
);
1998 tor_asprintf(&err_msg
,
1999 "Couldn't build extend_info_t for router %s named "
2000 "in INTRODUCE2 cell",
2001 escaped_safe_str_client(rp_nickname
));
2006 } else if (intro
->version
== 2) {
2007 rp
= extend_info_dup(intro
->u
.v2
.extend_info
);
2008 } else if (intro
->version
== 3) {
2009 rp
= extend_info_dup(intro
->u
.v3
.extend_info
);
2012 tor_asprintf(&err_msg
,
2013 "Unknown version %d in INTRODUCE2 cell",
2014 (int)(intro
->version
));
2020 /* rp is always set here: extend_info_dup guarantees a non-NULL result, and
2021 * the other cases goto err. */
2024 /* Make sure the RP we are being asked to connect to is _not_ a private
2025 * address unless it's allowed. Let's avoid to build a circuit to our
2026 * second middle node and fail right after when extending to the RP. */
2027 if (!extend_info_addr_is_allowed(&rp
->addr
)) {
2029 tor_asprintf(&err_msg
,
2030 "Relay IP in INTRODUCE2 cell is private address.");
2032 extend_info_free(rp
);
2040 *err_msg_out
= err_msg
;
2048 /** Free a parsed INTRODUCE1 or INTRODUCE2 cell that was allocated by
2049 * rend_service_parse_intro().
2052 rend_service_free_intro(rend_intro_cell_t
*request
)
2058 /* Free ciphertext */
2059 tor_free(request
->ciphertext
);
2060 request
->ciphertext_len
= 0;
2062 /* Have plaintext? */
2063 if (request
->plaintext
) {
2064 /* Zero it out just to be safe */
2065 memwipe(request
->plaintext
, 0, request
->plaintext_len
);
2066 tor_free(request
->plaintext
);
2067 request
->plaintext_len
= 0;
2070 /* Have parsed plaintext? */
2071 if (request
->parsed
) {
2072 switch (request
->version
) {
2076 * Nothing more to do; these formats have no further pointers
2081 extend_info_free(request
->u
.v2
.extend_info
);
2082 request
->u
.v2
.extend_info
= NULL
;
2085 if (request
->u
.v3
.auth_data
) {
2086 memwipe(request
->u
.v3
.auth_data
, 0, request
->u
.v3
.auth_len
);
2087 tor_free(request
->u
.v3
.auth_data
);
2090 extend_info_free(request
->u
.v3
.extend_info
);
2091 request
->u
.v3
.extend_info
= NULL
;
2095 "rend_service_free_intro() saw unknown protocol "
2101 /* Zero it out to make sure sensitive stuff doesn't hang around in memory */
2102 memwipe(request
, 0, sizeof(*request
));
2107 /** Parse an INTRODUCE1 or INTRODUCE2 cell into a newly allocated
2108 * rend_intro_cell_t structure. Free it with rend_service_free_intro()
2109 * when finished. The type parameter should be 1 or 2 to indicate whether
2110 * this is INTRODUCE1 or INTRODUCE2. This parses only the non-encrypted
2111 * parts; after this, call rend_service_decrypt_intro() with a key, then
2112 * rend_service_parse_intro_plaintext() to finish parsing. The optional
2113 * err_msg_out parameter is set to a string suitable for log output
2114 * if parsing fails. This function does some validation, but only
2115 * that which depends solely on the contents of the cell and the
2116 * key; it can be unit-tested. Further validation is done in
2117 * rend_service_validate_intro().
2121 rend_service_begin_parse_intro(const uint8_t *request
,
2126 rend_intro_cell_t
*rv
= NULL
;
2127 char *err_msg
= NULL
;
2129 if (!request
|| request_len
<= 0) goto err
;
2130 if (!(type
== 1 || type
== 2)) goto err
;
2132 /* First, check that the cell is long enough to be a sensible INTRODUCE */
2134 /* min key length plus digest length plus nickname length */
2136 (DIGEST_LEN
+ REND_COOKIE_LEN
+ (MAX_NICKNAME_LEN
+ 1) +
2139 tor_asprintf(&err_msg
,
2140 "got a truncated INTRODUCE%d cell",
2146 /* Allocate a new parsed cell structure */
2147 rv
= tor_malloc_zero(sizeof(*rv
));
2152 /* Copy in the ID */
2153 memcpy(rv
->pk
, request
, DIGEST_LEN
);
2155 /* Copy in the ciphertext */
2156 rv
->ciphertext
= tor_malloc(request_len
- DIGEST_LEN
);
2157 memcpy(rv
->ciphertext
, request
+ DIGEST_LEN
, request_len
- DIGEST_LEN
);
2158 rv
->ciphertext_len
= request_len
- DIGEST_LEN
;
2163 rend_service_free_intro(rv
);
2166 if (err_msg_out
&& !err_msg
) {
2167 tor_asprintf(&err_msg
,
2168 "unknown INTRODUCE%d error",
2173 if (err_msg_out
) *err_msg_out
= err_msg
;
2174 else tor_free(err_msg
);
2179 /** Parse the version-specific parts of a v0 or v1 INTRODUCE1 or INTRODUCE2
2184 rend_service_parse_intro_for_v0_or_v1(
2185 rend_intro_cell_t
*intro
,
2187 size_t plaintext_len
,
2190 const char *rp_nickname
, *endptr
;
2191 size_t nickname_field_len
, ver_specific_len
;
2193 if (intro
->version
== 1) {
2194 ver_specific_len
= MAX_HEX_NICKNAME_LEN
+ 2;
2195 rp_nickname
= ((const char *)buf
) + 1;
2196 nickname_field_len
= MAX_HEX_NICKNAME_LEN
+ 1;
2197 } else if (intro
->version
== 0) {
2198 ver_specific_len
= MAX_NICKNAME_LEN
+ 1;
2199 rp_nickname
= (const char *)buf
;
2200 nickname_field_len
= MAX_NICKNAME_LEN
+ 1;
2203 tor_asprintf(err_msg_out
,
2204 "rend_service_parse_intro_for_v0_or_v1() called with "
2205 "bad version %d on INTRODUCE%d cell (this is a bug)",
2207 (int)(intro
->type
));
2211 if (plaintext_len
< ver_specific_len
) {
2213 tor_asprintf(err_msg_out
,
2214 "short plaintext of encrypted part in v1 INTRODUCE%d "
2215 "cell (%lu bytes, needed %lu)",
2217 (unsigned long)plaintext_len
,
2218 (unsigned long)ver_specific_len
);
2222 endptr
= memchr(rp_nickname
, 0, nickname_field_len
);
2223 if (!endptr
|| endptr
== rp_nickname
) {
2225 tor_asprintf(err_msg_out
,
2226 "couldn't find a nul-padded nickname in "
2228 (int)(intro
->type
));
2233 if ((intro
->version
== 0 &&
2234 !is_legal_nickname(rp_nickname
)) ||
2235 (intro
->version
== 1 &&
2236 !is_legal_nickname_or_hexdigest(rp_nickname
))) {
2238 tor_asprintf(err_msg_out
,
2239 "bad nickname in INTRODUCE%d cell",
2240 (int)(intro
->type
));
2245 memcpy(intro
->u
.v0_v1
.rp
, rp_nickname
, endptr
- rp_nickname
+ 1);
2247 return ver_specific_len
;
2253 /** Parse the version-specific parts of a v2 INTRODUCE1 or INTRODUCE2 cell
2257 rend_service_parse_intro_for_v2(
2258 rend_intro_cell_t
*intro
,
2260 size_t plaintext_len
,
2264 extend_info_t
*extend_info
= NULL
;
2265 ssize_t ver_specific_len
;
2268 * We accept version 3 too so that the v3 parser can call this with
2269 * an adjusted buffer for the latter part of a v3 cell, which is
2270 * identical to a v2 cell.
2272 if (!(intro
->version
== 2 ||
2273 intro
->version
== 3)) {
2275 tor_asprintf(err_msg_out
,
2276 "rend_service_parse_intro_for_v2() called with "
2277 "bad version %d on INTRODUCE%d cell (this is a bug)",
2279 (int)(intro
->type
));
2283 /* 7 == version, IP and port, DIGEST_LEN == id, 2 == key length */
2284 if (plaintext_len
< 7 + DIGEST_LEN
+ 2) {
2286 tor_asprintf(err_msg_out
,
2287 "truncated plaintext of encrypted parted of "
2288 "version %d INTRODUCE%d cell",
2290 (int)(intro
->type
));
2296 extend_info
= tor_malloc_zero(sizeof(extend_info_t
));
2297 tor_addr_from_ipv4n(&extend_info
->addr
, get_uint32(buf
+ 1));
2298 extend_info
->port
= ntohs(get_uint16(buf
+ 5));
2299 memcpy(extend_info
->identity_digest
, buf
+ 7, DIGEST_LEN
);
2300 extend_info
->nickname
[0] = '$';
2301 base16_encode(extend_info
->nickname
+ 1, sizeof(extend_info
->nickname
) - 1,
2302 extend_info
->identity_digest
, DIGEST_LEN
);
2303 klen
= ntohs(get_uint16(buf
+ 7 + DIGEST_LEN
));
2305 /* 7 == version, IP and port, DIGEST_LEN == id, 2 == key length */
2306 if (plaintext_len
< 7 + DIGEST_LEN
+ 2 + klen
) {
2308 tor_asprintf(err_msg_out
,
2309 "truncated plaintext of encrypted parted of "
2310 "version %d INTRODUCE%d cell",
2312 (int)(intro
->type
));
2318 extend_info
->onion_key
=
2319 crypto_pk_asn1_decode((const char *)(buf
+ 7 + DIGEST_LEN
+ 2), klen
);
2320 if (!extend_info
->onion_key
) {
2322 tor_asprintf(err_msg_out
,
2323 "error decoding onion key in version %d "
2331 if (128 != crypto_pk_keysize(extend_info
->onion_key
)) {
2333 tor_asprintf(err_msg_out
,
2334 "invalid onion key size in version %d INTRODUCE%d cell",
2342 ver_specific_len
= 7+DIGEST_LEN
+2+klen
;
2344 if (intro
->version
== 2) intro
->u
.v2
.extend_info
= extend_info
;
2345 else intro
->u
.v3
.extend_info
= extend_info
;
2347 return ver_specific_len
;
2350 extend_info_free(extend_info
);
2355 /** Parse the version-specific parts of a v3 INTRODUCE1 or INTRODUCE2 cell
2359 rend_service_parse_intro_for_v3(
2360 rend_intro_cell_t
*intro
,
2362 size_t plaintext_len
,
2365 ssize_t adjust
, v2_ver_specific_len
, ts_offset
;
2367 /* This should only be called on v3 cells */
2368 if (intro
->version
!= 3) {
2370 tor_asprintf(err_msg_out
,
2371 "rend_service_parse_intro_for_v3() called with "
2372 "bad version %d on INTRODUCE%d cell (this is a bug)",
2374 (int)(intro
->type
));
2379 * Check that we have at least enough to get auth_len:
2381 * 1 octet for version, 1 for auth_type, 2 for auth_len
2383 if (plaintext_len
< 4) {
2385 tor_asprintf(err_msg_out
,
2386 "truncated plaintext of encrypted parted of "
2387 "version %d INTRODUCE%d cell",
2389 (int)(intro
->type
));
2396 * The rend_client_send_introduction() function over in rendclient.c is
2397 * broken (i.e., fails to match the spec) in such a way that we can't
2398 * change it without breaking the protocol. Specifically, it doesn't
2399 * emit auth_len when auth-type is REND_NO_AUTH, so everything is off
2400 * by two bytes after that. Calculate ts_offset and do everything from
2401 * the timestamp on relative to that to handle this dain bramage.
2404 intro
->u
.v3
.auth_type
= buf
[1];
2405 if (intro
->u
.v3
.auth_type
!= REND_NO_AUTH
) {
2406 intro
->u
.v3
.auth_len
= ntohs(get_uint16(buf
+ 2));
2407 ts_offset
= 4 + intro
->u
.v3
.auth_len
;
2409 intro
->u
.v3
.auth_len
= 0;
2413 /* Check that auth len makes sense for this auth type */
2414 if (intro
->u
.v3
.auth_type
== REND_BASIC_AUTH
||
2415 intro
->u
.v3
.auth_type
== REND_STEALTH_AUTH
) {
2416 if (intro
->u
.v3
.auth_len
!= REND_DESC_COOKIE_LEN
) {
2418 tor_asprintf(err_msg_out
,
2419 "wrong auth data size %d for INTRODUCE%d cell, "
2421 (int)(intro
->u
.v3
.auth_len
),
2423 REND_DESC_COOKIE_LEN
);
2430 /* Check that we actually have everything up through the timestamp */
2431 if (plaintext_len
< (size_t)(ts_offset
)+4) {
2433 tor_asprintf(err_msg_out
,
2434 "truncated plaintext of encrypted parted of "
2435 "version %d INTRODUCE%d cell",
2437 (int)(intro
->type
));
2443 if (intro
->u
.v3
.auth_type
!= REND_NO_AUTH
&&
2444 intro
->u
.v3
.auth_len
> 0) {
2445 /* Okay, we can go ahead and copy auth_data */
2446 intro
->u
.v3
.auth_data
= tor_malloc(intro
->u
.v3
.auth_len
);
2448 * We know we had an auth_len field in this case, so 4 is
2451 memcpy(intro
->u
.v3
.auth_data
, buf
+ 4, intro
->u
.v3
.auth_len
);
2455 * From here on, the format is as in v2, so we call the v2 parser with
2456 * adjusted buffer and length. We are 4 + ts_offset octets in, but the
2457 * v2 parser expects to skip over a version byte at the start, so we
2458 * adjust by 3 + ts_offset.
2460 adjust
= 3 + ts_offset
;
2462 v2_ver_specific_len
=
2463 rend_service_parse_intro_for_v2(intro
,
2464 buf
+ adjust
, plaintext_len
- adjust
,
2467 /* Success in v2 parser */
2468 if (v2_ver_specific_len
>= 0) return v2_ver_specific_len
+ adjust
;
2469 /* Failure in v2 parser; it will have provided an err_msg */
2470 else return v2_ver_specific_len
;
2476 /** Table of parser functions for version-specific parts of an INTRODUCE2
2481 (*intro_version_handlers
[])(
2482 rend_intro_cell_t
*,
2486 { rend_service_parse_intro_for_v0_or_v1
,
2487 rend_service_parse_intro_for_v0_or_v1
,
2488 rend_service_parse_intro_for_v2
,
2489 rend_service_parse_intro_for_v3
};
2491 /** Decrypt the encrypted part of an INTRODUCE1 or INTRODUCE2 cell,
2492 * return 0 if successful, or < 0 and write an error message to
2493 * *err_msg_out if provided.
2497 rend_service_decrypt_intro(
2498 rend_intro_cell_t
*intro
,
2502 char *err_msg
= NULL
;
2503 uint8_t key_digest
[DIGEST_LEN
];
2504 char service_id
[REND_SERVICE_ID_LEN_BASE32
+1];
2506 uint8_t buf
[RELAY_PAYLOAD_SIZE
];
2507 int result
, status
= -1;
2509 if (!intro
|| !key
) {
2512 tor_strdup("rend_service_decrypt_intro() called with bad "
2520 /* Make sure we have ciphertext */
2521 if (!(intro
->ciphertext
) || intro
->ciphertext_len
<= 0) {
2523 tor_asprintf(&err_msg
,
2524 "rend_intro_cell_t was missing ciphertext for "
2526 (int)(intro
->type
));
2532 /* Check that this cell actually matches this service key */
2534 /* first DIGEST_LEN bytes of request is intro or service pk digest */
2535 crypto_pk_get_digest(key
, (char *)key_digest
);
2536 if (tor_memneq(key_digest
, intro
->pk
, DIGEST_LEN
)) {
2538 base32_encode(service_id
, REND_SERVICE_ID_LEN_BASE32
+ 1,
2539 (char*)(intro
->pk
), REND_SERVICE_ID_LEN
);
2540 tor_asprintf(&err_msg
,
2541 "got an INTRODUCE%d cell for the wrong service (%s)",
2543 escaped(service_id
));
2550 /* Make sure the encrypted part is long enough to decrypt */
2552 key_len
= crypto_pk_keysize(key
);
2553 if (intro
->ciphertext_len
< key_len
) {
2555 tor_asprintf(&err_msg
,
2556 "got an INTRODUCE%d cell with a truncated PK-encrypted "
2558 (int)(intro
->type
));
2565 /* Decrypt the encrypted part */
2567 note_crypto_pk_op(REND_SERVER
);
2569 crypto_pk_private_hybrid_decrypt(
2570 key
, (char *)buf
, sizeof(buf
),
2571 (const char *)(intro
->ciphertext
), intro
->ciphertext_len
,
2572 PK_PKCS1_OAEP_PADDING
, 1);
2575 tor_asprintf(&err_msg
,
2576 "couldn't decrypt INTRODUCE%d cell",
2577 (int)(intro
->type
));
2582 intro
->plaintext_len
= result
;
2583 intro
->plaintext
= tor_malloc(intro
->plaintext_len
);
2584 memcpy(intro
->plaintext
, buf
, intro
->plaintext_len
);
2591 if (err_msg_out
&& !err_msg
) {
2592 tor_asprintf(&err_msg
,
2593 "unknown INTRODUCE%d error decrypting encrypted part",
2594 intro
? (int)(intro
->type
) : -1);
2598 if (err_msg_out
) *err_msg_out
= err_msg
;
2599 else tor_free(err_msg
);
2601 /* clean up potentially sensitive material */
2602 memwipe(buf
, 0, sizeof(buf
));
2603 memwipe(key_digest
, 0, sizeof(key_digest
));
2604 memwipe(service_id
, 0, sizeof(service_id
));
2609 /** Parse the plaintext of the encrypted part of an INTRODUCE1 or
2610 * INTRODUCE2 cell, return 0 if successful, or < 0 and write an error
2611 * message to *err_msg_out if provided.
2615 rend_service_parse_intro_plaintext(
2616 rend_intro_cell_t
*intro
,
2619 char *err_msg
= NULL
;
2620 ssize_t ver_specific_len
, ver_invariant_len
;
2627 tor_strdup("rend_service_parse_intro_plaintext() called with NULL "
2628 "rend_intro_cell_t");
2635 /* Check that we have plaintext */
2636 if (!(intro
->plaintext
) || intro
->plaintext_len
<= 0) {
2638 err_msg
= tor_strdup("rend_intro_cell_t was missing plaintext");
2644 /* In all formats except v0, the first byte is a version number */
2645 version
= intro
->plaintext
[0];
2647 /* v0 has no version byte (stupid...), so handle it as a fallback */
2648 if (version
> 3) version
= 0;
2650 /* Copy the version into the parsed cell structure */
2651 intro
->version
= version
;
2653 /* Call the version-specific parser from the table */
2655 intro_version_handlers
[version
](intro
,
2656 intro
->plaintext
, intro
->plaintext_len
,
2658 if (ver_specific_len
< 0) {
2663 /** The rendezvous cookie and Diffie-Hellman stuff are version-invariant
2664 * and at the end of the plaintext of the encrypted part of the cell.
2667 ver_invariant_len
= intro
->plaintext_len
- ver_specific_len
;
2668 if (ver_invariant_len
< REND_COOKIE_LEN
+ DH_KEY_LEN
) {
2669 tor_asprintf(&err_msg
,
2670 "decrypted plaintext of INTRODUCE%d cell was truncated (%ld bytes)",
2672 (long)(intro
->plaintext_len
));
2675 } else if (ver_invariant_len
> REND_COOKIE_LEN
+ DH_KEY_LEN
) {
2676 tor_asprintf(&err_msg
,
2677 "decrypted plaintext of INTRODUCE%d cell was too long (%ld bytes)",
2679 (long)(intro
->plaintext_len
));
2684 intro
->plaintext
+ ver_specific_len
,
2687 intro
->plaintext
+ ver_specific_len
+ REND_COOKIE_LEN
,
2691 /* Flag it as being fully parsed */
2698 if (err_msg_out
&& !err_msg
) {
2699 tor_asprintf(&err_msg
,
2700 "unknown INTRODUCE%d error parsing encrypted part",
2701 intro
? (int)(intro
->type
) : -1);
2705 if (err_msg_out
) *err_msg_out
= err_msg
;
2706 else tor_free(err_msg
);
2711 /** Do validity checks on a parsed intro cell after decryption; some of
2712 * these are not done in rend_service_parse_intro_plaintext() itself because
2713 * they depend on a lot of other state and would make it hard to unit test.
2714 * Returns >= 0 if successful or < 0 if the intro cell is invalid, and
2715 * optionally writes out an error message for logging. If an err_msg
2716 * pointer is provided, it is the caller's responsibility to free any
2721 rend_service_validate_intro_late(const rend_intro_cell_t
*intro
,
2729 tor_strdup("NULL intro cell passed to "
2730 "rend_service_validate_intro_late()");
2736 if (intro
->version
== 3 && intro
->parsed
) {
2737 if (!(intro
->u
.v3
.auth_type
== REND_NO_AUTH
||
2738 intro
->u
.v3
.auth_type
== REND_BASIC_AUTH
||
2739 intro
->u
.v3
.auth_type
== REND_STEALTH_AUTH
)) {
2740 /* This is an informative message, not an error, as in the old code */
2742 tor_asprintf(err_msg_out
,
2743 "unknown authorization type %d",
2744 intro
->u
.v3
.auth_type
);
2752 /** Called when we fail building a rendezvous circuit at some point other
2753 * than the last hop: launches a new circuit to the same rendezvous point.
2756 rend_service_relaunch_rendezvous(origin_circuit_t
*oldcirc
)
2758 origin_circuit_t
*newcirc
;
2759 cpath_build_state_t
*newstate
, *oldstate
;
2761 tor_assert(oldcirc
->base_
.purpose
== CIRCUIT_PURPOSE_S_CONNECT_REND
);
2763 /* Don't relaunch the same rend circ twice. */
2764 if (oldcirc
->hs_service_side_rend_circ_has_been_relaunched
) {
2765 log_info(LD_REND
, "Rendezvous circuit to %s has already been relaunched; "
2766 "not relaunching it again.",
2767 oldcirc
->build_state
?
2768 safe_str(extend_info_describe(oldcirc
->build_state
->chosen_exit
))
2772 oldcirc
->hs_service_side_rend_circ_has_been_relaunched
= 1;
2774 if (!oldcirc
->build_state
||
2775 oldcirc
->build_state
->failure_count
> MAX_REND_FAILURES
||
2776 oldcirc
->build_state
->expiry_time
< time(NULL
)) {
2778 "Attempt to build circuit to %s for rendezvous has failed "
2779 "too many times or expired; giving up.",
2780 oldcirc
->build_state
?
2781 safe_str(extend_info_describe(oldcirc
->build_state
->chosen_exit
))
2786 oldstate
= oldcirc
->build_state
;
2787 tor_assert(oldstate
);
2789 if (oldstate
->service_pending_final_cpath_ref
== NULL
) {
2790 log_info(LD_REND
,"Skipping relaunch of circ that failed on its first hop. "
2791 "Initiator will retry.");
2795 log_info(LD_REND
,"Reattempting rendezvous circuit to '%s'",
2796 safe_str(extend_info_describe(oldstate
->chosen_exit
)));
2798 /* You'd think Single Onion Services would want to retry the rendezvous
2799 * using a direct connection. But if it's blocked by a firewall, or the
2800 * service is IPv6-only, or the rend point avoiding becoming a one-hop
2801 * proxy, we need a 3-hop connection. */
2802 newcirc
= circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND
,
2803 oldstate
->chosen_exit
,
2804 CIRCLAUNCH_NEED_CAPACITY
|CIRCLAUNCH_IS_INTERNAL
);
2807 log_warn(LD_REND
,"Couldn't relaunch rendezvous circuit to '%s'.",
2808 safe_str(extend_info_describe(oldstate
->chosen_exit
)));
2811 newstate
= newcirc
->build_state
;
2812 tor_assert(newstate
);
2813 newstate
->failure_count
= oldstate
->failure_count
+1;
2814 newstate
->expiry_time
= oldstate
->expiry_time
;
2815 newstate
->service_pending_final_cpath_ref
=
2816 oldstate
->service_pending_final_cpath_ref
;
2817 ++(newstate
->service_pending_final_cpath_ref
->refcount
);
2819 newcirc
->rend_data
= rend_data_dup(oldcirc
->rend_data
);
2822 /** Launch a circuit to serve as an introduction point for the service
2823 * <b>service</b> at the introduction point <b>nickname</b>
2826 rend_service_launch_establish_intro(rend_service_t
*service
,
2827 rend_intro_point_t
*intro
)
2829 origin_circuit_t
*launched
;
2830 int flags
= CIRCLAUNCH_NEED_UPTIME
|CIRCLAUNCH_IS_INTERNAL
;
2831 const or_options_t
*options
= get_options();
2832 extend_info_t
*launch_ei
= intro
->extend_info
;
2833 extend_info_t
*direct_ei
= NULL
;
2835 /* Are we in single onion mode? */
2836 if (rend_service_allow_non_anonymous_connection(options
)) {
2837 /* Do we have a descriptor for the node?
2838 * We've either just chosen it from the consensus, or we've just reviewed
2839 * our intro points to see which ones are still valid, and deleted the ones
2840 * that aren't in the consensus any more. */
2841 const node_t
*node
= node_get_by_id(launch_ei
->identity_digest
);
2843 /* The service has kept an intro point after it went missing from the
2844 * consensus. If we did anything else here, it would be a consensus
2845 * distinguisher. Which are less of an issue for single onion services,
2846 * but still a bug. */
2849 /* Can we connect to the node directly? If so, replace launch_ei
2850 * (a multi-hop extend_info) with one suitable for direct connection. */
2851 if (rend_service_use_direct_connection_node(options
, node
)) {
2852 direct_ei
= extend_info_from_node(node
, 1);
2853 if (BUG(!direct_ei
)) {
2854 /* rend_service_use_direct_connection_node and extend_info_from_node
2855 * disagree about which addresses on this node are permitted. This
2856 * should never happen. Avoiding the connection is a safe response. */
2859 flags
= flags
| CIRCLAUNCH_ONEHOP_TUNNEL
;
2860 launch_ei
= direct_ei
;
2863 /* launch_ei is either intro->extend_info, or has been replaced with a valid
2864 * extend_info for single onion service direct connection. */
2865 tor_assert(launch_ei
);
2866 /* We must have the same intro when making a direct connection. */
2867 tor_assert(tor_memeq(intro
->extend_info
->identity_digest
,
2868 launch_ei
->identity_digest
,
2872 "Launching circuit to introduction point %s%s%s for service %s",
2873 safe_str_client(extend_info_describe(intro
->extend_info
)),
2874 direct_ei
? " via direct address " : "",
2875 direct_ei
? safe_str_client(extend_info_describe(direct_ei
)) : "",
2876 service
->service_id
);
2878 rep_hist_note_used_internal(time(NULL
), 1, 0);
2880 ++service
->n_intro_circuits_launched
;
2881 launched
= circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
,
2886 "Can't launch circuit to establish introduction at %s%s%s.",
2887 safe_str_client(extend_info_describe(intro
->extend_info
)),
2888 direct_ei
? " via direct address " : "",
2889 direct_ei
? safe_str_client(extend_info_describe(direct_ei
)) : ""
2891 extend_info_free(direct_ei
);
2894 /* We must have the same exit node even if cannibalized or direct connection.
2896 tor_assert(tor_memeq(intro
->extend_info
->identity_digest
,
2897 launched
->build_state
->chosen_exit
->identity_digest
,
2900 launched
->rend_data
= rend_data_service_create(service
->service_id
,
2901 service
->pk_digest
, NULL
,
2902 service
->auth_type
);
2903 launched
->intro_key
= crypto_pk_dup_key(intro
->intro_key
);
2904 if (launched
->base_
.state
== CIRCUIT_STATE_OPEN
)
2905 rend_service_intro_has_opened(launched
);
2906 extend_info_free(direct_ei
);
2910 /** Return the number of introduction points that are established for the
2913 count_established_intro_points(const rend_service_t
*service
)
2915 unsigned int num
= 0;
2917 SMARTLIST_FOREACH(service
->intro_nodes
, rend_intro_point_t
*, intro
,
2918 num
+= intro
->circuit_established
2923 /** Return the number of introduction points that are or are being
2924 * established for the given service. This function iterates over all
2925 * circuit and count those that are linked to the service and are waiting
2926 * for the intro point to respond. */
2928 count_intro_point_circuits(const rend_service_t
*service
)
2930 unsigned int num_ipos
= 0;
2931 SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t
*, circ
) {
2932 if (!circ
->marked_for_close
&&
2933 circ
->state
== CIRCUIT_STATE_OPEN
&&
2934 (circ
->purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
||
2935 circ
->purpose
== CIRCUIT_PURPOSE_S_INTRO
)) {
2936 origin_circuit_t
*oc
= TO_ORIGIN_CIRCUIT(circ
);
2937 if (oc
->rend_data
&&
2938 !rend_cmp_service_ids(service
->service_id
,
2939 oc
->rend_data
->onion_address
))
2943 SMARTLIST_FOREACH_END(circ
);
2947 /** Called when we're done building a circuit to an introduction point:
2948 * sends a RELAY_ESTABLISH_INTRO cell.
2951 rend_service_intro_has_opened(origin_circuit_t
*circuit
)
2953 rend_service_t
*service
;
2956 char buf
[RELAY_PAYLOAD_SIZE
];
2957 char auth
[DIGEST_LEN
+ 9];
2958 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
2959 int reason
= END_CIRC_REASON_TORPROTOCOL
;
2961 tor_assert(circuit
->base_
.purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
);
2962 assert_circ_anonymity_ok(circuit
, get_options());
2963 tor_assert(circuit
->cpath
);
2964 tor_assert(circuit
->rend_data
);
2966 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+1,
2967 circuit
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
2969 service
= rend_service_get_by_pk_digest(
2970 circuit
->rend_data
->rend_pk_digest
);
2972 log_warn(LD_REND
, "Unrecognized service ID %s on introduction circuit %u.",
2973 safe_str_client(serviceid
), (unsigned)circuit
->base_
.n_circ_id
);
2974 reason
= END_CIRC_REASON_NOSUCHSERVICE
;
2978 /* If we already have enough introduction circuits for this service,
2979 * redefine this one as a general circuit or close it, depending.
2980 * Substract the amount of expiring nodes here since the circuits are
2982 if ((count_intro_point_circuits(service
) -
2983 smartlist_len(service
->expiring_nodes
)) >
2984 service
->n_intro_points_wanted
) {
2985 const or_options_t
*options
= get_options();
2986 /* Remove the intro point associated with this circuit, it's being
2987 * repurposed or closed thus cleanup memory. */
2988 rend_intro_point_t
*intro
= find_intro_point(circuit
);
2989 if (intro
!= NULL
) {
2990 smartlist_remove(service
->intro_nodes
, intro
);
2991 rend_intro_point_free(intro
);
2994 if (options
->ExcludeNodes
) {
2995 /* XXXX in some future version, we can test whether the transition is
2996 allowed or not given the actual nodes in the circuit. But for now,
2997 this case, we might as well close the thing. */
2998 log_info(LD_CIRC
|LD_REND
, "We have just finished an introduction "
2999 "circuit, but we already have enough. Closing it.");
3000 reason
= END_CIRC_REASON_NONE
;
3003 tor_assert(circuit
->build_state
->is_internal
);
3004 log_info(LD_CIRC
|LD_REND
, "We have just finished an introduction "
3005 "circuit, but we already have enough. Redefining purpose to "
3006 "general; leaving as internal.");
3008 circuit_change_purpose(TO_CIRCUIT(circuit
), CIRCUIT_PURPOSE_C_GENERAL
);
3011 rend_data_t
*rend_data
= circuit
->rend_data
;
3012 circuit
->rend_data
= NULL
;
3013 rend_data_free(rend_data
);
3016 crypto_pk_t
*intro_key
= circuit
->intro_key
;
3017 circuit
->intro_key
= NULL
;
3018 crypto_pk_free(intro_key
);
3021 circuit_has_opened(circuit
);
3027 "Established circuit %u as introduction point for service %s",
3028 (unsigned)circuit
->base_
.n_circ_id
, serviceid
);
3029 circuit_log_path(LOG_INFO
, LD_REND
, circuit
);
3031 /* Use the intro key instead of the service key in ESTABLISH_INTRO. */
3032 crypto_pk_t
*intro_key
= circuit
->intro_key
;
3033 /* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
3034 r
= crypto_pk_asn1_encode(intro_key
, buf
+2,
3035 RELAY_PAYLOAD_SIZE
-2);
3037 log_warn(LD_BUG
, "Internal error; failed to establish intro point.");
3038 reason
= END_CIRC_REASON_INTERNAL
;
3042 set_uint16(buf
, htons((uint16_t)len
));
3044 memcpy(auth
, circuit
->cpath
->prev
->rend_circ_nonce
, DIGEST_LEN
);
3045 memcpy(auth
+DIGEST_LEN
, "INTRODUCE", 9);
3046 if (crypto_digest(buf
+len
, auth
, DIGEST_LEN
+9))
3049 note_crypto_pk_op(REND_SERVER
);
3050 r
= crypto_pk_private_sign_digest(intro_key
, buf
+len
, sizeof(buf
)-len
,
3053 log_warn(LD_BUG
, "Internal error: couldn't sign introduction request.");
3054 reason
= END_CIRC_REASON_INTERNAL
;
3059 if (relay_send_command_from_edge(0, TO_CIRCUIT(circuit
),
3060 RELAY_COMMAND_ESTABLISH_INTRO
,
3061 buf
, len
, circuit
->cpath
->prev
)<0) {
3062 log_info(LD_GENERAL
,
3063 "Couldn't send introduction request for service %s on circuit %u",
3064 serviceid
, (unsigned)circuit
->base_
.n_circ_id
);
3065 reason
= END_CIRC_REASON_INTERNAL
;
3069 /* We've attempted to use this circuit */
3070 pathbias_count_use_attempt(circuit
);
3075 circuit_mark_for_close(TO_CIRCUIT(circuit
), reason
);
3077 memwipe(buf
, 0, sizeof(buf
));
3078 memwipe(auth
, 0, sizeof(auth
));
3079 memwipe(serviceid
, 0, sizeof(serviceid
));
3084 /** Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a
3085 * live introduction point, and note that the service descriptor is
3086 * now out-of-date. */
3088 rend_service_intro_established(origin_circuit_t
*circuit
,
3089 const uint8_t *request
,
3092 rend_service_t
*service
;
3093 rend_intro_point_t
*intro
;
3094 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
3098 if (circuit
->base_
.purpose
!= CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
) {
3099 log_warn(LD_PROTOCOL
,
3100 "received INTRO_ESTABLISHED cell on non-intro circuit.");
3103 tor_assert(circuit
->rend_data
);
3104 service
= rend_service_get_by_pk_digest(
3105 circuit
->rend_data
->rend_pk_digest
);
3107 log_warn(LD_REND
, "Unknown service on introduction circuit %u.",
3108 (unsigned)circuit
->base_
.n_circ_id
);
3111 /* We've just successfully established a intro circuit to one of our
3112 * introduction point, account for it. */
3113 intro
= find_intro_point(circuit
);
3114 if (intro
== NULL
) {
3116 "Introduction circuit established without a rend_intro_point_t "
3117 "object for service %s on circuit %u",
3118 safe_str_client(serviceid
), (unsigned)circuit
->base_
.n_circ_id
);
3121 intro
->circuit_established
= 1;
3122 /* We might not have every introduction point ready but at this point we
3123 * know that the descriptor needs to be uploaded. */
3124 service
->desc_is_dirty
= time(NULL
);
3125 circuit_change_purpose(TO_CIRCUIT(circuit
), CIRCUIT_PURPOSE_S_INTRO
);
3127 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+ 1,
3128 circuit
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
3130 "Received INTRO_ESTABLISHED cell on circuit %u for service %s",
3131 (unsigned)circuit
->base_
.n_circ_id
, serviceid
);
3133 /* Getting a valid INTRODUCE_ESTABLISHED means we've successfully
3135 pathbias_mark_use_success(circuit
);
3139 circuit_mark_for_close(TO_CIRCUIT(circuit
), END_CIRC_REASON_TORPROTOCOL
);
3143 /** Called once a circuit to a rendezvous point is established: sends a
3144 * RELAY_COMMAND_RENDEZVOUS1 cell.
3147 rend_service_rendezvous_has_opened(origin_circuit_t
*circuit
)
3149 rend_service_t
*service
;
3150 char buf
[RELAY_PAYLOAD_SIZE
];
3152 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
3156 tor_assert(circuit
->base_
.purpose
== CIRCUIT_PURPOSE_S_CONNECT_REND
);
3157 tor_assert(circuit
->cpath
);
3158 tor_assert(circuit
->build_state
);
3159 assert_circ_anonymity_ok(circuit
, get_options());
3160 tor_assert(circuit
->rend_data
);
3162 /* Declare the circuit dirty to avoid reuse, and for path-bias */
3163 if (!circuit
->base_
.timestamp_dirty
)
3164 circuit
->base_
.timestamp_dirty
= time(NULL
);
3166 /* This may be redundant */
3167 pathbias_count_use_attempt(circuit
);
3169 hop
= circuit
->build_state
->service_pending_final_cpath_ref
->cpath
;
3171 base16_encode(hexcookie
,9,circuit
->rend_data
->rend_cookie
,4);
3172 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+1,
3173 circuit
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
3176 "Done building circuit %u to rendezvous with "
3177 "cookie %s for service %s",
3178 (unsigned)circuit
->base_
.n_circ_id
, hexcookie
, serviceid
);
3179 circuit_log_path(LOG_INFO
, LD_REND
, circuit
);
3181 /* Clear the 'in-progress HS circ has timed out' flag for
3182 * consistency with what happens on the client side; this line has
3183 * no effect on Tor's behaviour. */
3184 circuit
->hs_circ_has_timed_out
= 0;
3186 /* If hop is NULL, another rend circ has already connected to this
3187 * rend point. Close this circ. */
3189 log_info(LD_REND
, "Another rend circ has already reached this rend point; "
3190 "closing this rend circ.");
3191 reason
= END_CIRC_REASON_NONE
;
3195 /* Remove our final cpath element from the reference, so that no
3196 * other circuit will try to use it. Store it in
3197 * pending_final_cpath for now to ensure that it will be freed if
3198 * our rendezvous attempt fails. */
3199 circuit
->build_state
->pending_final_cpath
= hop
;
3200 circuit
->build_state
->service_pending_final_cpath_ref
->cpath
= NULL
;
3202 service
= rend_service_get_by_pk_digest(
3203 circuit
->rend_data
->rend_pk_digest
);
3205 log_warn(LD_GENERAL
, "Internal error: unrecognized service ID on "
3206 "rendezvous circuit.");
3207 reason
= END_CIRC_REASON_INTERNAL
;
3211 /* All we need to do is send a RELAY_RENDEZVOUS1 cell... */
3212 memcpy(buf
, circuit
->rend_data
->rend_cookie
, REND_COOKIE_LEN
);
3213 if (crypto_dh_get_public(hop
->rend_dh_handshake_state
,
3214 buf
+REND_COOKIE_LEN
, DH_KEY_LEN
)<0) {
3215 log_warn(LD_GENERAL
,"Couldn't get DH public key.");
3216 reason
= END_CIRC_REASON_INTERNAL
;
3219 memcpy(buf
+REND_COOKIE_LEN
+DH_KEY_LEN
, hop
->rend_circ_nonce
,
3223 if (relay_send_command_from_edge(0, TO_CIRCUIT(circuit
),
3224 RELAY_COMMAND_RENDEZVOUS1
,
3225 buf
, REND_COOKIE_LEN
+DH_KEY_LEN
+DIGEST_LEN
,
3226 circuit
->cpath
->prev
)<0) {
3227 log_warn(LD_GENERAL
, "Couldn't send RENDEZVOUS1 cell.");
3228 reason
= END_CIRC_REASON_INTERNAL
;
3232 crypto_dh_free(hop
->rend_dh_handshake_state
);
3233 hop
->rend_dh_handshake_state
= NULL
;
3235 /* Append the cpath entry. */
3236 hop
->state
= CPATH_STATE_OPEN
;
3237 /* set the windows to default. these are the windows
3238 * that the service thinks the client has.
3240 hop
->package_window
= circuit_initial_package_window();
3241 hop
->deliver_window
= CIRCWINDOW_START
;
3243 onion_append_to_cpath(&circuit
->cpath
, hop
);
3244 circuit
->build_state
->pending_final_cpath
= NULL
; /* prevent double-free */
3246 /* Change the circuit purpose. */
3247 circuit_change_purpose(TO_CIRCUIT(circuit
), CIRCUIT_PURPOSE_S_REND_JOINED
);
3252 circuit_mark_for_close(TO_CIRCUIT(circuit
), reason
);
3254 memwipe(buf
, 0, sizeof(buf
));
3255 memwipe(serviceid
, 0, sizeof(serviceid
));
3256 memwipe(hexcookie
, 0, sizeof(hexcookie
));
3262 * Manage introduction points
3265 /** Return the (possibly non-open) introduction circuit ending at
3266 * <b>intro</b> for the service whose public key is <b>pk_digest</b>.
3267 * (<b>desc_version</b> is ignored). Return NULL if no such service is
3270 static origin_circuit_t
*
3271 find_intro_circuit(rend_intro_point_t
*intro
, const char *pk_digest
)
3273 origin_circuit_t
*circ
= NULL
;
3276 while ((circ
= circuit_get_next_by_pk_and_purpose(circ
,pk_digest
,
3277 CIRCUIT_PURPOSE_S_INTRO
))) {
3278 if (tor_memeq(circ
->build_state
->chosen_exit
->identity_digest
,
3279 intro
->extend_info
->identity_digest
, DIGEST_LEN
) &&
3286 while ((circ
= circuit_get_next_by_pk_and_purpose(circ
,pk_digest
,
3287 CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
))) {
3288 if (tor_memeq(circ
->build_state
->chosen_exit
->identity_digest
,
3289 intro
->extend_info
->identity_digest
, DIGEST_LEN
) &&
3297 /** Return the corresponding introdution point using the circuit <b>circ</b>
3298 * found in the <b>service</b>. NULL is returned if not found. */
3299 static rend_intro_point_t
*
3300 find_expiring_intro_point(rend_service_t
*service
, origin_circuit_t
*circ
)
3302 tor_assert(service
);
3303 tor_assert(TO_CIRCUIT(circ
)->purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
||
3304 TO_CIRCUIT(circ
)->purpose
== CIRCUIT_PURPOSE_S_INTRO
);
3306 SMARTLIST_FOREACH(service
->expiring_nodes
, rend_intro_point_t
*,
3308 if (crypto_pk_eq_keys(intro_point
->intro_key
, circ
->intro_key
)) {
3315 /** Return a pointer to the rend_intro_point_t corresponding to the
3316 * service-side introduction circuit <b>circ</b>. */
3317 static rend_intro_point_t
*
3318 find_intro_point(origin_circuit_t
*circ
)
3320 const char *serviceid
;
3321 rend_service_t
*service
= NULL
;
3323 tor_assert(TO_CIRCUIT(circ
)->purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
||
3324 TO_CIRCUIT(circ
)->purpose
== CIRCUIT_PURPOSE_S_INTRO
);
3325 tor_assert(circ
->rend_data
);
3326 serviceid
= circ
->rend_data
->onion_address
;
3328 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, s
,
3329 if (tor_memeq(s
->service_id
, serviceid
, REND_SERVICE_ID_LEN_BASE32
)) {
3334 if (service
== NULL
) return NULL
;
3336 SMARTLIST_FOREACH(service
->intro_nodes
, rend_intro_point_t
*, intro_point
,
3337 if (crypto_pk_eq_keys(intro_point
->intro_key
, circ
->intro_key
)) {
3344 /** Upload the rend_encoded_v2_service_descriptor_t's in <b>descs</b>
3345 * associated with the rend_service_descriptor_t <b>renddesc</b> to
3346 * the responsible hidden service directories OR the hidden service
3347 * directories specified by <b>hs_dirs</b>; <b>service_id</b> and
3348 * <b>seconds_valid</b> are only passed for logging purposes.
3351 directory_post_to_hs_dir(rend_service_descriptor_t
*renddesc
,
3352 smartlist_t
*descs
, smartlist_t
*hs_dirs
,
3353 const char *service_id
, int seconds_valid
)
3355 int i
, j
, failed_upload
= 0;
3356 smartlist_t
*responsible_dirs
= smartlist_new();
3357 smartlist_t
*successful_uploads
= smartlist_new();
3358 routerstatus_t
*hs_dir
;
3359 for (i
= 0; i
< smartlist_len(descs
); i
++) {
3360 rend_encoded_v2_service_descriptor_t
*desc
= smartlist_get(descs
, i
);
3361 /** If any HSDirs are specified, they should be used instead of
3362 * the responsible directories */
3363 if (hs_dirs
&& smartlist_len(hs_dirs
) > 0) {
3364 smartlist_add_all(responsible_dirs
, hs_dirs
);
3366 /* Determine responsible dirs. */
3367 if (hid_serv_get_responsible_directories(responsible_dirs
,
3368 desc
->desc_id
) < 0) {
3369 log_warn(LD_REND
, "Could not determine the responsible hidden service "
3370 "directories to post descriptors to.");
3371 control_event_hs_descriptor_upload(service_id
,
3377 for (j
= 0; j
< smartlist_len(responsible_dirs
); j
++) {
3378 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
3381 rend_data_t
*rend_data
;
3382 hs_dir
= smartlist_get(responsible_dirs
, j
);
3383 if (smartlist_contains_digest(renddesc
->successful_uploads
,
3384 hs_dir
->identity_digest
))
3385 /* Don't upload descriptor if we succeeded in doing so last time. */
3387 node
= node_get_by_id(hs_dir
->identity_digest
);
3388 if (!node
|| !node_has_descriptor(node
)) {
3389 log_info(LD_REND
, "Not launching upload for for v2 descriptor to "
3390 "hidden service directory %s; we don't have its "
3391 "router descriptor. Queuing for later upload.",
3392 safe_str_client(routerstatus_describe(hs_dir
)));
3396 /* Send publish request. */
3398 /* We need the service ID to identify which service did the upload
3399 * request. Lookup is made in rend_service_desc_has_uploaded(). */
3400 rend_data
= rend_data_client_create(service_id
, desc
->desc_id
, NULL
,
3402 directory_initiate_command_routerstatus_rend(hs_dir
,
3403 DIR_PURPOSE_UPLOAD_RENDDESC_V2
,
3404 ROUTER_PURPOSE_GENERAL
,
3405 DIRIND_ANONYMOUS
, NULL
,
3407 strlen(desc
->desc_str
),
3409 rend_data_free(rend_data
);
3410 base32_encode(desc_id_base32
, sizeof(desc_id_base32
),
3411 desc
->desc_id
, DIGEST_LEN
);
3412 hs_dir_ip
= tor_dup_ip(hs_dir
->addr
);
3413 log_info(LD_REND
, "Launching upload for v2 descriptor for "
3414 "service '%s' with descriptor ID '%s' with validity "
3415 "of %d seconds to hidden service directory '%s' on "
3417 safe_str_client(service_id
),
3418 safe_str_client(desc_id_base32
),
3423 control_event_hs_descriptor_upload(service_id
,
3424 hs_dir
->identity_digest
,
3426 tor_free(hs_dir_ip
);
3427 /* Remember successful upload to this router for next time. */
3428 if (!smartlist_contains_digest(successful_uploads
,
3429 hs_dir
->identity_digest
))
3430 smartlist_add(successful_uploads
, hs_dir
->identity_digest
);
3432 smartlist_clear(responsible_dirs
);
3434 if (!failed_upload
) {
3435 if (renddesc
->successful_uploads
) {
3436 SMARTLIST_FOREACH(renddesc
->successful_uploads
, char *, c
, tor_free(c
););
3437 smartlist_free(renddesc
->successful_uploads
);
3438 renddesc
->successful_uploads
= NULL
;
3440 renddesc
->all_uploads_performed
= 1;
3442 /* Remember which routers worked this time, so that we don't upload the
3443 * descriptor to them again. */
3444 if (!renddesc
->successful_uploads
)
3445 renddesc
->successful_uploads
= smartlist_new();
3446 SMARTLIST_FOREACH(successful_uploads
, const char *, c
, {
3447 if (!smartlist_contains_digest(renddesc
->successful_uploads
, c
)) {
3448 char *hsdir_id
= tor_memdup(c
, DIGEST_LEN
);
3449 smartlist_add(renddesc
->successful_uploads
, hsdir_id
);
3454 smartlist_free(responsible_dirs
);
3455 smartlist_free(successful_uploads
);
3458 /** Encode and sign an up-to-date service descriptor for <b>service</b>,
3459 * and upload it/them to the responsible hidden service directories.
3462 upload_service_descriptor(rend_service_t
*service
)
3464 time_t now
= time(NULL
);
3466 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
3469 rendpostperiod
= get_options()->RendPostPeriod
;
3471 networkstatus_t
*c
= networkstatus_get_latest_consensus();
3472 if (c
&& smartlist_len(c
->routerstatus_list
) > 0) {
3473 int seconds_valid
, i
, j
, num_descs
;
3474 smartlist_t
*descs
= smartlist_new();
3475 smartlist_t
*client_cookies
= smartlist_new();
3476 /* Either upload a single descriptor (including replicas) or one
3477 * descriptor for each authorized client in case of authorization
3478 * type 'stealth'. */
3479 num_descs
= service
->auth_type
== REND_STEALTH_AUTH
?
3480 smartlist_len(service
->clients
) : 1;
3481 for (j
= 0; j
< num_descs
; j
++) {
3482 crypto_pk_t
*client_key
= NULL
;
3483 rend_authorized_client_t
*client
= NULL
;
3484 smartlist_clear(client_cookies
);
3485 switch (service
->auth_type
) {
3487 /* Do nothing here. */
3489 case REND_BASIC_AUTH
:
3490 SMARTLIST_FOREACH(service
->clients
, rend_authorized_client_t
*,
3491 cl
, smartlist_add(client_cookies
, cl
->descriptor_cookie
));
3493 case REND_STEALTH_AUTH
:
3494 client
= smartlist_get(service
->clients
, j
);
3495 client_key
= client
->client_key
;
3496 smartlist_add(client_cookies
, client
->descriptor_cookie
);
3499 /* Encode the current descriptor. */
3500 seconds_valid
= rend_encode_v2_descriptors(descs
, service
->desc
,
3505 if (seconds_valid
< 0) {
3506 log_warn(LD_BUG
, "Internal error: couldn't encode service "
3507 "descriptor; not uploading.");
3508 smartlist_free(descs
);
3509 smartlist_free(client_cookies
);
3512 rend_get_service_id(service
->desc
->pk
, serviceid
);
3513 if (get_options()->PublishHidServDescriptors
) {
3514 /* Post the current descriptors to the hidden service directories. */
3515 log_info(LD_REND
, "Launching upload for hidden service %s",
3517 directory_post_to_hs_dir(service
->desc
, descs
, NULL
, serviceid
,
3520 /* Free memory for descriptors. */
3521 for (i
= 0; i
< smartlist_len(descs
); i
++)
3522 rend_encoded_v2_service_descriptor_free(smartlist_get(descs
, i
));
3523 smartlist_clear(descs
);
3524 /* Update next upload time. */
3525 if (seconds_valid
- REND_TIME_PERIOD_OVERLAPPING_V2_DESCS
3527 service
->next_upload_time
= now
+ rendpostperiod
;
3528 else if (seconds_valid
< REND_TIME_PERIOD_OVERLAPPING_V2_DESCS
)
3529 service
->next_upload_time
= now
+ seconds_valid
+ 1;
3531 service
->next_upload_time
= now
+ seconds_valid
-
3532 REND_TIME_PERIOD_OVERLAPPING_V2_DESCS
+ 1;
3533 /* Post also the next descriptors, if necessary. */
3534 if (seconds_valid
< REND_TIME_PERIOD_OVERLAPPING_V2_DESCS
) {
3535 seconds_valid
= rend_encode_v2_descriptors(descs
, service
->desc
,
3540 if (seconds_valid
< 0) {
3541 log_warn(LD_BUG
, "Internal error: couldn't encode service "
3542 "descriptor; not uploading.");
3543 smartlist_free(descs
);
3544 smartlist_free(client_cookies
);
3547 if (get_options()->PublishHidServDescriptors
) {
3548 directory_post_to_hs_dir(service
->desc
, descs
, NULL
, serviceid
,
3551 /* Free memory for descriptors. */
3552 for (i
= 0; i
< smartlist_len(descs
); i
++)
3553 rend_encoded_v2_service_descriptor_free(smartlist_get(descs
, i
));
3554 smartlist_clear(descs
);
3557 smartlist_free(descs
);
3558 smartlist_free(client_cookies
);
3560 if (get_options()->PublishHidServDescriptors
) {
3561 log_info(LD_REND
, "Successfully uploaded v2 rend descriptors!");
3563 log_info(LD_REND
, "Successfully stored created v2 rend descriptors!");
3567 /* If not uploaded, try again in one minute. */
3569 service
->next_upload_time
= now
+ 60;
3571 /* Unmark dirty flag of this service. */
3572 service
->desc_is_dirty
= 0;
3575 /** Return the number of INTRODUCE2 cells this hidden service has received
3576 * from this intro point. */
3578 intro_point_accepted_intro_count(rend_intro_point_t
*intro
)
3580 return intro
->accepted_introduce2_count
;
3583 /** Return non-zero iff <b>intro</b> should 'expire' now (i.e. we
3584 * should stop publishing it in new descriptors and eventually close
3587 intro_point_should_expire_now(rend_intro_point_t
*intro
,
3590 tor_assert(intro
!= NULL
);
3592 if (intro
->time_published
== -1) {
3593 /* Don't expire an intro point if we haven't even published it yet. */
3597 if (intro_point_accepted_intro_count(intro
) >=
3598 intro
->max_introductions
) {
3599 /* This intro point has been used too many times. Expire it now. */
3603 if (intro
->time_to_expire
== -1) {
3604 /* This intro point has been published, but we haven't picked an
3605 * expiration time for it. Pick one now. */
3606 int intro_point_lifetime_seconds
=
3607 crypto_rand_int_range(INTRO_POINT_LIFETIME_MIN_SECONDS
,
3608 INTRO_POINT_LIFETIME_MAX_SECONDS
);
3610 /* Start the expiration timer now, rather than when the intro
3611 * point was first published. There shouldn't be much of a time
3613 intro
->time_to_expire
= now
+ intro_point_lifetime_seconds
;
3618 /* This intro point has a time to expire set already. Use it. */
3619 return (now
>= intro
->time_to_expire
);
3622 /** Iterate over intro points in the given service and remove the invalid
3623 * ones. For an intro point object to be considered invalid, the circuit
3624 * _and_ node need to have disappeared.
3626 * If the intro point should expire, it's placed into the expiring_nodes
3627 * list of the service and removed from the active intro nodes list.
3629 * If <b>exclude_nodes</b> is not NULL, add the valid nodes to it.
3631 * If <b>retry_nodes</b> is not NULL, add the valid node to it if the
3632 * circuit disappeared but the node is still in the consensus. */
3634 remove_invalid_intro_points(rend_service_t
*service
,
3635 smartlist_t
*exclude_nodes
,
3636 smartlist_t
*retry_nodes
, time_t now
)
3638 tor_assert(service
);
3640 SMARTLIST_FOREACH_BEGIN(service
->intro_nodes
, rend_intro_point_t
*,
3642 /* Find the introduction point node object. */
3643 const node_t
*node
=
3644 node_get_by_id(intro
->extend_info
->identity_digest
);
3645 /* Find the intro circuit, this might be NULL. */
3646 origin_circuit_t
*intro_circ
=
3647 find_intro_circuit(intro
, service
->pk_digest
);
3649 /* Add the valid node to the exclusion list so we don't try to establish
3650 * an introduction point to it again. */
3651 if (node
&& exclude_nodes
) {
3652 smartlist_add(exclude_nodes
, (void*) node
);
3655 /* First, make sure we still have a valid circuit for this intro point.
3656 * If we dont, we'll give up on it and make a new one. */
3657 if (intro_circ
== NULL
) {
3658 log_info(LD_REND
, "Attempting to retry on %s as intro point for %s"
3659 " (circuit disappeared).",
3660 safe_str_client(extend_info_describe(intro
->extend_info
)),
3661 safe_str_client(service
->service_id
));
3662 /* We've lost the circuit for this intro point, flag it so it can be
3663 * accounted for when considiring uploading a descriptor. */
3664 intro
->circuit_established
= 0;
3666 /* Node is gone or we've reached our maximum circuit creationg retry
3667 * count, clean up everything, we'll find a new one. */
3669 intro
->circuit_retries
>= MAX_INTRO_POINT_CIRCUIT_RETRIES
) {
3670 rend_intro_point_free(intro
);
3671 SMARTLIST_DEL_CURRENT(service
->intro_nodes
, intro
);
3672 /* We've just killed the intro point, nothing left to do. */
3676 /* The intro point is still alive so let's try to use it again because
3677 * we have a published descriptor containing it. Keep the intro point
3678 * in the intro_nodes list because it's still valid, we are rebuilding
3679 * a circuit to it. */
3681 smartlist_add(retry_nodes
, intro
);
3684 /* else, the circuit is valid so in both cases, node being alive or not,
3685 * we leave the circuit and intro point object as is. Closing the
3686 * circuit here would leak new consensus timing and freeing the intro
3687 * point object would make the intro circuit unusable. */
3689 /* Now, check if intro point should expire. If it does, queue it so
3690 * it can be cleaned up once it has been replaced properly. */
3691 if (intro_point_should_expire_now(intro
, now
)) {
3692 log_info(LD_REND
, "Expiring %s as intro point for %s.",
3693 safe_str_client(extend_info_describe(intro
->extend_info
)),
3694 safe_str_client(service
->service_id
));
3695 smartlist_add(service
->expiring_nodes
, intro
);
3696 SMARTLIST_DEL_CURRENT(service
->intro_nodes
, intro
);
3697 /* Intro point is expired, we need a new one thus don't consider it
3698 * anymore has a valid established intro point. */
3699 intro
->circuit_established
= 0;
3701 } SMARTLIST_FOREACH_END(intro
);
3704 /** A new descriptor has been successfully uploaded for the given
3705 * <b>rend_data</b>. Remove and free the expiring nodes from the associated
3708 rend_service_desc_has_uploaded(const rend_data_t
*rend_data
)
3710 rend_service_t
*service
;
3712 tor_assert(rend_data
);
3714 service
= rend_service_get_by_service_id(rend_data
->onion_address
);
3715 if (service
== NULL
) {
3719 SMARTLIST_FOREACH_BEGIN(service
->expiring_nodes
, rend_intro_point_t
*,
3721 origin_circuit_t
*intro_circ
=
3722 find_intro_circuit(intro
, service
->pk_digest
);
3723 if (intro_circ
!= NULL
) {
3724 circuit_mark_for_close(TO_CIRCUIT(intro_circ
),
3725 END_CIRC_REASON_FINISHED
);
3727 SMARTLIST_DEL_CURRENT(service
->expiring_nodes
, intro
);
3728 rend_intro_point_free(intro
);
3729 } SMARTLIST_FOREACH_END(intro
);
3732 /** For every service, check how many intro points it currently has, and:
3733 * - Invalidate introdution points based on specific criteria, see
3734 * remove_invalid_intro_points comments.
3735 * - Pick new intro points as necessary.
3736 * - Launch circuits to any new intro points.
3738 * This is called once a second by the main loop.
3741 rend_consider_services_intro_points(void)
3745 const or_options_t
*options
= get_options();
3746 /* Are we in single onion mode? */
3747 const int allow_direct
= rend_service_allow_non_anonymous_connection(
3749 /* List of nodes we need to _exclude_ when choosing a new node to
3750 * establish an intro point to. */
3751 smartlist_t
*exclude_nodes
;
3752 /* List of nodes we need to retry to build a circuit on them because the
3753 * node is valid but circuit died. */
3754 smartlist_t
*retry_nodes
;
3756 if (!have_completed_a_circuit())
3759 exclude_nodes
= smartlist_new();
3760 retry_nodes
= smartlist_new();
3763 SMARTLIST_FOREACH_BEGIN(rend_service_list
, rend_service_t
*, service
) {
3765 /* Number of intro points we want to open and add to the intro nodes
3766 * list of the service. */
3767 unsigned int n_intro_points_to_open
;
3768 /* Have an unsigned len so we can use it to compare values else gcc is
3769 * not happy with unmatching signed comparaison. */
3770 unsigned int intro_nodes_len
;
3771 /* Different service are allowed to have the same introduction point as
3772 * long as they are on different circuit thus why we clear this list. */
3773 smartlist_clear(exclude_nodes
);
3774 smartlist_clear(retry_nodes
);
3776 /* This retry period is important here so we don't stress circuit
3778 if (now
> service
->intro_period_started
+ INTRO_CIRC_RETRY_PERIOD
) {
3779 /* One period has elapsed; we can try building circuits again. */
3780 service
->intro_period_started
= now
;
3781 service
->n_intro_circuits_launched
= 0;
3782 } else if (service
->n_intro_circuits_launched
>=
3783 MAX_INTRO_CIRCS_PER_PERIOD
) {
3784 /* We have failed too many times in this period; wait for the next
3785 * one before we try again. */
3789 /* Cleanup the invalid intro points and save the node objects, if apply,
3790 * in the exclude_nodes and retry_nodes list. */
3791 remove_invalid_intro_points(service
, exclude_nodes
, retry_nodes
, now
);
3793 /* Let's try to rebuild circuit on the nodes we want to retry on. */
3794 SMARTLIST_FOREACH_BEGIN(retry_nodes
, rend_intro_point_t
*, intro
) {
3795 r
= rend_service_launch_establish_intro(service
, intro
);
3797 log_warn(LD_REND
, "Error launching circuit to node %s for service %s.",
3798 safe_str_client(extend_info_describe(intro
->extend_info
)),
3799 safe_str_client(service
->service_id
));
3800 /* Unable to launch a circuit to that intro point, remove it from
3801 * the valid list so we can create a new one. */
3802 smartlist_remove(service
->intro_nodes
, intro
);
3803 rend_intro_point_free(intro
);
3806 intro
->circuit_retries
++;
3807 } SMARTLIST_FOREACH_END(intro
);
3809 /* Avoid mismatched signed comparaison below. */
3810 intro_nodes_len
= (unsigned int) smartlist_len(service
->intro_nodes
);
3812 /* Quiescent state, no node expiring and we have more or the amount of
3813 * wanted node for this service. Proceed to the next service. Could be
3814 * more because we launch two preemptive circuits if our intro nodes
3816 if (smartlist_len(service
->expiring_nodes
) == 0 &&
3817 intro_nodes_len
>= service
->n_intro_points_wanted
) {
3821 /* Number of intro points we want to open which is the wanted amount
3822 * minus the current amount of valid nodes. */
3823 n_intro_points_to_open
= service
->n_intro_points_wanted
- intro_nodes_len
;
3824 if (intro_nodes_len
== 0) {
3825 /* We want to end up with n_intro_points_wanted intro points, but if
3826 * we have no intro points at all (chances are they all cycled or we
3827 * are starting up), we launch NUM_INTRO_POINTS_EXTRA extra circuits
3828 * and use the first n_intro_points_wanted that complete. See proposal
3829 * #155, section 4 for the rationale of this which is purely for
3832 * The ones after the first n_intro_points_to_open will be converted
3833 * to 'general' internal circuits in rend_service_intro_has_opened(),
3834 * and then we'll drop them from the list of intro points. */
3835 n_intro_points_to_open
+= NUM_INTRO_POINTS_EXTRA
;
3838 for (i
= 0; i
< (int) n_intro_points_to_open
; i
++) {
3840 rend_intro_point_t
*intro
;
3841 router_crn_flags_t flags
= CRN_NEED_UPTIME
|CRN_NEED_DESC
;
3842 if (get_options()->AllowInvalid_
& ALLOW_INVALID_INTRODUCTION
)
3843 flags
|= CRN_ALLOW_INVALID
;
3844 router_crn_flags_t direct_flags
= flags
;
3845 direct_flags
|= CRN_PREF_ADDR
;
3846 direct_flags
|= CRN_DIRECT_CONN
;
3848 node
= router_choose_random_node(exclude_nodes
,
3849 options
->ExcludeNodes
,
3850 allow_direct
? direct_flags
: flags
);
3851 /* If we are in single onion mode, retry node selection for a 3-hop
3853 if (allow_direct
&& !node
) {
3855 "Unable to find an intro point that we can connect to "
3856 "directly for %s, falling back to a 3-hop path.",
3857 safe_str_client(service
->service_id
));
3858 node
= router_choose_random_node(exclude_nodes
,
3859 options
->ExcludeNodes
, flags
);
3864 "We only have %d introduction points established for %s; "
3866 smartlist_len(service
->intro_nodes
),
3867 safe_str_client(service
->service_id
),
3868 n_intro_points_to_open
);
3871 /* Add the choosen node to the exclusion list in order to avoid picking
3872 * it again in the next iteration. */
3873 smartlist_add(exclude_nodes
, (void*)node
);
3874 intro
= tor_malloc_zero(sizeof(rend_intro_point_t
));
3875 /* extend_info is for clients, so we want the multi-hop primary ORPort,
3876 * even if we are a single onion service and intend to connect to it
3877 * directly ourselves. */
3878 intro
->extend_info
= extend_info_from_node(node
, 0);
3879 intro
->intro_key
= crypto_pk_new();
3880 const int fail
= crypto_pk_generate_key(intro
->intro_key
);
3882 intro
->time_published
= -1;
3883 intro
->time_to_expire
= -1;
3884 intro
->max_introductions
=
3885 crypto_rand_int_range(INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS
,
3886 INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS
);
3887 smartlist_add(service
->intro_nodes
, intro
);
3888 log_info(LD_REND
, "Picked router %s as an intro point for %s.",
3889 safe_str_client(node_describe(node
)),
3890 safe_str_client(service
->service_id
));
3891 /* Establish new introduction circuit to our chosen intro point. */
3892 r
= rend_service_launch_establish_intro(service
, intro
);
3894 log_warn(LD_REND
, "Error launching circuit to node %s for service %s.",
3895 safe_str_client(extend_info_describe(intro
->extend_info
)),
3896 safe_str_client(service
->service_id
));
3897 /* This funcion will be called again by the main loop so this intro
3898 * point without a intro circuit will be retried on or removed after
3899 * a maximum number of attempts. */
3902 } SMARTLIST_FOREACH_END(service
);
3903 smartlist_free(exclude_nodes
);
3904 smartlist_free(retry_nodes
);
3907 #define MIN_REND_INITIAL_POST_DELAY (30)
3908 #define MIN_REND_INITIAL_POST_DELAY_TESTING (5)
3910 /** Regenerate and upload rendezvous service descriptors for all
3911 * services, if necessary. If the descriptor has been dirty enough
3912 * for long enough, definitely upload; else only upload when the
3913 * periodic timeout has expired.
3915 * For the first upload, pick a random time between now and two periods
3916 * from now, and pick it independently for each service.
3919 rend_consider_services_upload(time_t now
)
3922 rend_service_t
*service
;
3923 const or_options_t
*options
= get_options();
3924 int rendpostperiod
= options
->RendPostPeriod
;
3925 int rendinitialpostdelay
= (options
->TestingTorNetwork
?
3926 MIN_REND_INITIAL_POST_DELAY_TESTING
:
3927 MIN_REND_INITIAL_POST_DELAY
);
3929 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
3930 service
= smartlist_get(rend_service_list
, i
);
3931 if (!service
->next_upload_time
) { /* never been uploaded yet */
3932 /* The fixed lower bound of rendinitialpostdelay seconds ensures that
3933 * the descriptor is stable before being published. See comment below. */
3934 service
->next_upload_time
=
3935 now
+ rendinitialpostdelay
+ crypto_rand_int(2*rendpostperiod
);
3936 /* Single Onion Services prioritise availability over hiding their
3937 * startup time, as their IP address is publicly discoverable anyway.
3939 if (rend_service_reveal_startup_time(options
)) {
3940 service
->next_upload_time
= now
+ rendinitialpostdelay
;
3943 /* Does every introduction points have been established? */
3944 unsigned int intro_points_ready
=
3945 count_established_intro_points(service
) >=
3946 service
->n_intro_points_wanted
;
3947 if (intro_points_ready
&&
3948 (service
->next_upload_time
< now
||
3949 (service
->desc_is_dirty
&&
3950 service
->desc_is_dirty
< now
-rendinitialpostdelay
))) {
3951 /* if it's time, or if the directory servers have a wrong service
3952 * descriptor and ours has been stable for rendinitialpostdelay seconds,
3953 * upload a new one of each format. */
3954 rend_service_update_descriptor(service
);
3955 upload_service_descriptor(service
);
3960 /** True if the list of available router descriptors might have changed so
3961 * that we should have a look whether we can republish previously failed
3962 * rendezvous service descriptors. */
3963 static int consider_republishing_rend_descriptors
= 1;
3965 /** Called when our internal view of the directory has changed, so that we
3966 * might have router descriptors of hidden service directories available that
3967 * we did not have before. */
3969 rend_hsdir_routers_changed(void)
3971 consider_republishing_rend_descriptors
= 1;
3974 /** Consider republication of v2 rendezvous service descriptors that failed
3975 * previously, but without regenerating descriptor contents.
3978 rend_consider_descriptor_republication(void)
3981 rend_service_t
*service
;
3983 if (!consider_republishing_rend_descriptors
)
3985 consider_republishing_rend_descriptors
= 0;
3987 if (!get_options()->PublishHidServDescriptors
)
3990 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
3991 service
= smartlist_get(rend_service_list
, i
);
3992 if (service
->desc
&& !service
->desc
->all_uploads_performed
) {
3993 /* If we failed in uploading a descriptor last time, try again *without*
3994 * updating the descriptor's contents. */
3995 upload_service_descriptor(service
);
4000 /** Log the status of introduction points for all rendezvous services
4001 * at log severity <b>severity</b>.
4004 rend_service_dump_stats(int severity
)
4007 rend_service_t
*service
;
4008 rend_intro_point_t
*intro
;
4009 const char *safe_name
;
4010 origin_circuit_t
*circ
;
4012 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
4013 service
= smartlist_get(rend_service_list
, i
);
4014 tor_log(severity
, LD_GENERAL
, "Service configured in \"%s\":",
4015 service
->directory
);
4016 for (j
=0; j
< smartlist_len(service
->intro_nodes
); ++j
) {
4017 intro
= smartlist_get(service
->intro_nodes
, j
);
4018 safe_name
= safe_str_client(intro
->extend_info
->nickname
);
4020 circ
= find_intro_circuit(intro
, service
->pk_digest
);
4022 tor_log(severity
, LD_GENERAL
, " Intro point %d at %s: no circuit",
4026 tor_log(severity
, LD_GENERAL
, " Intro point %d at %s: circuit is %s",
4027 j
, safe_name
, circuit_state_to_string(circ
->base_
.state
));
4032 #ifdef HAVE_SYS_UN_H
4034 /** Given <b>ports</b>, a smarlist containing rend_service_port_config_t,
4035 * add the given <b>p</b>, a AF_UNIX port to the list. Return 0 on success
4036 * else return -ENOSYS if AF_UNIX is not supported (see function in the
4037 * #else statement below). */
4039 add_unix_port(smartlist_t
*ports
, rend_service_port_config_t
*p
)
4043 tor_assert(p
->is_unix_addr
);
4045 smartlist_add(ports
, p
);
4049 /** Given <b>conn</b> set it to use the given port <b>p</b> values. Return 0
4050 * on success else return -ENOSYS if AF_UNIX is not supported (see function
4051 * in the #else statement below). */
4053 set_unix_port(edge_connection_t
*conn
, rend_service_port_config_t
*p
)
4057 tor_assert(p
->is_unix_addr
);
4059 conn
->base_
.socket_family
= AF_UNIX
;
4060 tor_addr_make_unspec(&conn
->base_
.addr
);
4061 conn
->base_
.port
= 1;
4062 conn
->base_
.address
= tor_strdup(p
->unix_addr
);
4066 #else /* defined(HAVE_SYS_UN_H) */
4069 set_unix_port(edge_connection_t
*conn
, rend_service_port_config_t
*p
)
4077 add_unix_port(smartlist_t
*ports
, rend_service_port_config_t
*p
)
4084 #endif /* HAVE_SYS_UN_H */
4086 /** Given <b>conn</b>, a rendezvous exit stream, look up the hidden service for
4087 * 'circ', and look up the port and address based on conn-\>port.
4088 * Assign the actual conn-\>addr and conn-\>port. Return -2 on failure
4089 * for which the circuit should be closed, -1 on other failure,
4093 rend_service_set_connection_addr_port(edge_connection_t
*conn
,
4094 origin_circuit_t
*circ
)
4096 rend_service_t
*service
;
4097 char serviceid
[REND_SERVICE_ID_LEN_BASE32
+1];
4098 smartlist_t
*matching_ports
;
4099 rend_service_port_config_t
*chosen_port
;
4100 unsigned int warn_once
= 0;
4102 tor_assert(circ
->base_
.purpose
== CIRCUIT_PURPOSE_S_REND_JOINED
);
4103 tor_assert(circ
->rend_data
);
4104 log_debug(LD_REND
,"beginning to hunt for addr/port");
4105 base32_encode(serviceid
, REND_SERVICE_ID_LEN_BASE32
+1,
4106 circ
->rend_data
->rend_pk_digest
, REND_SERVICE_ID_LEN
);
4107 service
= rend_service_get_by_pk_digest(
4108 circ
->rend_data
->rend_pk_digest
);
4110 log_warn(LD_REND
, "Couldn't find any service associated with pk %s on "
4111 "rendezvous circuit %u; closing.",
4112 serviceid
, (unsigned)circ
->base_
.n_circ_id
);
4115 if (service
->max_streams_per_circuit
> 0) {
4116 /* Enforce the streams-per-circuit limit, and refuse to provide a
4117 * mapping if this circuit will exceed the limit. */
4118 #define MAX_STREAM_WARN_INTERVAL 600
4119 static struct ratelim_t stream_ratelim
=
4120 RATELIM_INIT(MAX_STREAM_WARN_INTERVAL
);
4121 if (circ
->rend_data
->nr_streams
>= service
->max_streams_per_circuit
) {
4122 log_fn_ratelim(&stream_ratelim
, LOG_WARN
, LD_REND
,
4123 "Maximum streams per circuit limit reached on rendezvous "
4124 "circuit %u; %s. Circuit has %d out of %d streams.",
4125 (unsigned)circ
->base_
.n_circ_id
,
4126 service
->max_streams_close_circuit
?
4128 "ignoring open stream request",
4129 circ
->rend_data
->nr_streams
,
4130 service
->max_streams_per_circuit
);
4131 return service
->max_streams_close_circuit
? -2 : -1;
4134 matching_ports
= smartlist_new();
4135 SMARTLIST_FOREACH(service
->ports
, rend_service_port_config_t
*, p
,
4137 if (conn
->base_
.port
!= p
->virtual_port
) {
4140 if (!(p
->is_unix_addr
)) {
4141 smartlist_add(matching_ports
, p
);
4143 if (add_unix_port(matching_ports
, p
)) {
4145 /* Unix port not supported so warn only once. */
4147 "Saw AF_UNIX virtual port mapping for port %d on service "
4148 "%s, which is unsupported on this platform. Ignoring it.",
4149 conn
->base_
.port
, serviceid
);
4155 chosen_port
= smartlist_choose(matching_ports
);
4156 smartlist_free(matching_ports
);
4158 if (!(chosen_port
->is_unix_addr
)) {
4159 /* Get a non-AF_UNIX connection ready for connection_exit_connect() */
4160 tor_addr_copy(&conn
->base_
.addr
, &chosen_port
->real_addr
);
4161 conn
->base_
.port
= chosen_port
->real_port
;
4163 if (set_unix_port(conn
, chosen_port
)) {
4164 /* Simply impossible to end up here else we were able to add a Unix
4165 * port without AF_UNIX support... ? */
4173 "No virtual port mapping exists for port %d on service %s",
4174 conn
->base_
.port
, serviceid
);
4176 if (service
->allow_unknown_ports
)
4182 /* Are HiddenServiceSingleHopMode and HiddenServiceNonAnonymousMode consistent?
4185 rend_service_non_anonymous_mode_consistent(const or_options_t
*options
)
4187 /* !! is used to make these options boolean */
4188 return (!! options
->HiddenServiceSingleHopMode
==
4189 !! options
->HiddenServiceNonAnonymousMode
);
4192 /* Do the options allow onion services to make direct (non-anonymous)
4193 * connections to introduction or rendezvous points?
4194 * Must only be called after options_validate_single_onion() has successfully
4195 * checked onion service option consistency.
4196 * Returns true if tor is in HiddenServiceSingleHopMode. */
4198 rend_service_allow_non_anonymous_connection(const or_options_t
*options
)
4200 tor_assert(rend_service_non_anonymous_mode_consistent(options
));
4201 return options
->HiddenServiceSingleHopMode
? 1 : 0;
4204 /* Do the options allow us to reveal the exact startup time of the onion
4206 * Single Onion Services prioritise availability over hiding their
4207 * startup time, as their IP address is publicly discoverable anyway.
4208 * Must only be called after options_validate_single_onion() has successfully
4209 * checked onion service option consistency.
4210 * Returns true if tor is in non-anonymous hidden service mode. */
4212 rend_service_reveal_startup_time(const or_options_t
*options
)
4214 tor_assert(rend_service_non_anonymous_mode_consistent(options
));
4215 return rend_service_non_anonymous_mode_enabled(options
);
4218 /* Is non-anonymous mode enabled using the HiddenServiceNonAnonymousMode
4220 * Must only be called after options_validate_single_onion() has successfully
4221 * checked onion service option consistency.
4224 rend_service_non_anonymous_mode_enabled(const or_options_t
*options
)
4226 tor_assert(rend_service_non_anonymous_mode_consistent(options
));
4227 return options
->HiddenServiceNonAnonymousMode
? 1 : 0;