When we connect and finish TLS negotiation with address:port, it is obvious that...
[tor.git] / src / or / dirserv.c
blobd966fb1ca8b0ad3ea51e7f8e46eee1686703aa7d
1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson. */
3 /* See LICENSE for licensing information */
4 /* $Id$ */
5 const char dirserv_c_id[] = "$Id$";
7 #include "or.h"
9 /**
10 * \file dirserv.c
11 * \brief Directory server core implementation.
12 **/
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 {
31 char *nickname;
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)
45 int i;
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);
55 return;
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.
67 int
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");
73 return -1;
75 add_fingerprint_to_dir(nickname, fp);
76 return 0;
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. */
85 int
86 dirserv_parse_fingerprint_file(const char *fname)
88 char *cf;
89 char *nickname, *fingerprint;
90 smartlist_t *fingerprint_list_new;
91 int i, result;
92 fingerprint_entry_t *ent;
93 struct config_line_t *front=NULL, *list;
95 cf = read_file_to_str(fname, 0);
96 if (!cf) {
97 log_fn(LOG_WARN, "Cannot open fingerprint file %s", fname);
98 return -1;
100 result = config_get_lines(cf, &front);
101 tor_free(cf);
102 if (result < 0) {
103 log_fn(LOG_WARN, "Error reading from fingerprint file");
104 return -1;
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);
113 continue;
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);
119 continue;
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. */
124 log(LOG_NOTICE,
125 "Authorizing a nickname '%s' would break many clients; skipping.",
126 DEFAULT_CLIENT_NICKNAME);
127 continue;
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();
150 return 0;
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)
160 int i, found=0;
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)) {
172 found = 1;
173 break;
177 if (!found) { /* No such server known */
178 log_fn(LOG_INFO,"no fingerprint found for '%s'",router->nickname);
179 return 0;
181 if (crypto_pk_get_fingerprint(router->identity_pkey, fp, 0)) {
182 log_fn(LOG_WARN,"error computing fingerprint");
183 return -1;
185 if (0==strcasecmp(ent->fingerprint, fp)) {
186 log_fn(LOG_DEBUG,"good fingerprint for '%s'",router->nickname);
187 return 1; /* Right fingerprint. */
188 } else {
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)
201 return NULL;
202 tor_assert(digest);
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; } );
208 return NULL;
211 #if 0
212 /** Return true iff any router named <b>nickname</b> with <b>digest</b>
213 * is in the verified fingerprint list. */
214 static int
215 router_nickname_is_approved(const char *nickname, const char *digest)
217 const char *n;
219 n = dirserv_get_nickname_by_digest(digest);
220 if (n && !strcasecmp(n,nickname))
221 return 1;
222 else
223 return 0;
225 #endif
227 /** Clear the current fingerprint list. */
228 void
229 dirserv_free_fingerprint_list()
231 int i;
232 fingerprint_entry_t *ent;
233 if (!fingerprint_list)
234 return;
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);
240 tor_free(ent);
242 smartlist_free(fingerprint_list);
243 fingerprint_list = NULL;
247 * Descriptor list
250 /** List of routerinfo_t for all server descriptors that this dirserv
251 * is holding.
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
257 * descriptors. */
258 void
259 dirserv_free_descriptors()
261 if (!descriptor_list)
262 return;
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. */
270 static int
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);
279 return -1;
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 */
286 return 0;
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
293 * to NULL.
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;
304 int i, r, found=-1;
305 char *start, *end;
306 char *desc_tmp = NULL;
307 size_t desc_len;
308 time_t now;
309 int verified=1; /* whether we knew its fingerprint already */
310 tor_assert(msg);
311 *msg = NULL;
312 if (!descriptor_list)
313 descriptor_list = smartlist_create();
315 start = strstr(*desc, "router ");
316 if (!start) {
317 log_fn(LOG_WARN, "no 'router' line found. This is not a descriptor.");
318 return -2;
320 if ((end = strstr(start+6, "\nrouter "))) {
321 ++end; /* Include NL. */
322 } else if ((end = strstr(start+6, "\ndirectory-signature"))) {
323 ++end;
324 } else {
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);
332 tor_free(desc_tmp);
333 if (!ri) {
334 log(LOG_WARN, "Couldn't parse descriptor");
335 *msg = "Rejected: Couldn't parse server descriptor.";
336 return -1;
338 /* Okay. Now check whether the fingerprint is recognized. */
339 r = dirserv_router_fingerprint_is_known(ri);
340 if (r==-1) {
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.";
343 routerinfo_free(ri);
344 *desc = end;
345 return -1;
346 } else if (r==0) {
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);
352 } else {
353 log_fn(LOG_INFO, "Fingerprint line: %s %s", ri->nickname, fp);
355 verified = 0;
357 /* Is there too much clock skew? */
358 now = time(NULL);
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.";
362 routerinfo_free(ri);
363 *desc = end;
364 return -1;
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.";
369 routerinfo_free(ri);
370 *desc = end;
371 return -1;
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.";
376 routerinfo_free(ri);
377 *desc = end;
378 return -1;
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)) {
385 found = i;
386 break;
389 if (found >= 0) {
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. */
398 routerinfo_free(ri);
399 *desc = end;
400 return verified;
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);
407 } else {
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);
417 *desc = end;
418 directory_set_dirty();
420 return verified;
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.)
427 static void
428 directory_remove_unrecognized(void)
430 int i;
431 int r;
432 routerinfo_t *ent;
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);
439 if (r<0) {
440 log(LOG_INFO, "Router '%s' is now verified with a key; removing old router with same name and different key.",
441 ent->nickname);
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
456 * generated one.
458 void
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
470 * <b>dir</b>.
473 dirserv_load_from_directory_string(const char *dir)
475 const char *cp = dir, *m;
476 while (1) {
477 cp = strstr(cp, "\nrouter ");
478 if (!cp) break;
479 ++cp;
480 if (dirserv_add_descriptor(&cp,&m) < -1) {
481 /* only fail if parsing failed; keep going if simply rejected */
482 return -1;
484 --cp; /*Back up to newline.*/
486 return 0;
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.
495 static char *
496 list_single_server_status(routerinfo_t *desc, int is_live,
497 int rr_format)
499 char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
500 char *cp;
502 tor_assert(desc);
504 cp = buf;
505 if (!is_live) {
506 *cp++ = '!';
508 if (desc->is_verified) {
509 strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
510 cp += strlen(cp);
511 if (!rr_format)
512 *cp++ = '=';
514 if (!desc->is_verified || !rr_format) {
515 *cp++ = '$';
516 base16_encode(cp, HEX_DIGEST_LEN+1, desc->identity_digest,
517 DIGEST_LEN);
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
540 * series.
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,
550 int is_live;
551 connection_t *conn;
552 conn = connection_get_by_identity_digest(
553 ri->identity_digest, CONN_TYPE_OR);
554 if (authdir_mode) {
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);
560 } else {
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);
577 return 0;
580 /** Remove any descriptors from the directory that are more than <b>age</b>
581 * seconds old.
583 void
584 dirserv_remove_old_servers(int age)
586 int i;
587 time_t cutoff;
588 routerinfo_t *ent;
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
607 * failure.
610 dirserv_dump_directory_to_string(char **dir_out,
611 crypto_pk_env_t *private_key)
613 char *cp;
614 char *running_routers, *router_status;
615 char *identity_pkey; /* Identity key, DER64-encoded. */
616 char *recommended_versions;
617 char digest[20];
618 char signature[128];
619 char published[33];
620 time_t published_on;
621 char *buf = NULL;
622 size_t buf_len;
623 int i;
625 tor_assert(dir_out);
626 *dir_out = NULL;
628 if (!descriptor_list)
629 descriptor_list = smartlist_create();
631 if (list_server_status(descriptor_list, &running_routers, &router_status))
632 return -1;
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.
638 #if 1
639 if (crypto_pk_DER64_encode_public_key(private_key, &identity_pkey)<0) {
640 log_fn(LOG_WARN,"write identity_pkey to string failed!");
641 return -1;
643 #else
645 int l;
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!");
648 return -1;
651 #endif
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
678 overruns.*/
680 tor_snprintf(buf, buf_len,
681 "signed-directory\n"
682 "published %s\n"
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,
688 identity_pkey);
690 tor_free(recommended_versions);
691 tor_free(running_routers);
692 tor_free(router_status);
693 tor_free(identity_pkey);
694 i = strlen(buf);
695 cp = buf+i;
697 SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
698 if (strlcat(buf, ri->signed_descriptor, buf_len) >= buf_len)
699 goto truncated);
701 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
702 signature.
704 if (strlcat(buf, "directory-signature ", buf_len) >= buf_len)
705 goto truncated;
706 if (strlcat(buf, get_options()->Nickname, buf_len) >= buf_len)
707 goto truncated;
708 if (strlcat(buf, "\n", buf_len) >= buf_len)
709 goto truncated;
711 if (router_get_dir_hash(buf,digest)) {
712 log_fn(LOG_WARN,"couldn't compute digest");
713 tor_free(buf);
714 return -1;
716 if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) {
717 log_fn(LOG_WARN,"couldn't sign digest");
718 tor_free(buf);
719 return -1;
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)
724 goto truncated;
726 i = strlen(buf);
727 cp = buf+i;
728 if (base64_encode(cp, buf_len-i, signature, 128) < 0) {
729 log_fn(LOG_WARN,"couldn't base64-encode signature");
730 tor_free(buf);
731 return -1;
734 if (strlcat(buf, "-----END SIGNATURE-----\n", buf_len) >= buf_len)
735 goto truncated;
737 *dir_out = buf;
738 return 0;
739 truncated:
740 log_fn(LOG_WARN,"tried to exceed string length.");
741 tor_free(buf);
742 return -1;
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 {
752 char *dir;
753 char *dir_z;
754 size_t dir_len;
755 size_t dir_z_len;
756 time_t published;
757 } 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)
769 time_t now;
770 cached_dir_t *d;
771 now = time(NULL);
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.");
777 } else {
778 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
779 log_fn(LOG_DEBUG, "Caching directory.");
780 tor_free(d->dir);
781 d->dir = tor_strdup(directory);
782 d->dir_len = strlen(directory);
783 tor_free(d->dir_z);
784 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
785 ZLIB_METHOD)) {
786 log_fn(LOG_WARN,"Error compressing cached directory");
788 d->published = when;
789 if (!is_running_routers) {
790 char filename[512];
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;
807 if (*directory) {
808 return compress ? d->dir_z_len : d->dir_len;
809 } else {
810 /* no directory yet retrieved */
811 return 0;
814 if (the_directory_is_dirty &&
815 the_directory_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
816 if (dirserv_regenerate_directory())
817 return 0;
818 } else {
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);
836 return -1;
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,
842 the_directory);
843 tor_free(the_directory_z);
844 if (tor_gzip_compress(&the_directory_z, &the_directory_z_len,
845 the_directory, the_directory_len,
846 ZLIB_METHOD)) {
847 log_fn(LOG_WARN, "Error gzipping directory.");
848 return -1;
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.");
859 tor_cleanup();
860 exit(0);
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);
869 return 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)
880 char *s=NULL, *cp;
881 char *router_status=NULL;
882 char digest[DIGEST_LEN];
883 char signature[PK_BYTES];
884 int i;
885 char published[33];
886 size_t len;
887 time_t published_on;
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)) {
894 goto err;
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.
900 #if 1
901 if (crypto_pk_DER64_encode_public_key(private_key, &identity_pkey)<0) {
902 log_fn(LOG_WARN,"write identity_pkey to string failed!");
903 goto err;
905 #else
907 int l;
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!");
910 goto err;
913 #endif
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"
920 "published %s\n"
921 "router-status %s\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");
930 goto err;
932 if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) {
933 log_fn(LOG_WARN,"couldn't sign digest");
934 goto err;
937 i = strlen(s);
938 cp = s+i;
939 if (base64_encode(cp, len-i, signature, 128) < 0) {
940 log_fn(LOG_WARN,"couldn't base64-encode signature");
941 goto err;
943 if (strlcat(s, "-----END SIGNATURE-----\n", len) >= len) {
944 goto err;
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,
953 ZLIB_METHOD)) {
954 log_fn(LOG_WARN, "Error gzipping runningrouters");
955 return -1;
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); */
963 return 0;
964 err:
965 tor_free(s);
966 tor_free(router_status);
967 return -1;
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;
978 if (*rr) {
979 return compress ? d->dir_z_len : d->dir_len;
980 } else {
981 /* no directory yet retrieved */
982 return 0;
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?");
989 return 0;
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.
1003 void
1004 dirserv_orconn_tls_done(const char *address,
1005 uint16_t or_port,
1006 const char *digest_rcvd,
1007 const char *nickname_rcvd)
1009 int i;
1010 tor_assert(address);
1011 tor_assert(digest_rcvd);
1012 tor_assert(nickname_rcvd);
1014 if (!descriptor_list)
1015 return;
1017 for (i = 0; i < smartlist_len(descriptor_list); ++i) {
1018 routerinfo_t *ri = smartlist_get(descriptor_list, i);
1019 int drop = 0;
1020 if (ri->is_verified)
1021 continue;
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);
1028 drop = 1;
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",
1031 address, or_port);
1032 drop = 1;
1034 if (drop) {
1035 routerinfo_free(ri);
1036 smartlist_del(descriptor_list, i--);
1037 directory_set_dirty();
1043 void
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);
1050 tor_free(fp); });
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));