Add a 'quit' command for the controller.
[tor.git] / src / or / dirserv.c
blobd5dc08d4551aafd039819480e285f32d2fbce689
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. Manages directory
12 * contents and generates directories.
13 **/
15 /** How far in the future do we allow a router to get? (seconds) */
16 #define ROUTER_ALLOW_SKEW (60*60*12) /* 12 hours */
17 /** How many seconds do we wait before regenerating the directory? */
18 #define DIR_REGEN_SLACK_TIME 5
20 /** Do we need to regenerate the directory when someone asks for it? */
21 static int the_directory_is_dirty = 1;
22 static int runningrouters_is_dirty = 1;
24 static void directory_remove_invalid(void);
25 static int dirserv_regenerate_directory(void);
26 /* Should be static; exposed for testing */
27 int add_fingerprint_to_dir(const char *nickname, const char *fp, smartlist_t *list);
29 /************** Fingerprint handling code ************/
31 typedef struct fingerprint_entry_t {
32 char *nickname;
33 char *fingerprint; /**< Stored as HEX_DIGEST_LEN characters, followed by a NUL */
34 } fingerprint_entry_t;
36 /** List of nickname-\>identity fingerprint mappings for all the routers
37 * that we recognize. Used to prevent Sybil attacks. */
38 /* Should be static; exposed for testing */
39 smartlist_t *fingerprint_list = NULL;
41 /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
42 * the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
43 * new, or 1 if we replaced the old value.
45 int /* Should be static; exposed for testing */
46 add_fingerprint_to_dir(const char *nickname, const char *fp, smartlist_t *list)
48 int i;
49 fingerprint_entry_t *ent;
50 tor_assert(nickname);
51 tor_assert(fp);
52 tor_assert(list);
54 for (i = 0; i < smartlist_len(list); ++i) {
55 ent = smartlist_get(list, i);
56 if (!strcasecmp(ent->nickname,nickname)) {
57 tor_free(ent->fingerprint);
58 ent->fingerprint = tor_strdup(fp);
59 return 1;
62 ent = tor_malloc(sizeof(fingerprint_entry_t));
63 ent->nickname = tor_strdup(nickname);
64 ent->fingerprint = tor_strdup(fp);
65 tor_strstrip(ent->fingerprint, " ");
66 smartlist_add(list, ent);
67 return 0;
70 /** Add the nickname and fingerprint for this OR to the
71 * global list of recognized identity key fingerprints. */
72 int
73 dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
75 char fp[FINGERPRINT_LEN+1];
76 if (crypto_pk_get_fingerprint(pk, fp, 0)<0) {
77 log_fn(LOG_ERR, "Error computing fingerprint");
78 return -1;
80 if (!fingerprint_list)
81 fingerprint_list = smartlist_create();
82 add_fingerprint_to_dir(nickname, fp, fingerprint_list);
83 return 0;
86 /** Parse the nickname-\>fingerprint mappings stored in the file named
87 * <b>fname</b>. The file format is line-based, with each non-blank
88 * holding one nickname, some space, and a fingerprint for that
89 * nickname. On success, replace the current fingerprint list with
90 * the contents of <b>fname</b> and return 0. On failure, leave the
91 * current fingerprint list untouched, and return -1. */
92 int
93 dirserv_parse_fingerprint_file(const char *fname)
95 char *cf;
96 char *nickname, *fingerprint;
97 smartlist_t *fingerprint_list_new;
98 int result;
99 config_line_t *front=NULL, *list;
101 cf = read_file_to_str(fname, 0);
102 if (!cf) {
103 log_fn(LOG_WARN, "Cannot open fingerprint file %s", fname);
104 return -1;
106 result = config_get_lines(cf, &front);
107 tor_free(cf);
108 if (result < 0) {
109 log_fn(LOG_WARN, "Error reading from fingerprint file");
110 return -1;
113 fingerprint_list_new = smartlist_create();
115 for (list=front; list; list=list->next) {
116 nickname = list->key; fingerprint = list->value;
117 if (strlen(nickname) > MAX_NICKNAME_LEN) {
118 log(LOG_NOTICE, "Nickname '%s' too long in fingerprint file. Skipping.", nickname);
119 continue;
121 if (strlen(fingerprint) != FINGERPRINT_LEN ||
122 !crypto_pk_check_fingerprint_syntax(fingerprint)) {
123 log_fn(LOG_NOTICE, "Invalid fingerprint (nickname '%s', fingerprint %s). Skipping.",
124 nickname, fingerprint);
125 continue;
127 if (0==strcasecmp(nickname, DEFAULT_CLIENT_NICKNAME)) {
128 /* If you approved an OR called "client", then clients who use
129 * the default nickname could all be rejected. That's no good. */
130 log(LOG_NOTICE,
131 "Authorizing a nickname '%s' would break many clients; skipping.",
132 DEFAULT_CLIENT_NICKNAME);
133 continue;
135 if (add_fingerprint_to_dir(nickname, fingerprint, fingerprint_list_new) != 0)
136 log(LOG_NOTICE, "Duplicate nickname '%s'.", nickname);
139 config_free_lines(front);
140 dirserv_free_fingerprint_list();
141 fingerprint_list = fingerprint_list_new;
142 /* Delete any routers whose fingerprints we no longer recognize */
143 directory_remove_invalid();
144 return 0;
147 /** Check whether <b>router</b> has a nickname/identity key combination that
148 * we recognize from the fingerprint list. Return 1 if router's
149 * identity and nickname match, -1 if we recognize the nickname but
150 * the identity key is wrong, and 0 if the nickname is not known. */
152 dirserv_router_fingerprint_is_known(const routerinfo_t *router)
154 int i, found=0;
155 fingerprint_entry_t *ent =NULL;
156 char fp[FINGERPRINT_LEN+1];
158 if (!fingerprint_list)
159 fingerprint_list = smartlist_create();
161 log_fn(LOG_DEBUG, "%d fingerprints known.", smartlist_len(fingerprint_list));
162 for (i=0;i<smartlist_len(fingerprint_list);++i) {
163 ent = smartlist_get(fingerprint_list, i);
164 log_fn(LOG_DEBUG,"%s vs %s", router->nickname, ent->nickname);
165 if (!strcasecmp(router->nickname,ent->nickname)) {
166 found = 1;
167 break;
171 if (!found) { /* No such server known */
172 log_fn(LOG_INFO,"no fingerprint found for '%s'",router->nickname);
173 return 0;
175 if (crypto_pk_get_fingerprint(router->identity_pkey, fp, 0)) {
176 log_fn(LOG_WARN,"error computing fingerprint");
177 return -1;
179 if (0==strcasecmp(ent->fingerprint, fp)) {
180 log_fn(LOG_DEBUG,"good fingerprint for '%s'",router->nickname);
181 return 1; /* Right fingerprint. */
182 } else {
183 log_fn(LOG_WARN,"mismatched fingerprint for '%s': expected '%s' got '%s'",
184 router->nickname, ent->fingerprint, fp);
185 return -1; /* Wrong fingerprint. */
189 /** If we are an authoritative dirserver, and the list of approved
190 * servers contains one whose identity key digest is <b>digest</b>,
191 * return that router's nickname. Otherwise return NULL. */
192 const char *
193 dirserv_get_nickname_by_digest(const char *digest)
195 char hexdigest[HEX_DIGEST_LEN+1];
196 if (!fingerprint_list)
197 return NULL;
198 tor_assert(digest);
200 base16_encode(hexdigest, HEX_DIGEST_LEN+1, digest, DIGEST_LEN);
201 SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t*, ent,
202 { if (!strcasecmp(hexdigest, ent->fingerprint))
203 return ent->nickname; } );
204 return NULL;
207 /** Clear the current fingerprint list. */
208 void
209 dirserv_free_fingerprint_list()
211 int i;
212 fingerprint_entry_t *ent;
213 if (!fingerprint_list)
214 return;
216 for (i = 0; i < smartlist_len(fingerprint_list); ++i) {
217 ent = smartlist_get(fingerprint_list, i);
218 tor_free(ent->nickname);
219 tor_free(ent->fingerprint);
220 tor_free(ent);
222 smartlist_free(fingerprint_list);
223 fingerprint_list = NULL;
227 * Descriptor list
230 /** List of routerinfo_t for all server descriptors that this dirserv
231 * is holding.
232 * XXXX This should eventually get coalesced into routerlist.c
234 static smartlist_t *descriptor_list = NULL;
236 /** Release all storage that the dirserv is holding for server
237 * descriptors. */
238 void
239 dirserv_free_descriptors()
241 if (!descriptor_list)
242 return;
243 SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
244 routerinfo_free(ri));
245 smartlist_clear(descriptor_list);
248 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
249 * unless we're configured to not care. Return 0 if all ok. */
250 static int
251 dirserv_router_has_valid_address(routerinfo_t *ri)
253 struct in_addr iaddr;
254 if (get_options()->DirAllowPrivateAddresses)
255 return 0; /* whatever it is, we're fine with it */
256 if (!tor_inet_aton(ri->address, &iaddr)) {
257 log_fn(LOG_INFO,"Router '%s' published non-IP address '%s'. Refusing.",
258 ri->nickname, ri->address);
259 return -1;
261 if (is_internal_IP(ntohl(iaddr.s_addr))) {
262 log_fn(LOG_INFO,"Router '%s' published internal IP address '%s'. Refusing.",
263 ri->nickname, ri->address);
264 return -1; /* it's a private IP, we should reject it */
266 return 0;
269 /** Parse the server descriptor at *desc and maybe insert it into the
270 * list of server descriptors, and (if the descriptor is well-formed)
271 * advance *desc immediately past the descriptor's end. Set msg to a
272 * message that should be passed back to the origin of this descriptor, or
273 * to NULL.
275 * Return 1 if descriptor is well-formed and accepted;
276 * 0 if well-formed and server is unapproved but accepted;
277 * -1 if it looks vaguely like a router descriptor but rejected;
278 * -2 if we can't find a router descriptor in *desc.
281 dirserv_add_descriptor(const char **desc, const char **msg)
283 routerinfo_t *ri = NULL, *ri_old=NULL;
284 int i, r, found=-1;
285 char *start, *end;
286 char *desc_tmp = NULL;
287 size_t desc_len;
288 time_t now;
289 int verified=1; /* whether we knew its fingerprint already */
290 tor_assert(msg);
291 *msg = NULL;
292 if (!descriptor_list)
293 descriptor_list = smartlist_create();
295 start = strstr(*desc, "router ");
296 if (!start) {
297 log_fn(LOG_WARN, "no 'router' line found. This is not a descriptor.");
298 return -2;
300 if ((end = strstr(start+6, "\nrouter "))) {
301 ++end; /* Include NL. */
302 } else if ((end = strstr(start+6, "\ndirectory-signature"))) {
303 ++end;
304 } else {
305 end = start+strlen(start);
307 desc_len = end-start;
308 desc_tmp = tor_strndup(start, desc_len); /* Is this strndup still needed???*/
310 /* Check: is the descriptor syntactically valid? */
311 ri = router_parse_entry_from_string(desc_tmp, NULL);
312 tor_free(desc_tmp);
313 if (!ri) {
314 log(LOG_WARN, "Couldn't parse descriptor");
315 *msg = "Rejected: Couldn't parse server descriptor.";
316 return -1;
318 /* Okay. Now check whether the fingerprint is recognized. */
319 r = dirserv_router_fingerprint_is_known(ri);
320 if (r==-1) {
321 log_fn(LOG_WARN, "Known nickname '%s', wrong fingerprint. Not adding (ContactInfo '%s', platform '%s').",
322 ri->nickname, ri->contact_info ? ri->contact_info : "",
323 ri->platform ? ri->platform : "");
324 *msg = "Rejected: There is already a verified server with this nickname and a different fingerprint.";
325 routerinfo_free(ri);
326 *desc = end;
327 return -1;
328 } else if (r==0) {
329 char fp[FINGERPRINT_LEN+1];
330 log_fn(LOG_INFO, "Unknown nickname '%s' (%s:%d). Will try to add.",
331 ri->nickname, ri->address, ri->or_port);
332 if (crypto_pk_get_fingerprint(ri->identity_pkey, fp, 1) < 0) {
333 log_fn(LOG_WARN, "Error computing fingerprint for '%s'", ri->nickname);
334 } else {
335 log_fn(LOG_INFO, "Fingerprint line: %s %s", ri->nickname, fp);
337 verified = 0;
339 /* Is there too much clock skew? */
340 now = time(NULL);
341 if (ri->published_on > now+ROUTER_ALLOW_SKEW) {
342 log_fn(LOG_NOTICE, "Publication time for nickname '%s' is too far (%d minutes) in the future; possible clock skew. Not adding (ContactInfo '%s', platform '%s').",
343 ri->nickname, (int)((ri->published_on-now)/60),
344 ri->contact_info ? ri->contact_info : "",
345 ri->platform ? ri->platform : "");
346 *msg = "Rejected: Your clock is set too far in the future, or your timezone is not correct.";
347 routerinfo_free(ri);
348 *desc = end;
349 return -1;
351 if (ri->published_on < now-ROUTER_MAX_AGE) {
352 log_fn(LOG_NOTICE, "Publication time for router with nickname '%s' is too far (%d minutes) in the past. Not adding (ContactInfo '%s', platform '%s').",
353 ri->nickname, (int)((now-ri->published_on)/60),
354 ri->contact_info ? ri->contact_info : "",
355 ri->platform ? ri->platform : "");
356 *msg = "Rejected: Server is expired, or your clock is too far in the past, or your timezone is not correct.";
357 routerinfo_free(ri);
358 *desc = end;
359 return -1;
361 if (dirserv_router_has_valid_address(ri) < 0) {
362 log_fn(LOG_NOTICE, "Router with nickname '%s' has invalid address '%s'. Not adding (ContactInfo '%s', platform '%s').",
363 ri->nickname, ri->address,
364 ri->contact_info ? ri->contact_info : "",
365 ri->platform ? ri->platform : "");
366 *msg = "Rejected: Address is not an IP, or IP is a private address.";
367 routerinfo_free(ri);
368 *desc = end;
369 return -1;
372 /* Do we already have an entry for this router? */
373 for (i = 0; i < smartlist_len(descriptor_list); ++i) {
374 ri_old = smartlist_get(descriptor_list, i);
375 if (!memcmp(ri->identity_digest, ri_old->identity_digest, DIGEST_LEN)) {
376 found = i;
377 break;
380 if (found >= 0) {
381 char hex_digest[HEX_DIGEST_LEN+1];
382 base16_encode(hex_digest, HEX_DIGEST_LEN+1, ri->identity_digest,DIGEST_LEN);
383 /* if so, decide whether to update it. */
384 if (ri_old->published_on >= ri->published_on) {
385 /* We already have a newer or equal-time descriptor */
386 log_fn(LOG_INFO,"We already have a new enough desc for server %s (nickname '%s'). Not adding.",hex_digest,ri->nickname);
387 *msg = "We already have a newer descriptor.";
388 /* This isn't really an error; return success. */
389 routerinfo_free(ri);
390 *desc = end;
391 return verified;
393 /* We don't alrady have a newer one; we'll update this one. */
394 log_fn(LOG_INFO,"Dirserv updating desc for server %s (nickname '%s')",hex_digest,ri->nickname);
395 *msg = verified?"Verified server updated":"Unverified server updated. (Have you sent us your key fingerprint?)";
396 routerinfo_free(ri_old);
397 smartlist_del_keeporder(descriptor_list, found);
398 } else {
399 /* Add at the end. */
400 log_fn(LOG_INFO,"Dirserv adding desc for nickname '%s'",ri->nickname);
401 *msg = verified?"Verified server added":"Unverified server added. (Have you sent us your key fingerprint?)";
404 ri->is_verified = verified ||
405 tor_version_as_new_as(ri->platform,"0.1.0.2-rc");
406 smartlist_add(descriptor_list, ri);
408 *desc = end;
409 directory_set_dirty();
411 return verified;
414 /** Remove all descriptors whose nicknames or fingerprints no longer
415 * are allowed by our fingerprint list. (Descriptors that used to be
416 * good can become bad when we reload the fingerprint list.)
418 static void
419 directory_remove_invalid(void)
421 int i;
422 int r;
423 routerinfo_t *ent;
424 if (!descriptor_list)
425 descriptor_list = smartlist_create();
427 for (i = 0; i < smartlist_len(descriptor_list); ++i) {
428 ent = smartlist_get(descriptor_list, i);
429 r = dirserv_router_fingerprint_is_known(ent);
430 if (r<0) {
431 log(LOG_INFO, "Router '%s' is now verified with a key; removing old router with same name and different key.",
432 ent->nickname);
433 routerinfo_free(ent);
434 smartlist_del(descriptor_list, i--);
435 } else if (r>0 && !ent->is_verified) {
436 log(LOG_INFO, "Router '%s' is now approved.", ent->nickname);
437 ent->is_verified = 1;
438 } else if (r==0 && ent->is_verified) {
439 log(LOG_INFO, "Router '%s' is no longer approved.", ent->nickname);
440 ent->is_verified = 0;
445 /** Write a list of unregistered descriptors into a newly allocated
446 * string and return it. Used by dirserv operators to keep track of
447 * fast nodes that haven't registered.
449 char *
450 dirserver_getinfo_unregistered(void)
452 int i, r;
453 smartlist_t *answerlist;
454 char buf[1024];
455 char *answer;
456 routerinfo_t *ent;
458 if (!descriptor_list)
459 return tor_strdup("");
461 answerlist = smartlist_create();
462 for (i = 0; i < smartlist_len(descriptor_list); ++i) {
463 ent = smartlist_get(descriptor_list, i);
464 r = dirserv_router_fingerprint_is_known(ent);
465 if (ent->bandwidthcapacity > 100000 && r == 0) {
466 /* then log this one */
467 tor_snprintf(buf, sizeof(buf),
468 "%s: BW %d on '%s'.",
469 ent->nickname, ent->bandwidthcapacity,
470 ent->platform ? ent->platform : "");
471 smartlist_add(answerlist, tor_strdup(buf));
474 answer = smartlist_join_strings(answerlist, "\r\n", 0, NULL);
475 SMARTLIST_FOREACH(answerlist, char *, cp, tor_free(cp));
476 smartlist_free(answerlist);
477 return answer;
480 /** Mark the directory as <b>dirty</b> -- when we're next asked for a
481 * directory, we will rebuild it instead of reusing the most recently
482 * generated one.
484 void
485 directory_set_dirty()
487 time_t now = time(NULL);
489 if (!the_directory_is_dirty)
490 the_directory_is_dirty = now;
491 if (!runningrouters_is_dirty)
492 runningrouters_is_dirty = now;
495 /** Load all descriptors from a directory stored in the string
496 * <b>dir</b>.
499 dirserv_load_from_directory_string(const char *dir)
501 const char *cp = dir, *m;
502 while (1) {
503 cp = strstr(cp, "\nrouter ");
504 if (!cp) break;
505 ++cp;
506 if (dirserv_add_descriptor(&cp,&m) < -1) {
507 /* only fail if parsing failed; keep going if simply rejected */
508 return -1;
510 --cp; /*Back up to newline.*/
512 return 0;
516 * Allocate and return a description of the status of the server <b>desc</b>,
517 * for use in a router-status line. The server is listed
518 * as running iff <b>is_live</b> is true.
520 static char *
521 list_single_server_status(routerinfo_t *desc, int is_live)
523 char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
524 char *cp;
526 tor_assert(desc);
528 cp = buf;
529 if (!is_live) {
530 *cp++ = '!';
532 if (desc->is_verified) {
533 strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
534 cp += strlen(cp);
535 *cp++ = '=';
537 *cp++ = '$';
538 base16_encode(cp, HEX_DIGEST_LEN+1, desc->identity_digest,
539 DIGEST_LEN);
540 return tor_strdup(buf);
543 /** Based on the routerinfo_ts in <b>routers</b>, allocate the
544 * contents of a router-status line, and store it in
545 * *<b>router_status_out</b>. Return 0 on success, -1 on failure.
548 list_server_status(smartlist_t *routers, char **router_status_out)
550 /* List of entries in a router-status style: An optional !, then an optional
551 * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
552 smartlist_t *rs_entries;
553 int authdir_mode = get_options()->AuthoritativeDir;
554 tor_assert(router_status_out);
556 rs_entries = smartlist_create();
558 SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
560 int is_live;
561 connection_t *conn;
562 conn = connection_get_by_identity_digest(
563 ri->identity_digest, CONN_TYPE_OR);
564 if (authdir_mode) {
565 /* Treat a router as alive if
566 * - It's me, and I'm not hibernating.
567 * or - we're connected to it. */
568 is_live = (router_is_me(ri) && !we_are_hibernating()) ||
569 (conn && conn->state == OR_CONN_STATE_OPEN);
570 } else {
571 is_live = ri->is_running;
573 smartlist_add(rs_entries, list_single_server_status(ri, is_live));
576 *router_status_out = smartlist_join_strings(rs_entries, " ", 0,NULL);
578 SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
579 smartlist_free(rs_entries);
581 return 0;
584 /** Remove any descriptors from the directory that are more than <b>age</b>
585 * seconds old.
587 void
588 dirserv_remove_old_servers(int age)
590 int i;
591 time_t cutoff;
592 routerinfo_t *ent;
593 if (!descriptor_list)
594 descriptor_list = smartlist_create();
596 cutoff = time(NULL) - age;
597 for (i = 0; i < smartlist_len(descriptor_list); ++i) {
598 ent = smartlist_get(descriptor_list, i);
599 if (ent->published_on <= cutoff) {
600 /* descriptor_list[i] is too old. Remove it. */
601 routerinfo_free(ent);
602 smartlist_del(descriptor_list, i--);
603 directory_set_dirty();
608 /** Generate a new directory and write it into a newly allocated string.
609 * Point *<b>dir_out</b> to the allocated string. Sign the
610 * directory with <b>private_key</b>. Return 0 on success, -1 on
611 * failure.
614 dirserv_dump_directory_to_string(char **dir_out,
615 crypto_pk_env_t *private_key)
617 char *router_status;
618 char *identity_pkey; /* Identity key, DER64-encoded. */
619 char *recommended_versions;
620 char digest[20];
621 char signature[128];
622 char published[33];
623 time_t published_on;
624 char *buf = NULL;
625 size_t buf_len;
626 int i;
627 size_t identity_pkey_len;
629 tor_assert(dir_out);
630 *dir_out = NULL;
632 if (!descriptor_list)
633 descriptor_list = smartlist_create();
635 if (list_server_status(descriptor_list, &router_status))
636 return -1;
638 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
639 &identity_pkey_len)<0) {
640 log_fn(LOG_WARN,"write identity_pkey to string failed!");
641 return -1;
645 smartlist_t *versions;
646 config_line_t *ln;
647 versions = smartlist_create();
648 for (ln = get_options()->RecommendedVersions; ln; ln = ln->next) {
649 smartlist_split_string(versions, ln->value, ",",
650 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
652 recommended_versions = smartlist_join_strings(versions,",",0,NULL);
653 SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
654 smartlist_free(versions);
657 dirserv_remove_old_servers(ROUTER_MAX_AGE);
658 published_on = time(NULL);
659 format_iso_time(published, published_on);
661 buf_len = 2048+strlen(recommended_versions)+
662 strlen(router_status);
663 SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
664 buf_len += strlen(ri->signed_descriptor));
665 buf = tor_malloc(buf_len);
666 /* We'll be comparing against buf_len throughout the rest of the
667 function, though strictly speaking we shouldn't be able to exceed
668 it. This is C, after all, so we may as well check for buffer
669 overruns.*/
671 tor_snprintf(buf, buf_len,
672 "signed-directory\n"
673 "published %s\n"
674 "recommended-software %s\n"
675 "router-status %s\n"
676 "dir-signing-key\n%s\n",
677 published, recommended_versions, router_status,
678 identity_pkey);
680 tor_free(recommended_versions);
681 tor_free(router_status);
682 tor_free(identity_pkey);
684 SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
685 if (strlcat(buf, ri->signed_descriptor, buf_len) >= buf_len)
686 goto truncated);
688 /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
689 signature.
691 if (strlcat(buf, "directory-signature ", buf_len) >= buf_len)
692 goto truncated;
693 if (strlcat(buf, get_options()->Nickname, buf_len) >= buf_len)
694 goto truncated;
695 if (strlcat(buf, "\n", buf_len) >= buf_len)
696 goto truncated;
698 if (router_get_dir_hash(buf,digest)) {
699 log_fn(LOG_WARN,"couldn't compute digest");
700 tor_free(buf);
701 return -1;
703 if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) {
704 log_fn(LOG_WARN,"couldn't sign digest");
705 tor_free(buf);
706 return -1;
708 log(LOG_DEBUG,"generated directory digest begins with %s",hex_str(digest,4));
710 if (strlcat(buf, "-----BEGIN SIGNATURE-----\n", buf_len) >= buf_len)
711 goto truncated;
713 i = strlen(buf);
714 if (base64_encode(buf+i, buf_len-i, signature, 128) < 0) {
715 log_fn(LOG_WARN,"couldn't base64-encode signature");
716 tor_free(buf);
717 return -1;
720 if (strlcat(buf, "-----END SIGNATURE-----\n", buf_len) >= buf_len)
721 goto truncated;
723 *dir_out = buf;
724 return 0;
725 truncated:
726 log_fn(LOG_WARN,"tried to exceed string length.");
727 tor_free(buf);
728 return -1;
731 /** Most recently generated encoded signed directory. */
732 static char *the_directory = NULL;
733 static size_t the_directory_len = 0;
734 static char *the_directory_z = NULL;
735 static size_t the_directory_z_len = 0;
737 /** DOCDOC */
738 typedef struct cached_dir_t {
739 char *dir;
740 char *dir_z;
741 size_t dir_len;
742 size_t dir_z_len;
743 time_t published;
744 } cached_dir_t;
746 /* used only by non-auth dirservers */
747 static cached_dir_t cached_directory = { NULL, NULL, 0, 0, 0 };
748 static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0 };
750 /** If we have no cached directory, or it is older than <b>when</b>, then
751 * replace it with <b>directory</b>, published at <b>when</b>.
753 void
754 dirserv_set_cached_directory(const char *directory, time_t when,
755 int is_running_routers)
757 time_t now;
758 cached_dir_t *d;
759 now = time(NULL);
760 d = is_running_routers ? &cached_runningrouters : &cached_directory;
761 if (when<=d->published) {
762 log_fn(LOG_INFO, "Ignoring old directory; not caching.");
763 } else if (when>=now+ROUTER_MAX_AGE) {
764 log_fn(LOG_INFO, "Ignoring future directory; not caching.");
765 } else {
766 /* if (when>d->published && when<now+ROUTER_MAX_AGE) */
767 log_fn(LOG_DEBUG, "Caching directory.");
768 tor_free(d->dir);
769 d->dir = tor_strdup(directory);
770 d->dir_len = strlen(directory);
771 tor_free(d->dir_z);
772 if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
773 ZLIB_METHOD)) {
774 log_fn(LOG_WARN,"Error compressing cached directory");
776 d->published = when;
777 if (!is_running_routers) {
778 char filename[512];
779 tor_snprintf(filename,sizeof(filename),"%s/cached-directory", get_options()->DataDirectory);
780 if (write_str_to_file(filename,cached_directory.dir,0) < 0) {
781 log_fn(LOG_NOTICE, "Couldn't write cached directory to disk. Ignoring.");
787 /** Set *<b>directory</b> to the most recently generated encoded signed
788 * directory, generating a new one as necessary. If not an authoritative
789 * directory may return 0 if no directory is yet cached.*/
790 size_t
791 dirserv_get_directory(const char **directory, int compress)
793 if (!get_options()->AuthoritativeDir) {
794 cached_dir_t *d = &cached_directory;
795 *directory = compress ? d->dir_z : d->dir;
796 if (*directory) {
797 return compress ? d->dir_z_len : d->dir_len;
798 } else {
799 /* no directory yet retrieved */
800 return 0;
803 if (the_directory_is_dirty &&
804 the_directory_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
805 if (dirserv_regenerate_directory())
806 return 0;
807 } else {
808 log(LOG_INFO,"Directory still clean, reusing.");
810 *directory = compress ? the_directory_z : the_directory;
811 return compress ? the_directory_z_len : the_directory_len;
815 * Generate a fresh directory (authdirservers only.)
817 static int
818 dirserv_regenerate_directory(void)
820 char *new_directory=NULL;
822 if (dirserv_dump_directory_to_string(&new_directory,
823 get_identity_key())) {
824 log(LOG_WARN, "Error creating directory.");
825 tor_free(new_directory);
826 return -1;
828 tor_free(the_directory);
829 the_directory = new_directory;
830 the_directory_len = strlen(the_directory);
831 log_fn(LOG_INFO,"New directory (size %d):\n%s",(int)the_directory_len,
832 the_directory);
833 tor_free(the_directory_z);
834 if (tor_gzip_compress(&the_directory_z, &the_directory_z_len,
835 the_directory, the_directory_len,
836 ZLIB_METHOD)) {
837 log_fn(LOG_WARN, "Error gzipping directory.");
838 return -1;
841 the_directory_is_dirty = 0;
843 /* Save the directory to disk so we re-load it quickly on startup.
845 dirserv_set_cached_directory(the_directory, time(NULL), 0);
847 return 0;
850 static char *the_runningrouters=NULL;
851 static size_t the_runningrouters_len=0;
852 static char *the_runningrouters_z=NULL;
853 static size_t the_runningrouters_z_len=0;
855 /** Replace the current running-routers list with a newly generated one. */
856 static int
857 generate_runningrouters(crypto_pk_env_t *private_key)
859 char *s=NULL, *cp;
860 char *router_status=NULL;
861 char digest[DIGEST_LEN];
862 char signature[PK_BYTES];
863 int i;
864 char published[33];
865 size_t len;
866 time_t published_on;
867 char *identity_pkey; /* Identity key, DER64-encoded. */
868 size_t identity_pkey_len;
870 if (!descriptor_list)
871 descriptor_list = smartlist_create();
873 if (list_server_status(descriptor_list, &router_status)) {
874 goto err;
876 if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
877 &identity_pkey_len)<0) {
878 log_fn(LOG_WARN,"write identity_pkey to string failed!");
879 goto err;
881 published_on = time(NULL);
882 format_iso_time(published, published_on);
884 len = 2048+strlen(router_status);
885 s = tor_malloc_zero(len);
886 tor_snprintf(s, len, "network-status\n"
887 "published %s\n"
888 "router-status %s\n"
889 "dir-signing-key\n%s"
890 "directory-signature %s\n"
891 "-----BEGIN SIGNATURE-----\n",
892 published, router_status, identity_pkey, get_options()->Nickname);
893 tor_free(router_status);
894 tor_free(identity_pkey);
895 if (router_get_runningrouters_hash(s,digest)) {
896 log_fn(LOG_WARN,"couldn't compute digest");
897 goto err;
899 if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) {
900 log_fn(LOG_WARN,"couldn't sign digest");
901 goto err;
904 i = strlen(s);
905 cp = s+i;
906 if (base64_encode(cp, len-i, signature, 128) < 0) {
907 log_fn(LOG_WARN,"couldn't base64-encode signature");
908 goto err;
910 if (strlcat(s, "-----END SIGNATURE-----\n", len) >= len) {
911 goto err;
914 tor_free(the_runningrouters);
915 the_runningrouters = s;
916 the_runningrouters_len = strlen(s);
917 tor_free(the_runningrouters_z);
918 if (tor_gzip_compress(&the_runningrouters_z, &the_runningrouters_z_len,
919 the_runningrouters, the_runningrouters_len,
920 ZLIB_METHOD)) {
921 log_fn(LOG_WARN, "Error gzipping runningrouters");
922 return -1;
924 runningrouters_is_dirty = 0;
926 /* We don't cache running-routers to disk, so there's no point in
927 * authdirservers caching it. */
928 /* dirserv_set_cached_directory(the_runningrouters, time(NULL), 1); */
930 return 0;
931 err:
932 tor_free(s);
933 tor_free(router_status);
934 return -1;
937 /** Set *<b>rr</b> to the most recently generated encoded signed
938 * running-routers list, generating a new one as necessary. Return the
939 * size of the directory on success, and 0 on failure. */
940 size_t
941 dirserv_get_runningrouters(const char **rr, int compress)
943 if (!get_options()->AuthoritativeDir) {
944 cached_dir_t *d = &cached_runningrouters;
945 *rr = compress ? d->dir_z : d->dir;
946 if (*rr) {
947 return compress ? d->dir_z_len : d->dir_len;
948 } else {
949 /* no directory yet retrieved */
950 return 0;
953 if (runningrouters_is_dirty &&
954 runningrouters_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
955 if (generate_runningrouters(get_identity_key())) {
956 log_fn(LOG_ERR, "Couldn't generate running-routers list?");
957 return 0;
960 *rr = compress ? the_runningrouters_z : the_runningrouters;
961 return compress ? the_runningrouters_z_len : the_runningrouters_len;
964 /** Called when a TLS handshake has completed successfully with a
965 * router listening at <b>address</b>:<b>or_port</b>, and has yielded
966 * a certificate with digest <b>digest_rcvd</b> and nickname
967 * <b>nickname_rcvd</b>. When this happens, it's clear that any other
968 * descriptors for that address/port combination must be unusable:
969 * delete them if they are not verified.
971 * Also, if as_advertised is 1, then inform the reachability checker
972 * that we could get to this guy.
974 void
975 dirserv_orconn_tls_done(const char *address,
976 uint16_t or_port,
977 const char *digest_rcvd,
978 const char *nickname_rcvd,
979 int as_advertised) //XXXRD
981 int i;
982 tor_assert(address);
983 tor_assert(digest_rcvd);
984 tor_assert(nickname_rcvd);
986 if (!descriptor_list)
987 return;
989 for (i = 0; i < smartlist_len(descriptor_list); ++i) {
990 routerinfo_t *ri = smartlist_get(descriptor_list, i);
991 int drop = 0;
992 if (ri->is_verified)
993 continue;
994 if (!strcasecmp(address, ri->address) &&
995 or_port == ri->or_port) {
996 /* We have a router at the same address! */
997 if (strcasecmp(ri->nickname, nickname_rcvd)) {
998 log_fn(LOG_NOTICE, "Dropping descriptor: nickname '%s' does not match nickname '%s' in cert from %s:%d",
999 ri->nickname, nickname_rcvd, address, or_port);
1000 drop = 1;
1001 } else if (memcmp(ri->identity_digest, digest_rcvd, DIGEST_LEN)) {
1002 log_fn(LOG_NOTICE, "Dropping descriptor: identity key does not match key in cert from %s:%d",
1003 address, or_port);
1004 drop = 1;
1006 if (drop) {
1007 routerinfo_free(ri);
1008 smartlist_del(descriptor_list, i--);
1009 directory_set_dirty();
1015 /** Release all storage used by the directory server. */
1016 void
1017 dirserv_free_all(void)
1019 if (fingerprint_list) {
1020 SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t*, fp,
1021 { tor_free(fp->nickname);
1022 tor_free(fp->fingerprint);
1023 tor_free(fp); });
1024 smartlist_free(fingerprint_list);
1025 fingerprint_list = NULL;
1027 if (descriptor_list) {
1028 SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
1029 routerinfo_free(ri));
1030 smartlist_free(descriptor_list);
1031 descriptor_list = NULL;
1033 tor_free(the_directory);
1034 tor_free(the_directory_z);
1035 the_directory_len = 0;
1036 the_directory_z_len = 0;
1037 tor_free(the_runningrouters);
1038 tor_free(the_runningrouters_z);
1039 the_runningrouters_len = 0;
1040 the_runningrouters_z_len = 0;
1041 tor_free(cached_directory.dir);
1042 tor_free(cached_directory.dir_z);
1043 tor_free(cached_runningrouters.dir);
1044 tor_free(cached_runningrouters.dir_z);
1045 memset(&cached_directory, 0, sizeof(cached_directory));
1046 memset(&cached_runningrouters, 0, sizeof(cached_runningrouters));