1 /* Copyright 2004-2007 Roger Dingledine, Nick Mathewson. */
2 /* See LICENSE for licensing information */
4 const char rendservice_c_id
[] =
9 * \brief The hidden-service side of rendezvous functionality.
14 static origin_circuit_t
*find_intro_circuit(routerinfo_t
*router
,
15 const char *pk_digest
);
17 /** Represents the mapping from a virtual port of a rendezvous service to
18 * a real port on some IP.
20 typedef struct rend_service_port_config_t
{
21 uint16_t virtual_port
;
24 } rend_service_port_config_t
;
26 /** Try to maintain this many intro points per service if possible. */
27 #define NUM_INTRO_POINTS 3
29 /** If we can't build our intro circuits, don't retry for this long. */
30 #define INTRO_CIRC_RETRY_PERIOD (60*5)
31 /** Don't try to build more than this many circuits before giving up
33 #define MAX_INTRO_CIRCS_PER_PERIOD 10
34 /** How many times will a hidden service operator attempt to connect to
35 * a requested rendezvous point before giving up? */
36 #define MAX_REND_FAILURES 30
37 /** How many seconds should we spend trying to connect to a requested
38 * rendezvous point before giving up? */
39 #define MAX_REND_TIMEOUT 30
41 /** Represents a single hidden service running at this OP. */
42 typedef struct rend_service_t
{
43 /** Fields specified in config file */
44 char *directory
; /**< where in the filesystem it stores it */
45 smartlist_t
*ports
; /**< List of rend_service_port_config_t */
46 char *intro_prefer_nodes
; /**< comma-separated list of nicknames */
47 char *intro_exclude_nodes
; /**< comma-separated list of nicknames */
49 crypto_pk_env_t
*private_key
;
50 char service_id
[REND_SERVICE_ID_LEN
+1];
51 char pk_digest
[DIGEST_LEN
];
52 smartlist_t
*intro_nodes
; /**< list of hexdigests for intro points we have,
53 * or are trying to establish. */
54 time_t intro_period_started
;
55 int n_intro_circuits_launched
; /**< count of intro circuits we have
56 * established in this period. */
57 rend_service_descriptor_t
*desc
;
59 time_t next_upload_time
;
62 /** A list of rend_service_t's for services run on this OP.
64 static smartlist_t
*rend_service_list
= NULL
;
66 /** Return the number of rendezvous services we have configured. */
68 num_rend_services(void)
70 if (!rend_service_list
)
72 return smartlist_len(rend_service_list
);
75 /** Release the storage held by <b>service</b>.
78 rend_service_free(rend_service_t
*service
)
81 tor_free(service
->directory
);
82 SMARTLIST_FOREACH(service
->ports
, void*, p
, tor_free(p
));
83 smartlist_free(service
->ports
);
84 if (service
->private_key
)
85 crypto_free_pk_env(service
->private_key
);
86 tor_free(service
->intro_prefer_nodes
);
87 tor_free(service
->intro_exclude_nodes
);
88 SMARTLIST_FOREACH(service
->intro_nodes
, void*, p
, tor_free(p
));
89 smartlist_free(service
->intro_nodes
);
91 rend_service_descriptor_free(service
->desc
);
95 /** Release all the storage held in rend_service_list.
98 rend_service_free_all(void)
100 if (!rend_service_list
) {
103 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, ptr
,
104 rend_service_free(ptr
));
105 smartlist_free(rend_service_list
);
106 rend_service_list
= NULL
;
109 /** Validate <b>service</b> and add it to rend_service_list if possible.
112 add_service(rend_service_t
*service
)
115 rend_service_port_config_t
*p
;
118 if (!service
->intro_prefer_nodes
)
119 service
->intro_prefer_nodes
= tor_strdup("");
120 if (!service
->intro_exclude_nodes
)
121 service
->intro_exclude_nodes
= tor_strdup("");
123 if (!smartlist_len(service
->ports
)) {
124 log_warn(LD_CONFIG
, "Hidden service with no ports configured; ignoring.");
125 rend_service_free(service
);
127 smartlist_set_capacity(service
->ports
, -1);
128 smartlist_add(rend_service_list
, service
);
129 log_debug(LD_REND
,"Configuring service with directory \"%s\"",
131 for (i
= 0; i
< smartlist_len(service
->ports
); ++i
) {
132 char addrbuf
[INET_NTOA_BUF_LEN
];
133 p
= smartlist_get(service
->ports
, i
);
134 addr
.s_addr
= htonl(p
->real_addr
);
135 tor_inet_ntoa(&addr
, addrbuf
, sizeof(addrbuf
));
136 log_debug(LD_REND
,"Service maps port %d to %s:%d",
137 p
->virtual_port
, addrbuf
, p
->real_port
);
142 /** Parses a real-port to virtual-port mapping and returns a new
143 * rend_service_port_config_t.
145 * The format is: VirtualPort (IP|RealPort|IP:RealPort)?
147 * IP defaults to 127.0.0.1; RealPort defaults to VirtualPort.
149 static rend_service_port_config_t
*
150 parse_port_config(const char *string
)
157 const char *addrport
;
158 rend_service_port_config_t
*result
= NULL
;
160 sl
= smartlist_create();
161 smartlist_split_string(sl
, string
, " ",
162 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
163 if (smartlist_len(sl
) < 1 || smartlist_len(sl
) > 2) {
164 log_warn(LD_CONFIG
, "Bad syntax in hidden service port configuration.");
168 virtport
= atoi(smartlist_get(sl
,0));
169 if (virtport
< 1 || virtport
> 65535) {
170 log_warn(LD_CONFIG
, "Missing or invalid port in hidden service port "
175 if (smartlist_len(sl
) == 1) {
176 /* No addr:port part; use default. */
178 addr
= 0x7F000001u
; /* 127.0.0.1 */
180 addrport
= smartlist_get(sl
,1);
181 if (strchr(addrport
, ':') || strchr(addrport
, '.')) {
182 if (parse_addr_port(LOG_WARN
, addrport
, NULL
, &addr
, &p
)<0) {
183 log_warn(LD_CONFIG
,"Unparseable address in hidden service port "
187 realport
= p
?p
:virtport
;
189 /* No addr:port, no addr -- must be port. */
190 realport
= atoi(addrport
);
191 if (realport
< 1 || realport
> 65535)
193 addr
= 0x7F000001u
; /* Default to 127.0.0.1 */
197 result
= tor_malloc(sizeof(rend_service_port_config_t
));
198 result
->virtual_port
= virtport
;
199 result
->real_port
= realport
;
200 result
->real_addr
= addr
;
202 SMARTLIST_FOREACH(sl
, char *, c
, tor_free(c
));
207 /** Set up rend_service_list, based on the values of HiddenServiceDir and
208 * HiddenServicePort in <b>options</b>. Return 0 on success and -1 on
209 * failure. (If <b>validate_only</b> is set, parse, warn and return as
210 * normal, but don't actually change the configured services.)
213 rend_config_services(or_options_t
*options
, int validate_only
)
216 rend_service_t
*service
= NULL
;
217 rend_service_port_config_t
*portcfg
;
219 if (!validate_only
) {
220 rend_service_free_all();
221 rend_service_list
= smartlist_create();
224 for (line
= options
->RendConfigLines
; line
; line
= line
->next
) {
225 if (!strcasecmp(line
->key
, "HiddenServiceDir")) {
228 rend_service_free(service
);
230 add_service(service
);
232 service
= tor_malloc_zero(sizeof(rend_service_t
));
233 service
->directory
= tor_strdup(line
->value
);
234 service
->ports
= smartlist_create();
235 service
->intro_nodes
= smartlist_create();
236 service
->intro_period_started
= time(NULL
);
240 log_warn(LD_CONFIG
, "%s with no preceding HiddenServiceDir directive",
242 rend_service_free(service
);
245 if (!strcasecmp(line
->key
, "HiddenServicePort")) {
246 portcfg
= parse_port_config(line
->value
);
248 rend_service_free(service
);
251 smartlist_add(service
->ports
, portcfg
);
252 } else if (!strcasecmp(line
->key
, "HiddenServiceNodes")) {
253 if (service
->intro_prefer_nodes
) {
255 "Got multiple HiddenServiceNodes lines for a single "
259 service
->intro_prefer_nodes
= tor_strdup(line
->value
);
261 tor_assert(!strcasecmp(line
->key
, "HiddenServiceExcludeNodes"));
262 if (service
->intro_exclude_nodes
) {
264 "Got multiple HiddenServiceExcludedNodes lines for "
265 "a single service.");
268 service
->intro_exclude_nodes
= tor_strdup(line
->value
);
273 rend_service_free(service
);
275 add_service(service
);
281 /** Replace the old value of <b>service</b>-\>desc with one that reflects
282 * the other fields in service.
285 rend_service_update_descriptor(rend_service_t
*service
)
287 rend_service_descriptor_t
*d
;
288 origin_circuit_t
*circ
;
290 routerinfo_t
*router
;
293 rend_service_descriptor_free(service
->desc
);
294 service
->desc
= NULL
;
296 d
= service
->desc
= tor_malloc(sizeof(rend_service_descriptor_t
));
297 d
->pk
= crypto_pk_dup_key(service
->private_key
);
298 d
->timestamp
= time(NULL
);
300 n
= smartlist_len(service
->intro_nodes
);
301 d
->n_intro_points
= 0;
302 d
->intro_points
= tor_malloc_zero(sizeof(char*)*n
);
303 d
->intro_point_extend_info
= tor_malloc_zero(sizeof(extend_info_t
*)*n
);
304 d
->protocols
= (1<<2) | (1<<0); /* We support protocol 2 and protocol 0. */
305 for (i
=0; i
< n
; ++i
) {
306 router
= router_get_by_nickname(smartlist_get(service
->intro_nodes
, i
),1);
308 log_info(LD_REND
,"Router '%s' not found for intro point %d. Skipping.",
309 safe_str((char*)smartlist_get(service
->intro_nodes
, i
)), i
);
312 circ
= find_intro_circuit(router
, service
->pk_digest
);
313 if (circ
&& circ
->_base
.purpose
== CIRCUIT_PURPOSE_S_INTRO
) {
314 /* We have an entirely established intro circuit. */
315 d
->intro_points
[d
->n_intro_points
] = tor_strdup(router
->nickname
);
316 d
->intro_point_extend_info
[d
->n_intro_points
] =
317 extend_info_from_router(router
);
323 /** Load and/or generate private keys for all hidden services. Return 0 on
324 * success, -1 on failure.
327 rend_service_load_keys(void)
334 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
335 s
= smartlist_get(rend_service_list
,i
);
338 log_info(LD_REND
, "Loading hidden-service keys from \"%s\"",
341 /* Check/create directory */
342 if (check_private_dir(s
->directory
, CPD_CREATE
) < 0)
346 if (strlcpy(fname
,s
->directory
,sizeof(fname
)) >= sizeof(fname
) ||
347 strlcat(fname
,"/private_key",sizeof(fname
)) >= sizeof(fname
)) {
348 log_warn(LD_CONFIG
, "Directory name too long to store key file: \"%s\".",
352 s
->private_key
= init_key_from_file(fname
);
356 /* Create service file */
357 if (rend_get_service_id(s
->private_key
, s
->service_id
)<0) {
358 log_warn(LD_BUG
, "Internal error: couldn't encode service ID.");
361 if (crypto_pk_get_digest(s
->private_key
, s
->pk_digest
)<0) {
362 log_warn(LD_BUG
, "Bug: Couldn't compute hash of public key.");
365 if (strlcpy(fname
,s
->directory
,sizeof(fname
)) >= sizeof(fname
) ||
366 strlcat(fname
,"/hostname",sizeof(fname
)) >= sizeof(fname
)) {
367 log_warn(LD_CONFIG
, "Directory name too long to store hostname file:"
368 " \"%s\".", s
->directory
);
371 tor_snprintf(buf
, sizeof(buf
),"%s.onion\n", s
->service_id
);
372 if (write_str_to_file(fname
,buf
,0)<0)
378 /** Return the service whose public key has a digest of <b>digest</b>. Return
379 * NULL if no such service exists.
381 static rend_service_t
*
382 rend_service_get_by_pk_digest(const char* digest
)
384 SMARTLIST_FOREACH(rend_service_list
, rend_service_t
*, s
,
385 if (!memcmp(s
->pk_digest
,digest
,DIGEST_LEN
)) return s
);
389 /** Return 1 if any virtual port in <b>service</b> wants a circuit
390 * to have good uptime. Else return 0.
393 rend_service_requires_uptime(rend_service_t
*service
)
396 rend_service_port_config_t
*p
;
398 for (i
=0; i
< smartlist_len(service
->ports
); ++i
) {
399 p
= smartlist_get(service
->ports
, i
);
400 if (smartlist_string_num_isin(get_options()->LongLivedPorts
,
411 /** Respond to an INTRODUCE2 cell by launching a circuit to the chosen
415 rend_service_introduce(origin_circuit_t
*circuit
, const char *request
,
418 char *ptr
, *r_cookie
;
419 extend_info_t
*extend_info
= NULL
;
420 char buf
[RELAY_PAYLOAD_SIZE
];
421 char keys
[DIGEST_LEN
+CPATH_KEY_MATERIAL_LEN
]; /* Holds KH, Df, Db, Kf, Kb */
422 rend_service_t
*service
;
425 crypto_dh_env_t
*dh
= NULL
;
426 origin_circuit_t
*launched
= NULL
;
427 crypt_path_t
*cpath
= NULL
;
428 char serviceid
[REND_SERVICE_ID_LEN
+1];
430 int circ_needs_uptime
;
431 int reason
= END_CIRC_REASON_TORPROTOCOL
;
433 base32_encode(serviceid
, REND_SERVICE_ID_LEN
+1,
434 circuit
->rend_pk_digest
,10);
435 log_info(LD_REND
, "Received INTRODUCE2 cell for service %s on circ %d.",
436 escaped(serviceid
), circuit
->_base
.n_circ_id
);
438 if (circuit
->_base
.purpose
!= CIRCUIT_PURPOSE_S_INTRO
) {
439 log_warn(LD_PROTOCOL
,
440 "Got an INTRODUCE2 over a non-introduction circuit %d.",
441 circuit
->_base
.n_circ_id
);
445 /* min key length plus digest length plus nickname length */
446 if (request_len
< DIGEST_LEN
+REND_COOKIE_LEN
+(MAX_NICKNAME_LEN
+1)+
448 log_warn(LD_PROTOCOL
, "Got a truncated INTRODUCE2 cell on circ %d.",
449 circuit
->_base
.n_circ_id
);
453 /* first DIGEST_LEN bytes of request is service pk digest */
454 service
= rend_service_get_by_pk_digest(request
);
456 log_warn(LD_REND
, "Got an INTRODUCE2 cell for an unrecognized service %s.",
460 if (memcmp(circuit
->rend_pk_digest
, request
, DIGEST_LEN
)) {
461 base32_encode(serviceid
, REND_SERVICE_ID_LEN
+1, request
, 10);
462 log_warn(LD_REND
, "Got an INTRODUCE2 cell for the wrong service (%s).",
467 keylen
= crypto_pk_keysize(service
->private_key
);
468 if (request_len
< keylen
+DIGEST_LEN
) {
469 log_warn(LD_PROTOCOL
,
470 "PK-encrypted portion of INTRODUCE2 cell was truncated.");
473 /* Next N bytes is encrypted with service key */
474 note_crypto_pk_op(REND_SERVER
);
475 r
= crypto_pk_private_hybrid_decrypt(
476 service
->private_key
,buf
,request
+DIGEST_LEN
,request_len
-DIGEST_LEN
,
477 PK_PKCS1_OAEP_PADDING
,1);
479 log_warn(LD_PROTOCOL
, "Couldn't decrypt INTRODUCE2 cell.");
484 /* Version 2 INTRODUCE2 cell. */
486 extend_info
= tor_malloc_zero(sizeof(extend_info_t
));
487 extend_info
->addr
= ntohl(get_uint32(buf
+1));
488 extend_info
->port
= ntohs(get_uint16(buf
+5));
489 memcpy(extend_info
->identity_digest
, buf
+7, DIGEST_LEN
);
490 extend_info
->nickname
[0] = '$';
491 base16_encode(extend_info
->nickname
+1, sizeof(extend_info
->nickname
)-1,
492 extend_info
->identity_digest
, DIGEST_LEN
);
494 klen
= ntohs(get_uint16(buf
+7+DIGEST_LEN
));
495 if ((int)len
!= 7+DIGEST_LEN
+2+klen
+20+128) {
496 log_warn(LD_PROTOCOL
, "Bad length %u for version 2 INTRODUCE2 cell.",
498 reason
= END_CIRC_REASON_TORPROTOCOL
;
501 extend_info
->onion_key
= crypto_pk_asn1_decode(buf
+7+DIGEST_LEN
+2, klen
);
502 if (!extend_info
->onion_key
) {
503 log_warn(LD_PROTOCOL
,
504 "Error decoding onion key in version 2 INTRODUCE2 cell.");
505 reason
= END_CIRC_REASON_TORPROTOCOL
;
508 ptr
= buf
+7+DIGEST_LEN
+2+klen
;
509 len
-= 7+DIGEST_LEN
+2+klen
;
512 size_t nickname_field_len
;
513 routerinfo_t
*router
;
517 nickname_field_len
= MAX_HEX_NICKNAME_LEN
+1;
520 nickname_field_len
= MAX_NICKNAME_LEN
+1;
524 ptr
=memchr(rp_nickname
,0,nickname_field_len
);
525 if (!ptr
|| ptr
== rp_nickname
) {
526 log_warn(LD_PROTOCOL
,
527 "Couldn't find a nul-padded nickname in INTRODUCE2 cell.");
530 if ((version
== 0 && !is_legal_nickname(rp_nickname
)) ||
531 (version
== 1 && !is_legal_nickname_or_hexdigest(rp_nickname
))) {
532 log_warn(LD_PROTOCOL
, "Bad nickname in INTRODUCE2 cell.");
535 /* Okay, now we know that a nickname is at the start of the buffer. */
536 ptr
= rp_nickname
+nickname_field_len
;
537 len
-= nickname_field_len
;
538 len
-= rp_nickname
- buf
; /* also remove header space used by version, if
540 router
= router_get_by_nickname(rp_nickname
, 0);
542 log_info(LD_REND
, "Couldn't find router %s named in rendezvous cell.",
543 escaped_safe_str(rp_nickname
));
544 /* XXXX Add a no-such-router reason? */
545 reason
= END_CIRC_REASON_TORPROTOCOL
;
549 extend_info
= extend_info_from_router(router
);
552 if (len
!= REND_COOKIE_LEN
+DH_KEY_LEN
) {
553 log_warn(LD_PROTOCOL
, "Bad length %u for INTRODUCE2 cell.", (int)len
);
554 reason
= END_CIRC_REASON_TORPROTOCOL
;
559 base16_encode(hexcookie
,9,r_cookie
,4);
561 /* Try DH handshake... */
562 dh
= crypto_dh_new();
563 if (!dh
|| crypto_dh_generate_public(dh
)<0) {
564 log_warn(LD_BUG
,"Internal error: couldn't build DH state "
565 "or generate public key.");
566 reason
= END_CIRC_REASON_INTERNAL
;
569 if (crypto_dh_compute_secret(dh
, ptr
+REND_COOKIE_LEN
, DH_KEY_LEN
, keys
,
570 DIGEST_LEN
+CPATH_KEY_MATERIAL_LEN
)<0) {
571 log_warn(LD_BUG
, "Internal error: couldn't complete DH handshake");
572 reason
= END_CIRC_REASON_INTERNAL
;
576 circ_needs_uptime
= rend_service_requires_uptime(service
);
578 /* help predict this next time */
579 rep_hist_note_used_internal(time(NULL
), circ_needs_uptime
, 1);
581 /* Launch a circuit to alice's chosen rendezvous point.
583 for (i
=0;i
<MAX_REND_FAILURES
;i
++) {
584 launched
= circuit_launch_by_extend_info(
585 CIRCUIT_PURPOSE_S_CONNECT_REND
, 0, extend_info
,
586 circ_needs_uptime
, 1, 1);
591 if (!launched
) { /* give up */
592 log_warn(LD_REND
, "Giving up launching first hop of circuit to rendezvous "
593 "point %s for service %s.",
594 escaped_safe_str(extend_info
->nickname
), serviceid
);
595 reason
= END_CIRC_REASON_CONNECTFAILED
;
599 "Accepted intro; launching circuit to %s "
600 "(cookie %s) for service %s.",
601 escaped_safe_str(extend_info
->nickname
), hexcookie
, serviceid
);
602 tor_assert(launched
->build_state
);
603 /* Fill in the circuit's state. */
604 memcpy(launched
->rend_pk_digest
, circuit
->rend_pk_digest
,
606 memcpy(launched
->rend_cookie
, r_cookie
, REND_COOKIE_LEN
);
607 strlcpy(launched
->rend_query
, service
->service_id
,
608 sizeof(launched
->rend_query
));
609 launched
->build_state
->pending_final_cpath
= cpath
=
610 tor_malloc_zero(sizeof(crypt_path_t
));
611 cpath
->magic
= CRYPT_PATH_MAGIC
;
612 launched
->build_state
->expiry_time
= time(NULL
) + MAX_REND_TIMEOUT
;
614 cpath
->dh_handshake_state
= dh
;
616 if (circuit_init_cpath_crypto(cpath
,keys
+DIGEST_LEN
,1)<0)
618 memcpy(cpath
->handshake_digest
, keys
, DIGEST_LEN
);
619 if (extend_info
) extend_info_free(extend_info
);
623 if (dh
) crypto_dh_free(dh
);
625 circuit_mark_for_close(TO_CIRCUIT(launched
), reason
);
626 if (extend_info
) extend_info_free(extend_info
);
630 /** Called when we fail building a rendezvous circuit at some point other
631 * than the last hop: launches a new circuit to the same rendezvous point.
634 rend_service_relaunch_rendezvous(origin_circuit_t
*oldcirc
)
636 origin_circuit_t
*newcirc
;
637 cpath_build_state_t
*newstate
, *oldstate
;
639 tor_assert(oldcirc
->_base
.purpose
== CIRCUIT_PURPOSE_S_CONNECT_REND
);
641 if (!oldcirc
->build_state
||
642 oldcirc
->build_state
->failure_count
> MAX_REND_FAILURES
||
643 oldcirc
->build_state
->expiry_time
< time(NULL
)) {
645 "Attempt to build circuit to %s for rendezvous has failed "
646 "too many times or expired; giving up.",
647 oldcirc
->build_state
?
648 oldcirc
->build_state
->chosen_exit
->nickname
: "*unknown*");
652 oldstate
= oldcirc
->build_state
;
653 tor_assert(oldstate
);
655 if (oldstate
->pending_final_cpath
== NULL
) {
656 log_info(LD_REND
,"Skipping relaunch of circ that failed on its first hop. "
657 "Initiator will retry.");
661 log_info(LD_REND
,"Reattempting rendezvous circuit to '%s'",
662 oldstate
->chosen_exit
->nickname
);
664 newcirc
= circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND
, 0,
665 oldstate
->chosen_exit
, 0, 1, 1);
667 log_warn(LD_REND
,"Couldn't relaunch rendezvous circuit to '%s'.",
668 oldstate
->chosen_exit
->nickname
);
671 newstate
= newcirc
->build_state
;
672 tor_assert(newstate
);
673 newstate
->failure_count
= oldstate
->failure_count
+1;
674 newstate
->expiry_time
= oldstate
->expiry_time
;
675 newstate
->pending_final_cpath
= oldstate
->pending_final_cpath
;
676 oldstate
->pending_final_cpath
= NULL
;
678 memcpy(newcirc
->rend_query
, oldcirc
->rend_query
, REND_SERVICE_ID_LEN
+1);
679 memcpy(newcirc
->rend_pk_digest
, oldcirc
->rend_pk_digest
,
681 memcpy(newcirc
->rend_cookie
, oldcirc
->rend_cookie
,
685 /** Launch a circuit to serve as an introduction point for the service
686 * <b>service</b> at the introduction point <b>nickname</b>
689 rend_service_launch_establish_intro(rend_service_t
*service
,
690 const char *nickname
)
692 origin_circuit_t
*launched
;
695 "Launching circuit to introduction point %s for service %s",
696 escaped_safe_str(nickname
), service
->service_id
);
698 rep_hist_note_used_internal(time(NULL
), 1, 0);
700 ++service
->n_intro_circuits_launched
;
701 launched
= circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
, 0,
705 "Can't launch circuit to establish introduction at %s.",
706 escaped_safe_str(nickname
));
709 strlcpy(launched
->rend_query
, service
->service_id
,
710 sizeof(launched
->rend_query
));
711 memcpy(launched
->rend_pk_digest
, service
->pk_digest
, DIGEST_LEN
);
713 if (launched
->_base
.state
== CIRCUIT_STATE_OPEN
)
714 rend_service_intro_has_opened(launched
);
718 /** Called when we're done building a circuit to an introduction point:
719 * sends a RELAY_ESTABLISH_INTRO cell.
722 rend_service_intro_has_opened(origin_circuit_t
*circuit
)
724 rend_service_t
*service
;
727 char buf
[RELAY_PAYLOAD_SIZE
];
728 char auth
[DIGEST_LEN
+ 9];
729 char serviceid
[REND_SERVICE_ID_LEN
+1];
730 int reason
= END_CIRC_REASON_TORPROTOCOL
;
732 tor_assert(circuit
->_base
.purpose
== CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
);
733 tor_assert(circuit
->cpath
);
735 base32_encode(serviceid
, REND_SERVICE_ID_LEN
+1,
736 circuit
->rend_pk_digest
,10);
738 service
= rend_service_get_by_pk_digest(circuit
->rend_pk_digest
);
740 log_warn(LD_REND
, "Unrecognized service ID %s on introduction circuit %d.",
741 serviceid
, circuit
->_base
.n_circ_id
);
742 reason
= END_CIRC_REASON_NOSUCHSERVICE
;
747 "Established circuit %d as introduction point for service %s",
748 circuit
->_base
.n_circ_id
, serviceid
);
750 /* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
751 len
= crypto_pk_asn1_encode(service
->private_key
, buf
+2,
752 RELAY_PAYLOAD_SIZE
-2);
753 set_uint16(buf
, htons((uint16_t)len
));
755 memcpy(auth
, circuit
->cpath
->prev
->handshake_digest
, DIGEST_LEN
);
756 memcpy(auth
+DIGEST_LEN
, "INTRODUCE", 9);
757 if (crypto_digest(buf
+len
, auth
, DIGEST_LEN
+9))
760 note_crypto_pk_op(REND_SERVER
);
761 r
= crypto_pk_private_sign_digest(service
->private_key
, buf
+len
, buf
, len
);
763 log_warn(LD_BUG
, "Internal error: couldn't sign introduction request.");
764 reason
= END_CIRC_REASON_INTERNAL
;
769 if (connection_edge_send_command(NULL
, TO_CIRCUIT(circuit
),
770 RELAY_COMMAND_ESTABLISH_INTRO
,
771 buf
, len
, circuit
->cpath
->prev
)<0) {
773 "Couldn't send introduction request for service %s on circuit %d",
774 serviceid
, circuit
->_base
.n_circ_id
);
775 reason
= END_CIRC_REASON_INTERNAL
;
781 circuit_mark_for_close(TO_CIRCUIT(circuit
), reason
);
784 /** Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a
785 * live introduction point, and note that the service descriptor is
788 rend_service_intro_established(origin_circuit_t
*circuit
, const char *request
,
791 rend_service_t
*service
;
795 if (circuit
->_base
.purpose
!= CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
) {
796 log_warn(LD_PROTOCOL
,
797 "received INTRO_ESTABLISHED cell on non-intro circuit.");
800 service
= rend_service_get_by_pk_digest(circuit
->rend_pk_digest
);
802 log_warn(LD_REND
, "Unknown service on introduction circuit %d.",
803 circuit
->_base
.n_circ_id
);
806 service
->desc_is_dirty
= time(NULL
);
807 circuit
->_base
.purpose
= CIRCUIT_PURPOSE_S_INTRO
;
811 circuit_mark_for_close(TO_CIRCUIT(circuit
), END_CIRC_REASON_TORPROTOCOL
);
815 /** Called once a circuit to a rendezvous point is established: sends a
816 * RELAY_COMMAND_RENDEZVOUS1 cell.
819 rend_service_rendezvous_has_opened(origin_circuit_t
*circuit
)
821 rend_service_t
*service
;
822 char buf
[RELAY_PAYLOAD_SIZE
];
824 char serviceid
[REND_SERVICE_ID_LEN
+1];
828 tor_assert(circuit
->_base
.purpose
== CIRCUIT_PURPOSE_S_CONNECT_REND
);
829 tor_assert(circuit
->cpath
);
830 tor_assert(circuit
->build_state
);
831 hop
= circuit
->build_state
->pending_final_cpath
;
834 base16_encode(hexcookie
,9,circuit
->rend_cookie
,4);
835 base32_encode(serviceid
, REND_SERVICE_ID_LEN
+1,
836 circuit
->rend_pk_digest
,10);
839 "Done building circuit %d to rendezvous with "
840 "cookie %s for service %s",
841 circuit
->_base
.n_circ_id
, hexcookie
, serviceid
);
843 service
= rend_service_get_by_pk_digest(circuit
->rend_pk_digest
);
845 log_warn(LD_GENERAL
, "Internal error: unrecognized service ID on "
846 "introduction circuit.");
847 reason
= END_CIRC_REASON_INTERNAL
;
851 /* All we need to do is send a RELAY_RENDEZVOUS1 cell... */
852 memcpy(buf
, circuit
->rend_cookie
, REND_COOKIE_LEN
);
853 if (crypto_dh_get_public(hop
->dh_handshake_state
,
854 buf
+REND_COOKIE_LEN
, DH_KEY_LEN
)<0) {
855 log_warn(LD_GENERAL
,"Couldn't get DH public key.");
856 reason
= END_CIRC_REASON_INTERNAL
;
859 memcpy(buf
+REND_COOKIE_LEN
+DH_KEY_LEN
, hop
->handshake_digest
,
863 if (connection_edge_send_command(NULL
, TO_CIRCUIT(circuit
),
864 RELAY_COMMAND_RENDEZVOUS1
,
865 buf
, REND_COOKIE_LEN
+DH_KEY_LEN
+DIGEST_LEN
,
866 circuit
->cpath
->prev
)<0) {
867 log_warn(LD_GENERAL
, "Couldn't send RENDEZVOUS1 cell.");
868 reason
= END_CIRC_REASON_INTERNAL
;
872 crypto_dh_free(hop
->dh_handshake_state
);
873 hop
->dh_handshake_state
= NULL
;
875 /* Append the cpath entry. */
876 hop
->state
= CPATH_STATE_OPEN
;
877 /* set the windows to default. these are the windows
878 * that bob thinks alice has.
880 hop
->package_window
= CIRCWINDOW_START
;
881 hop
->deliver_window
= CIRCWINDOW_START
;
883 onion_append_to_cpath(&circuit
->cpath
, hop
);
884 circuit
->build_state
->pending_final_cpath
= NULL
; /* prevent double-free */
886 /* Change the circuit purpose. */
887 circuit
->_base
.purpose
= CIRCUIT_PURPOSE_S_REND_JOINED
;
891 circuit_mark_for_close(TO_CIRCUIT(circuit
), reason
);
895 * Manage introduction points
898 /** Return the (possibly non-open) introduction circuit ending at
899 * <b>router</b> for the service whose public key is <b>pk_digest</b>. Return
900 * NULL if no such service is found.
902 static origin_circuit_t
*
903 find_intro_circuit(routerinfo_t
*router
, const char *pk_digest
)
905 origin_circuit_t
*circ
= NULL
;
908 while ((circ
= circuit_get_next_by_pk_and_purpose(circ
,pk_digest
,
909 CIRCUIT_PURPOSE_S_INTRO
))) {
910 if (!strcasecmp(circ
->build_state
->chosen_exit
->nickname
,
917 while ((circ
= circuit_get_next_by_pk_and_purpose(circ
,pk_digest
,
918 CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
))) {
919 if (!strcasecmp(circ
->build_state
->chosen_exit
->nickname
,
927 /** Encode and sign an up-to-date service descriptor for <b>service</b>,
928 * and upload it to all the dirservers.
931 upload_service_descriptor(rend_service_t
*service
, int version
)
936 /* Update the descriptor. */
937 rend_service_update_descriptor(service
);
938 if (rend_encode_service_descriptor(service
->desc
,
940 service
->private_key
,
941 &desc
, &desc_len
)<0) {
942 log_warn(LD_BUG
, "Internal error: couldn't encode service descriptor; "
947 /* Post it to the dirservers */
948 directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC
, desc
, desc_len
);
951 service
->desc_is_dirty
= 0;
954 /** For every service, check how many intro points it currently has, and:
955 * - Pick new intro points as necessary.
956 * - Launch circuits to any new intro points.
959 rend_services_introduce(void)
962 routerinfo_t
*router
;
963 rend_service_t
*service
;
965 int changed
, prev_intro_nodes
;
966 smartlist_t
*intro_routers
, *exclude_routers
;
969 intro_routers
= smartlist_create();
970 exclude_routers
= smartlist_create();
973 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
974 smartlist_clear(intro_routers
);
975 service
= smartlist_get(rend_service_list
, i
);
979 if (now
> service
->intro_period_started
+INTRO_CIRC_RETRY_PERIOD
) {
980 /* One period has elapsed; we can try building circuits again. */
981 service
->intro_period_started
= now
;
982 service
->n_intro_circuits_launched
= 0;
983 } else if (service
->n_intro_circuits_launched
>=
984 MAX_INTRO_CIRCS_PER_PERIOD
) {
985 /* We have failed too many times in this period; wait for the next
986 * one before we try again. */
990 /* Find out which introduction points we have in progress for this
992 for (j
=0; j
< smartlist_len(service
->intro_nodes
); ++j
) {
993 intro
= smartlist_get(service
->intro_nodes
, j
);
994 router
= router_get_by_nickname(intro
, 0);
995 if (!router
|| !find_intro_circuit(router
,service
->pk_digest
)) {
996 log_info(LD_REND
,"Giving up on %s as intro point for %s.",
997 intro
, service
->service_id
);
999 smartlist_del(service
->intro_nodes
,j
--);
1001 service
->desc_is_dirty
= now
;
1003 smartlist_add(intro_routers
, router
);
1006 /* We have enough intro points, and the intro points we thought we had were
1009 if (!changed
&& smartlist_len(service
->intro_nodes
) >= NUM_INTRO_POINTS
) {
1010 /* We have all our intro points! Start a fresh period and reset the
1012 service
->intro_period_started
= now
;
1013 service
->n_intro_circuits_launched
= 0;
1017 /* Remember how many introduction circuits we started with. */
1018 prev_intro_nodes
= smartlist_len(service
->intro_nodes
);
1020 smartlist_add_all(exclude_routers
, intro_routers
);
1021 /* The directory is now here. Pick three ORs as intro points. */
1022 for (j
=prev_intro_nodes
; j
< NUM_INTRO_POINTS
; ++j
) {
1024 router
= router_choose_random_node(service
->intro_prefer_nodes
,
1025 service
->intro_exclude_nodes
, exclude_routers
, 1, 0, 0,
1026 get_options()->_AllowInvalid
& ALLOW_INVALID_INTRODUCTION
,
1030 "Could only establish %d introduction points for %s.",
1031 smartlist_len(service
->intro_nodes
), service
->service_id
);
1035 hex_digest
= tor_malloc_zero(HEX_DIGEST_LEN
+2);
1036 hex_digest
[0] = '$';
1037 base16_encode(hex_digest
+1, HEX_DIGEST_LEN
+1,
1038 router
->cache_info
.identity_digest
,
1040 smartlist_add(intro_routers
, router
);
1041 smartlist_add(exclude_routers
, router
);
1042 smartlist_add(service
->intro_nodes
, hex_digest
);
1043 log_info(LD_REND
, "Picked router %s as an intro point for %s.",
1044 router
->nickname
, service
->service_id
);
1047 /* Reset exclude_routers, for the next time around the loop. */
1048 smartlist_clear(exclude_routers
);
1050 /* If there's no need to launch new circuits, stop here. */
1054 /* Establish new introduction points. */
1055 for (j
=prev_intro_nodes
; j
< smartlist_len(service
->intro_nodes
); ++j
) {
1056 intro
= smartlist_get(service
->intro_nodes
, j
);
1057 r
= rend_service_launch_establish_intro(service
, intro
);
1059 log_warn(LD_REND
, "Error launching circuit to node %s for service %s.",
1060 intro
, service
->service_id
);
1064 smartlist_free(intro_routers
);
1065 smartlist_free(exclude_routers
);
1068 /** Regenerate and upload rendezvous service descriptors for all
1069 * services, if necessary. If the descriptor has been dirty enough
1070 * for long enough, definitely upload; else only upload when the
1071 * periodic timeout has expired.
1073 * For the first upload, pick a random time between now and two periods
1074 * from now, and pick it independently for each service.
1077 rend_consider_services_upload(time_t now
)
1080 rend_service_t
*service
;
1081 int rendpostperiod
= get_options()->RendPostPeriod
;
1083 if (!get_options()->PublishHidServDescriptors
)
1086 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
1087 service
= smartlist_get(rend_service_list
, i
);
1088 if (!service
->next_upload_time
) { /* never been uploaded yet */
1089 service
->next_upload_time
=
1090 now
+ crypto_rand_int(2*rendpostperiod
);
1092 if (service
->next_upload_time
< now
||
1093 (service
->desc_is_dirty
&&
1094 service
->desc_is_dirty
< now
-30)) {
1095 /* if it's time, or if the directory servers have a wrong service
1096 * descriptor and ours has been stable for 30 seconds, upload a
1097 * new one of each format. */
1098 upload_service_descriptor(service
, 0);
1099 service
->next_upload_time
= now
+ rendpostperiod
;
1104 /** Log the status of introduction points for all rendezvous services
1105 * at log severity <b>severity</b>.
1108 rend_service_dump_stats(int severity
)
1111 routerinfo_t
*router
;
1112 rend_service_t
*service
;
1113 const char *nickname
, *safe_name
;
1114 char nn_buf
[MAX_VERBOSE_NICKNAME_LEN
];
1115 origin_circuit_t
*circ
;
1117 for (i
=0; i
< smartlist_len(rend_service_list
); ++i
) {
1118 service
= smartlist_get(rend_service_list
, i
);
1119 log(severity
, LD_GENERAL
, "Service configured in \"%s\":",
1120 service
->directory
);
1121 for (j
=0; j
< smartlist_len(service
->intro_nodes
); ++j
) {
1122 nickname
= smartlist_get(service
->intro_nodes
, j
);
1123 router
= router_get_by_nickname(nickname
,1);
1125 router_get_verbose_nickname(nn_buf
, router
);
1128 safe_name
= safe_str(nickname
);
1131 log(severity
, LD_GENERAL
,
1132 " Intro point %d at %s: unrecognized router", j
, safe_name
);
1135 circ
= find_intro_circuit(router
, service
->pk_digest
);
1137 log(severity
, LD_GENERAL
, " Intro point %d at %s: no circuit",
1141 log(severity
, LD_GENERAL
, " Intro point %d at %s: circuit is %s",
1142 j
, safe_name
, circuit_state_to_string(circ
->_base
.state
));
1147 /** Given <b>conn</b>, a rendezvous exit stream, look up the hidden service for
1148 * 'circ', and look up the port and address based on conn-\>port.
1149 * Assign the actual conn-\>addr and conn-\>port. Return -1 if failure,
1153 rend_service_set_connection_addr_port(edge_connection_t
*conn
,
1154 origin_circuit_t
*circ
)
1156 rend_service_t
*service
;
1158 rend_service_port_config_t
*p
;
1159 char serviceid
[REND_SERVICE_ID_LEN
+1];
1161 tor_assert(circ
->_base
.purpose
== CIRCUIT_PURPOSE_S_REND_JOINED
);
1162 log_debug(LD_REND
,"beginning to hunt for addr/port");
1163 base32_encode(serviceid
, REND_SERVICE_ID_LEN
+1,
1164 circ
->rend_pk_digest
,10);
1165 service
= rend_service_get_by_pk_digest(circ
->rend_pk_digest
);
1167 log_warn(LD_REND
, "Couldn't find any service associated with pk %s on "
1168 "rendezvous circuit %d; closing.",
1169 serviceid
, circ
->_base
.n_circ_id
);
1172 for (i
= 0; i
< smartlist_len(service
->ports
); ++i
) {
1173 p
= smartlist_get(service
->ports
, i
);
1174 if (conn
->_base
.port
== p
->virtual_port
) {
1175 conn
->_base
.addr
= p
->real_addr
;
1176 conn
->_base
.port
= p
->real_port
;
1180 log_info(LD_REND
, "No virtual port mapping exists for port %d on service %s",
1181 conn
->_base
.port
,serviceid
);