1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson. */
3 /* See LICENSE for licensing information */
5 const char dirserv_c_id
[] = "$Id$";
11 * \brief Directory server core implementation.
14 /** How far in the future do we allow a router to get? (seconds) */
15 #define ROUTER_ALLOW_SKEW (30*60)
16 /** How many seconds do we wait before regenerating the directory? */
17 #define DIR_REGEN_SLACK_TIME 10
19 /** Do we need to regenerate the directory when someone asks for it? */
20 static int the_directory_is_dirty
= 1;
21 static int runningrouters_is_dirty
= 1;
23 static void directory_remove_unrecognized(void);
24 static int dirserv_regenerate_directory(void);
25 /* Should be static; exposed for testing */
26 void add_fingerprint_to_dir(const char *nickname
, const char *fp
);
28 /************** Fingerprint handling code ************/
30 typedef struct fingerprint_entry_t
{
32 char *fingerprint
; /**< Stored as HEX_DIGEST_LEN characters, followed by a NUL */
33 } fingerprint_entry_t
;
35 /** List of nickname-\>identity fingerprint mappings for all the routers
36 * that we recognize. Used to prevent Sybil attacks. */
37 static smartlist_t
*fingerprint_list
= NULL
;
39 /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
40 * the global list of recognized identity key fingerprints.
42 void /* Should be static; exposed for testing */
43 add_fingerprint_to_dir(const char *nickname
, const char *fp
)
46 fingerprint_entry_t
*ent
;
47 if (!fingerprint_list
)
48 fingerprint_list
= smartlist_create();
50 for (i
= 0; i
< smartlist_len(fingerprint_list
); ++i
) {
51 ent
= smartlist_get(fingerprint_list
, i
);
52 if (!strcasecmp(ent
->nickname
,nickname
)) {
53 tor_free(ent
->fingerprint
);
54 ent
->fingerprint
= tor_strdup(fp
);
58 ent
= tor_malloc(sizeof(fingerprint_entry_t
));
59 ent
->nickname
= tor_strdup(nickname
);
60 ent
->fingerprint
= tor_strdup(fp
);
61 tor_strstrip(ent
->fingerprint
, " ");
62 smartlist_add(fingerprint_list
, ent
);
65 /** Add the nickname and fingerprint for this OR to the recognized list.
68 dirserv_add_own_fingerprint(const char *nickname
, crypto_pk_env_t
*pk
)
70 char fp
[FINGERPRINT_LEN
+1];
71 if (crypto_pk_get_fingerprint(pk
, fp
, 0)<0) {
72 log_fn(LOG_ERR
, "Error computing fingerprint");
75 add_fingerprint_to_dir(nickname
, fp
);
79 /** Parse the nickname-\>fingerprint mappings stored in the file named
80 * <b>fname</b>. The file format is line-based, with each non-blank
81 * holding one nickname, some space, and a fingerprint for that
82 * nickname. On success, replace the current fingerprint list with
83 * the contents of <b>fname</b> and return 0. On failure, leave the
84 * current fingerprint list untouched, and return -1. */
86 dirserv_parse_fingerprint_file(const char *fname
)
89 char *nickname
, *fingerprint
;
90 smartlist_t
*fingerprint_list_new
;
92 fingerprint_entry_t
*ent
;
93 struct config_line_t
*front
=NULL
, *list
;
95 cf
= read_file_to_str(fname
, 0);
97 log_fn(LOG_WARN
, "Cannot open fingerprint file %s", fname
);
100 result
= config_get_lines(cf
, &front
);
103 log_fn(LOG_WARN
, "Error reading from fingerprint file");
107 fingerprint_list_new
= smartlist_create();
109 for (list
=front
; list
; list
=list
->next
) {
110 nickname
= list
->key
; fingerprint
= list
->value
;
111 if (strlen(nickname
) > MAX_NICKNAME_LEN
) {
112 log(LOG_NOTICE
, "Nickname '%s' too long in fingerprint file. Skipping.", nickname
);
115 if (strlen(fingerprint
) != FINGERPRINT_LEN
||
116 !crypto_pk_check_fingerprint_syntax(fingerprint
)) {
117 log_fn(LOG_NOTICE
, "Invalid fingerprint (nickname '%s', fingerprint %s). Skipping.",
118 nickname
, fingerprint
);
121 if (0==strcasecmp(nickname
, DEFAULT_CLIENT_NICKNAME
)) {
122 /* If you approved an OR called "client", then clients who use
123 * the default nickname could all be rejected. That's no good. */
125 "Authorizing a nickname '%s' would break many clients; skipping.",
126 DEFAULT_CLIENT_NICKNAME
);
129 for (i
= 0; i
< smartlist_len(fingerprint_list_new
); ++i
) {
130 ent
= smartlist_get(fingerprint_list_new
, i
);
131 if (0==strcasecmp(ent
->nickname
, nickname
)) {
132 log(LOG_NOTICE
, "Duplicate nickname '%s'. Skipping.",nickname
);
133 break; /* out of the for. the 'if' below means skip to the next line. */
136 if (i
== smartlist_len(fingerprint_list_new
)) { /* not a duplicate */
137 ent
= tor_malloc(sizeof(fingerprint_entry_t
));
138 ent
->nickname
= tor_strdup(nickname
);
139 ent
->fingerprint
= tor_strdup(fingerprint
);
140 tor_strstrip(ent
->fingerprint
, " ");
141 smartlist_add(fingerprint_list_new
, ent
);
145 config_free_lines(front
);
146 dirserv_free_fingerprint_list();
147 fingerprint_list
= fingerprint_list_new
;
148 /* Delete any routers whose fingerprints we no longer recognize */
149 directory_remove_unrecognized();
153 /** Check whether <b>router</b> has a nickname/identity key combination that
154 * we recognize from the fingerprint list. Return 1 if router's
155 * identity and nickname match, -1 if we recognize the nickname but
156 * the identity key is wrong, and 0 if the nickname is not known. */
158 dirserv_router_fingerprint_is_known(const routerinfo_t
*router
)
161 fingerprint_entry_t
*ent
=NULL
;
162 char fp
[FINGERPRINT_LEN
+1];
164 if (!fingerprint_list
)
165 fingerprint_list
= smartlist_create();
167 log_fn(LOG_DEBUG
, "%d fingerprints known.", smartlist_len(fingerprint_list
));
168 for (i
=0;i
<smartlist_len(fingerprint_list
);++i
) {
169 ent
= smartlist_get(fingerprint_list
, i
);
170 log_fn(LOG_DEBUG
,"%s vs %s", router
->nickname
, ent
->nickname
);
171 if (!strcasecmp(router
->nickname
,ent
->nickname
)) {
177 if (!found
) { /* No such server known */
178 log_fn(LOG_INFO
,"no fingerprint found for '%s'",router
->nickname
);
181 if (crypto_pk_get_fingerprint(router
->identity_pkey
, fp
, 0)) {
182 log_fn(LOG_WARN
,"error computing fingerprint");
185 if (0==strcasecmp(ent
->fingerprint
, fp
)) {
186 log_fn(LOG_DEBUG
,"good fingerprint for '%s'",router
->nickname
);
187 return 1; /* Right fingerprint. */
189 log_fn(LOG_WARN
,"mismatched fingerprint for '%s'",router
->nickname
);
190 return -1; /* Wrong fingerprint. */
194 /** If we are an authoritative dirserver, and the list of approved
195 * servers contains one whose identity key digest is <b>digest</b>,
196 * return that router's nickname. Otherwise return NULL. */
197 const char *dirserv_get_nickname_by_digest(const char *digest
)
199 char hexdigest
[HEX_DIGEST_LEN
+1];
200 if (!fingerprint_list
)
204 base16_encode(hexdigest
, HEX_DIGEST_LEN
+1, digest
, DIGEST_LEN
);
205 SMARTLIST_FOREACH(fingerprint_list
, fingerprint_entry_t
*, ent
,
206 { if (!strcasecmp(hexdigest
, ent
->fingerprint
))
207 return ent
->nickname
; } );
212 /** Return true iff any router named <b>nickname</b> with <b>digest</b>
213 * is in the verified fingerprint list. */
215 router_nickname_is_approved(const char *nickname
, const char *digest
)
219 n
= dirserv_get_nickname_by_digest(digest
);
220 if (n
&& !strcasecmp(n
,nickname
))
227 /** Clear the current fingerprint list. */
229 dirserv_free_fingerprint_list()
232 fingerprint_entry_t
*ent
;
233 if (!fingerprint_list
)
236 for (i
= 0; i
< smartlist_len(fingerprint_list
); ++i
) {
237 ent
= smartlist_get(fingerprint_list
, i
);
238 tor_free(ent
->nickname
);
239 tor_free(ent
->fingerprint
);
242 smartlist_free(fingerprint_list
);
243 fingerprint_list
= NULL
;
250 /** List of routerinfo_t for all server descriptors that this dirserv
252 * XXXX This should eventually get coalesced into routerlist.c
254 static smartlist_t
*descriptor_list
= NULL
;
256 /** Release all storage that the dirserv is holding for server
259 dirserv_free_descriptors()
261 if (!descriptor_list
)
263 SMARTLIST_FOREACH(descriptor_list
, routerinfo_t
*, ri
,
264 routerinfo_free(ri
));
265 smartlist_clear(descriptor_list
);
268 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
269 * unless we're configured to not care. Return 0 if all ok. */
271 dirserv_router_has_valid_address(routerinfo_t
*ri
)
273 struct in_addr iaddr
;
274 if (get_options()->DirAllowPrivateAddresses
)
275 return 0; /* whatever it is, we're fine with it */
276 if (!tor_inet_aton(ri
->address
, &iaddr
)) {
277 log_fn(LOG_INFO
,"Router '%s' published non-IP address '%s'. Refusing.",
278 ri
->nickname
, ri
->address
);
281 if (is_internal_IP(ntohl(iaddr
.s_addr
))) {
282 log_fn(LOG_INFO
,"Router '%s' published internal IP address '%s'. Refusing.",
283 ri
->nickname
, ri
->address
);
284 return -1; /* it's a private IP, we should reject it */
289 /** Parse the server descriptor at *desc and maybe insert it into the
290 * list of server descriptors, and (if the descriptor is well-formed)
291 * advance *desc immediately past the descriptor's end. Set msg to a
292 * message that should be passed back to the origin of this descriptor, or
295 * Return 1 if descriptor is well-formed and accepted;
296 * 0 if well-formed and server is unapproved but accepted;
297 * -1 if well-formed but rejected;
298 * -2 if not well-formed.
301 dirserv_add_descriptor(const char **desc
, const char **msg
)
303 routerinfo_t
*ri
= NULL
, *ri_old
=NULL
;
306 char *desc_tmp
= NULL
;
309 int verified
=1; /* whether we knew its fingerprint already */
312 if (!descriptor_list
)
313 descriptor_list
= smartlist_create();
315 start
= strstr(*desc
, "router ");
317 log_fn(LOG_WARN
, "no 'router' line found. This is not a descriptor.");
320 if ((end
= strstr(start
+6, "\nrouter "))) {
321 ++end
; /* Include NL. */
322 } else if ((end
= strstr(start
+6, "\ndirectory-signature"))) {
325 end
= start
+strlen(start
);
327 desc_len
= end
-start
;
328 desc_tmp
= tor_strndup(start
, desc_len
); /* Is this strndup still needed???*/
330 /* Check: is the descriptor syntactically valid? */
331 ri
= router_parse_entry_from_string(desc_tmp
, NULL
);
334 log(LOG_WARN
, "Couldn't parse descriptor");
335 *msg
= "Rejected: Couldn't parse server descriptor.";
338 /* Okay. Now check whether the fingerprint is recognized. */
339 r
= dirserv_router_fingerprint_is_known(ri
);
341 log_fn(LOG_WARN
, "Known nickname '%s', wrong fingerprint. Not adding.", ri
->nickname
);
342 *msg
= "Rejected: There is already a verified server with this nickname and a different fingerprint.";
347 char fp
[FINGERPRINT_LEN
+1];
348 log_fn(LOG_INFO
, "Unknown nickname '%s' (%s:%d). Will try to add.",
349 ri
->nickname
, ri
->address
, ri
->or_port
);
350 if (crypto_pk_get_fingerprint(ri
->identity_pkey
, fp
, 1) < 0) {
351 log_fn(LOG_WARN
, "Error computing fingerprint for '%s'", ri
->nickname
);
353 log_fn(LOG_INFO
, "Fingerprint line: %s %s", ri
->nickname
, fp
);
357 /* Is there too much clock skew? */
359 if (ri
->published_on
> now
+ROUTER_ALLOW_SKEW
) {
360 log_fn(LOG_NOTICE
, "Publication time for nickname '%s' is too far in the future; possible clock skew. Not adding.", ri
->nickname
);
361 *msg
= "Rejected: Your clock is set too far in the future, or your timezone is not correct.";
366 if (ri
->published_on
< now
-ROUTER_MAX_AGE
) {
367 log_fn(LOG_NOTICE
, "Publication time for router with nickname '%s' is too far in the past. Not adding.", ri
->nickname
);
368 *msg
= "Rejected: Server is expired, or your clock is too far in the past, or your timezone is not correct.";
373 if (dirserv_router_has_valid_address(ri
) < 0) {
374 log_fn(LOG_NOTICE
, "Router with nickname '%s' has invalid address '%s'. Not adding.", ri
->nickname
, ri
->address
);
375 *msg
= "Rejected: Address is not an IP, or IP is a private address.";
381 /* Do we already have an entry for this router? */
382 for (i
= 0; i
< smartlist_len(descriptor_list
); ++i
) {
383 ri_old
= smartlist_get(descriptor_list
, i
);
384 if (!memcmp(ri
->identity_digest
, ri_old
->identity_digest
, DIGEST_LEN
)) {
390 char hex_digest
[HEX_DIGEST_LEN
+1];
391 base16_encode(hex_digest
, HEX_DIGEST_LEN
+1, ri
->identity_digest
,DIGEST_LEN
);
392 /* if so, decide whether to update it. */
393 if (ri_old
->published_on
>= ri
->published_on
) {
394 /* We already have a newer or equal-time descriptor */
395 log_fn(LOG_INFO
,"We already have a new enough desc for server %s (nickname '%s'). Not adding.",hex_digest
,ri
->nickname
);
396 *msg
= "We already have a newer descriptor.";
397 /* This isn't really an error; return success. */
402 /* We don't alrady have a newer one; we'll update this one. */
403 log_fn(LOG_INFO
,"Dirserv updating desc for server %s (nickname '%s')",hex_digest
,ri
->nickname
);
404 *msg
= verified
?"Verified server updated":"Unverified server updated. (Have you sent us your key fingerprint?)";
405 routerinfo_free(ri_old
);
406 smartlist_del_keeporder(descriptor_list
, found
);
408 /* Add at the end. */
409 log_fn(LOG_INFO
,"Dirserv adding desc for nickname '%s'",ri
->nickname
);
410 *msg
= verified
?"Verified server added":"Unverified server added. (Have you sent us your key fingerprint?)";
413 ri
->is_verified
= verified
||
414 tor_version_as_new_as(ri
->platform
,"0.1.0.2-rc");
415 smartlist_add(descriptor_list
, ri
);
418 directory_set_dirty();
423 /** Remove all descriptors whose nicknames or fingerprints we don't
424 * recognize. (Descriptors that used to be good can become
425 * unrecognized when we reload the fingerprint list.)
428 directory_remove_unrecognized(void)
433 if (!descriptor_list
)
434 descriptor_list
= smartlist_create();
436 for (i
= 0; i
< smartlist_len(descriptor_list
); ++i
) {
437 ent
= smartlist_get(descriptor_list
, i
);
438 r
= dirserv_router_fingerprint_is_known(ent
);
440 log(LOG_INFO
, "Router '%s' is now verified with a key; removing old router with same name and different key.",
442 routerinfo_free(ent
);
443 smartlist_del(descriptor_list
, i
--);
444 } else if (r
>0 && !ent
->is_verified
) {
445 log(LOG_INFO
, "Router '%s' is now approved.", ent
->nickname
);
446 ent
->is_verified
= 1;
447 } else if (r
==0 && ent
->is_verified
) {
448 log(LOG_INFO
, "Router '%s' is no longer approved.", ent
->nickname
);
449 ent
->is_verified
= 0;
454 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
455 * directory, we will rebuild it instead of reusing the most recently
459 directory_set_dirty()
461 time_t now
= time(NULL
);
463 if (!the_directory_is_dirty
)
464 the_directory_is_dirty
= now
;
465 if (!runningrouters_is_dirty
)
466 runningrouters_is_dirty
= now
;
469 /** Load all descriptors from a directory stored in the string
473 dirserv_load_from_directory_string(const char *dir
)
475 const char *cp
= dir
, *m
;
477 cp
= strstr(cp
, "\nrouter ");
480 if (dirserv_add_descriptor(&cp
,&m
) < -1) {
481 /* only fail if parsing failed; keep going if simply rejected */
484 --cp
; /*Back up to newline.*/
490 * Allocate and return a description of the status of the server <b>desc</b>,
491 * for use in a running-routers line (if <b>rr_format</b> is true), or in a
492 * router-status line (if <b>rr_format</b> is false. The server is listed
493 * as running iff <b>is_live</b> is true.
496 list_single_server_status(routerinfo_t
*desc
, int is_live
,
499 char buf
[MAX_NICKNAME_LEN
+HEX_DIGEST_LEN
+4]; /* !nickname=$hexdigest\0 */
508 if (desc
->is_verified
) {
509 strlcpy(cp
, desc
->nickname
, sizeof(buf
)-(cp
-buf
));
514 if (!desc
->is_verified
|| !rr_format
) {
516 base16_encode(cp
, HEX_DIGEST_LEN
+1, desc
->identity_digest
,
519 return tor_strdup(buf
);
522 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
523 * contents of a running-routers line and a router-status line, and
524 * store them in *<b>running_routers_out</b> and
525 * *<b>router_status_out</b> respectively. If either is NULL, skip
526 * it. Return 0 on success, -1 on failure.
529 list_server_status(smartlist_t
*routers
, char **running_routers_out
, char **router_status_out
)
531 /* List of entries in running-routers style: An optional !, then either
532 * a nickname or a dollar-prefixed hexdigest. */
533 smartlist_t
*rr_entries
;
534 /* List of entries in a router-status style: An optional !, then an optional
535 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
536 smartlist_t
*rs_entries
;
537 /* XXXX Really, we should merge descriptor_list into routerlist. But
538 * this is potentially tricky, since the semantics of the two lists
539 * are not quite the same. In any case, it's not for the 0.1.0.x
542 int authdir_mode
= get_options()->AuthoritativeDir
;
543 tor_assert(running_routers_out
|| router_status_out
);
545 rr_entries
= smartlist_create();
546 rs_entries
= smartlist_create();
548 SMARTLIST_FOREACH(routers
, routerinfo_t
*, ri
,
552 conn
= connection_get_by_identity_digest(
553 ri
->identity_digest
, CONN_TYPE_OR
);
555 /* Treat a router as alive if
556 * - It's me, and I'm not hibernating.
557 * or - we're connected to it. */
558 is_live
= (router_is_me(ri
) && !we_are_hibernating()) ||
559 (conn
&& conn
->state
== OR_CONN_STATE_OPEN
);
561 is_live
= ri
->is_running
;
563 smartlist_add(rr_entries
, list_single_server_status(ri
, is_live
, 1));
564 smartlist_add(rs_entries
, list_single_server_status(ri
, is_live
, 0));
567 if (running_routers_out
)
568 *running_routers_out
= smartlist_join_strings(rr_entries
, " ", 0,NULL
);
569 if (router_status_out
)
570 *router_status_out
= smartlist_join_strings(rs_entries
, " ", 0,NULL
);
572 SMARTLIST_FOREACH(rr_entries
, char *, cp
, tor_free(cp
));
573 SMARTLIST_FOREACH(rs_entries
, char *, cp
, tor_free(cp
));
574 smartlist_free(rr_entries
);
575 smartlist_free(rs_entries
);
580 /** Remove any descriptors from the directory that are more than <b>age</b>
584 dirserv_remove_old_servers(int age
)
589 if (!descriptor_list
)
590 descriptor_list
= smartlist_create();
592 cutoff
= time(NULL
) - age
;
593 for (i
= 0; i
< smartlist_len(descriptor_list
); ++i
) {
594 ent
= smartlist_get(descriptor_list
, i
);
595 if (ent
->published_on
<= cutoff
) {
596 /* descriptor_list[i] is too old. Remove it. */
597 routerinfo_free(ent
);
598 smartlist_del(descriptor_list
, i
--);
599 directory_set_dirty();
604 /** Generate a new directory and write it into a newly allocated string.
605 * Point *<b>dir_out</b> to the allocated string. Sign the
606 * directory with <b>private_key</b>. Return 0 on success, -1 on
610 dirserv_dump_directory_to_string(char **dir_out
,
611 crypto_pk_env_t
*private_key
)
614 char *running_routers
, *router_status
;
615 char *identity_pkey
; /* Identity key, DER64-encoded. */
616 char *recommended_versions
;
628 if (!descriptor_list
)
629 descriptor_list
= smartlist_create();
631 if (list_server_status(descriptor_list
, &running_routers
, &router_status
))
634 /* ASN.1-encode the public key. This is a temporary measure; once
635 * everyone is running 0.0.9pre3 or later, we can shift to using a
636 * PEM-encoded key instead.
639 if (crypto_pk_DER64_encode_public_key(private_key
, &identity_pkey
)<0) {
640 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
646 if (crypto_pk_write_public_key_to_string(private_key
,&identity_pkey
,&l
)<0) {
647 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
654 smartlist_t
*versions
;
655 struct config_line_t
*ln
;
656 versions
= smartlist_create();
657 for (ln
= get_options()->RecommendedVersions
; ln
; ln
= ln
->next
) {
658 smartlist_split_string(versions
, ln
->value
, ",",
659 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
661 recommended_versions
= smartlist_join_strings(versions
,",",0,NULL
);
662 SMARTLIST_FOREACH(versions
,char *,s
,tor_free(s
));
663 smartlist_free(versions
);
666 dirserv_remove_old_servers(ROUTER_MAX_AGE
);
667 published_on
= time(NULL
);
668 format_iso_time(published
, published_on
);
670 buf_len
= 2048+strlen(recommended_versions
)+strlen(running_routers
)+
671 strlen(router_status
);
672 SMARTLIST_FOREACH(descriptor_list
, routerinfo_t
*, ri
,
673 buf_len
+= strlen(ri
->signed_descriptor
));
674 buf
= tor_malloc(buf_len
);
675 /* We'll be comparing against buf_len throughout the rest of the
676 function, though strictly speaking we shouldn't be able to exceed
677 it. This is C, after all, so we may as well check for buffer
680 tor_snprintf(buf
, buf_len
,
683 "recommended-software %s\n"
684 "running-routers %s\n"
685 "opt router-status %s\n"
686 "opt dir-signing-key %s\n\n",
687 published
, recommended_versions
, running_routers
, router_status
,
690 tor_free(recommended_versions
);
691 tor_free(running_routers
);
692 tor_free(router_status
);
693 tor_free(identity_pkey
);
697 SMARTLIST_FOREACH(descriptor_list
, routerinfo_t
*, ri
,
698 if (strlcat(buf
, ri
->signed_descriptor
, buf_len
) >= buf_len
)
701 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
704 if (strlcat(buf
, "directory-signature ", buf_len
) >= buf_len
)
706 if (strlcat(buf
, get_options()->Nickname
, buf_len
) >= buf_len
)
708 if (strlcat(buf
, "\n", buf_len
) >= buf_len
)
711 if (router_get_dir_hash(buf
,digest
)) {
712 log_fn(LOG_WARN
,"couldn't compute digest");
716 if (crypto_pk_private_sign(private_key
, signature
, digest
, 20) < 0) {
717 log_fn(LOG_WARN
,"couldn't sign digest");
721 log(LOG_DEBUG
,"generated directory digest begins with %s",hex_str(digest
,4));
723 if (strlcat(cp
, "-----BEGIN SIGNATURE-----\n", buf_len
) >= buf_len
)
728 if (base64_encode(cp
, buf_len
-i
, signature
, 128) < 0) {
729 log_fn(LOG_WARN
,"couldn't base64-encode signature");
734 if (strlcat(buf
, "-----END SIGNATURE-----\n", buf_len
) >= buf_len
)
740 log_fn(LOG_WARN
,"tried to exceed string length.");
745 /** Most recently generated encoded signed directory. */
746 static char *the_directory
= NULL
;
747 static size_t the_directory_len
= 0;
748 static char *the_directory_z
= NULL
;
749 static size_t the_directory_z_len
= 0;
751 typedef struct cached_dir_t
{
759 /* used only by non-auth dirservers */
760 static cached_dir_t cached_directory
= { NULL
, NULL
, 0, 0, 0 };
761 static cached_dir_t cached_runningrouters
= { NULL
, NULL
, 0, 0, 0 };
763 /** If we have no cached directory, or it is older than <b>when</b>, then
764 * replace it with <b>directory</b>, published at <b>when</b>.
766 void dirserv_set_cached_directory(const char *directory
, time_t when
,
767 int is_running_routers
)
772 d
= is_running_routers
? &cached_runningrouters
: &cached_directory
;
773 if (when
<=d
->published
) {
774 log_fn(LOG_INFO
, "Ignoring old directory; not caching.");
775 } else if (when
>=now
+ROUTER_MAX_AGE
) {
776 log_fn(LOG_INFO
, "Ignoring future directory; not caching.");
778 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
779 log_fn(LOG_DEBUG
, "Caching directory.");
781 d
->dir
= tor_strdup(directory
);
782 d
->dir_len
= strlen(directory
);
784 if (tor_gzip_compress(&(d
->dir_z
), &(d
->dir_z_len
), d
->dir
, d
->dir_len
,
786 log_fn(LOG_WARN
,"Error compressing cached directory");
789 if (!is_running_routers
) {
791 tor_snprintf(filename
,sizeof(filename
),"%s/cached-directory", get_options()->DataDirectory
);
792 if (write_str_to_file(filename
,cached_directory
.dir
,0) < 0) {
793 log_fn(LOG_NOTICE
, "Couldn't write cached directory to disk. Ignoring.");
799 /** Set *<b>directory</b> to the most recently generated encoded signed
800 * directory, generating a new one as necessary. If not an authoritative
801 * directory may return 0 if no directory is yet cached.*/
802 size_t dirserv_get_directory(const char **directory
, int compress
)
804 if (!get_options()->AuthoritativeDir
) {
805 cached_dir_t
*d
= &cached_directory
;
806 *directory
= compress
? d
->dir_z
: d
->dir
;
808 return compress
? d
->dir_z_len
: d
->dir_len
;
810 /* no directory yet retrieved */
814 if (the_directory_is_dirty
&&
815 the_directory_is_dirty
+ DIR_REGEN_SLACK_TIME
< time(NULL
)) {
816 if (dirserv_regenerate_directory())
819 log(LOG_INFO
,"Directory still clean, reusing.");
821 *directory
= compress
? the_directory_z
: the_directory
;
822 return compress
? the_directory_z_len
: the_directory_len
;
826 * Generate a fresh directory (authdirservers only.)
828 static int dirserv_regenerate_directory(void)
830 char *new_directory
=NULL
;
832 if (dirserv_dump_directory_to_string(&new_directory
,
833 get_identity_key())) {
834 log(LOG_WARN
, "Error creating directory.");
835 tor_free(new_directory
);
838 tor_free(the_directory
);
839 the_directory
= new_directory
;
840 the_directory_len
= strlen(the_directory
);
841 log_fn(LOG_INFO
,"New directory (size %d):\n%s",(int)the_directory_len
,
843 tor_free(the_directory_z
);
844 if (tor_gzip_compress(&the_directory_z
, &the_directory_z_len
,
845 the_directory
, the_directory_len
,
847 log_fn(LOG_WARN
, "Error gzipping directory.");
851 /* Now read the directory we just made in order to update our own
852 * router lists. This does more signature checking than is strictly
853 * necessary, but safe is better than sorry. */
854 new_directory
= tor_strdup(the_directory
);
855 /* use a new copy of the dir, since get_dir_from_string scribbles on it */
856 if (router_load_routerlist_from_directory(new_directory
,
857 get_identity_key(), 1, 0)) {
858 log_fn(LOG_ERR
, "We just generated a directory we can't parse. Dying.");
862 tor_free(new_directory
);
863 the_directory_is_dirty
= 0;
865 /* Save the directory to disk so we re-load it quickly on startup.
867 dirserv_set_cached_directory(the_directory
, time(NULL
), 0);
872 static char *the_runningrouters
=NULL
;
873 static size_t the_runningrouters_len
=0;
874 static char *the_runningrouters_z
=NULL
;
875 static size_t the_runningrouters_z_len
=0;
877 /** Replace the current running-routers list with a newly generated one. */
878 static int generate_runningrouters(crypto_pk_env_t
*private_key
)
881 char *router_status
=NULL
;
882 char digest
[DIGEST_LEN
];
883 char signature
[PK_BYTES
];
888 char *identity_pkey
; /* Identity key, DER64-encoded. */
890 if (!descriptor_list
)
891 descriptor_list
= smartlist_create();
893 if (list_server_status(descriptor_list
, NULL
, &router_status
)) {
896 /* ASN.1-encode the public key. This is a temporary measure; once
897 * everyone is running 0.0.9pre3 or later, we can shift to using a
898 * PEM-encoded key instead.
901 if (crypto_pk_DER64_encode_public_key(private_key
, &identity_pkey
)<0) {
902 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
908 if (crypto_pk_write_public_key_to_string(private_key
,&identity_pkey
,&l
)<0) {
909 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
914 published_on
= time(NULL
);
915 format_iso_time(published
, published_on
);
917 len
= 2048+strlen(router_status
);
918 s
= tor_malloc_zero(len
);
919 tor_snprintf(s
, len
, "network-status\n"
922 "opt dir-signing-key %s\n"
923 "directory-signature %s\n"
924 "-----BEGIN SIGNATURE-----\n",
925 published
, router_status
, identity_pkey
, get_options()->Nickname
);
926 tor_free(router_status
);
927 tor_free(identity_pkey
);
928 if (router_get_runningrouters_hash(s
,digest
)) {
929 log_fn(LOG_WARN
,"couldn't compute digest");
932 if (crypto_pk_private_sign(private_key
, signature
, digest
, 20) < 0) {
933 log_fn(LOG_WARN
,"couldn't sign digest");
939 if (base64_encode(cp
, len
-i
, signature
, 128) < 0) {
940 log_fn(LOG_WARN
,"couldn't base64-encode signature");
943 if (strlcat(s
, "-----END SIGNATURE-----\n", len
) >= len
) {
947 tor_free(the_runningrouters
);
948 the_runningrouters
= s
;
949 the_runningrouters_len
= strlen(s
);
950 tor_free(the_runningrouters_z
);
951 if (tor_gzip_compress(&the_runningrouters_z
, &the_runningrouters_z_len
,
952 the_runningrouters
, the_runningrouters_len
,
954 log_fn(LOG_WARN
, "Error gzipping runningrouters");
957 runningrouters_is_dirty
= 0;
959 /* We don't cache running-routers to disk, so there's no point in
960 * authdirservers caching it. */
961 /* dirserv_set_cached_directory(the_runningrouters, time(NULL), 1); */
966 tor_free(router_status
);
970 /** Set *<b>rr</b> to the most recently generated encoded signed
971 * running-routers list, generating a new one as necessary. Return the
972 * size of the directory on success, and 0 on failure. */
973 size_t dirserv_get_runningrouters(const char **rr
, int compress
)
975 if (!get_options()->AuthoritativeDir
) {
976 cached_dir_t
*d
= &cached_runningrouters
;
977 *rr
= compress
? d
->dir_z
: d
->dir
;
979 return compress
? d
->dir_z_len
: d
->dir_len
;
981 /* no directory yet retrieved */
985 if (runningrouters_is_dirty
&&
986 runningrouters_is_dirty
+ DIR_REGEN_SLACK_TIME
< time(NULL
)) {
987 if (generate_runningrouters(get_identity_key())) {
988 log_fn(LOG_ERR
, "Couldn't generate running-routers list?");
992 *rr
= compress
? the_runningrouters_z
: the_runningrouters
;
993 return compress
? the_runningrouters_z_len
: the_runningrouters_len
;
996 /** Called when a TLS handshake has completed successfully with a
997 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
998 * a certificate with digest <b>digest_rcvd</b> and nickname
999 * <b>nickname_rcvd</b>. When this happens, it's clear that any other
1000 * descriptors for that address/port combination must be unusable:
1001 * delete them if they are not verified.
1004 dirserv_orconn_tls_done(const char *address
,
1006 const char *digest_rcvd
,
1007 const char *nickname_rcvd
)
1010 tor_assert(address
);
1011 tor_assert(digest_rcvd
);
1012 tor_assert(nickname_rcvd
);
1014 if (!descriptor_list
)
1017 for (i
= 0; i
< smartlist_len(descriptor_list
); ++i
) {
1018 routerinfo_t
*ri
= smartlist_get(descriptor_list
, i
);
1020 if (ri
->is_verified
)
1022 if (!strcasecmp(address
, ri
->address
) &&
1023 or_port
== ri
->or_port
) {
1024 /* We have a router at the same address! */
1025 if (strcasecmp(ri
->nickname
, nickname_rcvd
)) {
1026 log_fn(LOG_WARN
, "Dropping descriptor: nickname '%s' does not match nickname '%s' in cert from %s:%d",
1027 ri
->nickname
, nickname_rcvd
, address
, or_port
);
1029 } else if (memcmp(ri
->identity_digest
, digest_rcvd
, DIGEST_LEN
)) {
1030 log_fn(LOG_WARN
, "Dropping descriptor: identity key does not match key in cert from %s:%d",
1035 routerinfo_free(ri
);
1036 smartlist_del(descriptor_list
, i
--);
1037 directory_set_dirty();
1044 dirserv_free_all(void)
1046 if (fingerprint_list
) {
1047 SMARTLIST_FOREACH(fingerprint_list
, fingerprint_entry_t
*, fp
,
1048 { tor_free(fp
->nickname
);
1049 tor_free(fp
->fingerprint
);
1051 smartlist_free(fingerprint_list
);
1052 fingerprint_list
= NULL
;
1054 if (descriptor_list
) {
1055 SMARTLIST_FOREACH(descriptor_list
, routerinfo_t
*, ri
,
1056 routerinfo_free(ri
));
1057 smartlist_free(descriptor_list
);
1058 descriptor_list
= NULL
;
1060 tor_free(the_directory
);
1061 tor_free(the_directory_z
);
1062 the_directory_len
= 0;
1063 the_directory_z_len
= 0;
1064 tor_free(the_runningrouters
);
1065 tor_free(the_runningrouters_z
);
1066 the_runningrouters_len
= 0;
1067 the_runningrouters_z_len
= 0;
1068 tor_free(cached_directory
.dir
);
1069 tor_free(cached_directory
.dir_z
);
1070 tor_free(cached_runningrouters
.dir
);
1071 tor_free(cached_runningrouters
.dir_z
);
1072 memset(&cached_directory
, 0, sizeof(cached_directory
));
1073 memset(&cached_runningrouters
, 0, sizeof(cached_runningrouters
));