1 /* Copyright 2001-2003 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
5 #define OR_PUBLICKEY_BEGIN_TAG "-----BEGIN RSA PUBLIC KEY-----\n"
6 #define OR_PUBLICKEY_END_TAG "-----END RSA PUBLIC KEY-----\n"
7 #define OR_SIGNATURE_BEGIN_TAG "-----BEGIN SIGNATURE-----\n"
8 #define OR_SIGNATURE_END_TAG "-----END SIGNATURE-----\n"
11 /* XXX this is required on rh7 to make strptime not complain. how bad
12 * is this for portability?
17 /****************************************************************************/
19 static routerlist_t
*routerlist
= NULL
; /* router array */
20 static routerinfo_t
*desc_routerinfo
= NULL
; /* my descriptor */
21 static char descriptor
[8192]; /* string representation of my descriptor */
23 extern or_options_t options
; /* command-line and config-file options */
25 /****************************************************************************/
27 struct directory_token
;
28 typedef struct directory_token directory_token_t
;
30 /* static function prototypes */
31 static int router_add_exit_policy_from_string(routerinfo_t
*router
, char *s
);
32 static int router_add_exit_policy(routerinfo_t
*router
,
33 directory_token_t
*tok
);
34 static int router_resolve_routerlist(routerlist_t
*dir
);
36 /****************************************************************************/
38 void router_retry_connections(void) {
42 for (i
=0;i
<routerlist
->n_routers
;i
++) {
43 router
= routerlist
->routers
[i
];
44 if(!connection_exact_get_by_addr_port(router
->addr
,router
->or_port
)) {
46 log_fn(LOG_DEBUG
,"connecting to OR %s:%u.",router
->address
,router
->or_port
);
47 connection_or_connect(router
);
52 routerinfo_t
*router_pick_directory_server(void) {
53 /* pick a random running router with a positive dir_port */
55 routerinfo_t
*router
, *dirserver
=NULL
;
61 for(i
=0;i
<routerlist
->n_routers
;i
++) {
62 router
= routerlist
->routers
[i
];
63 if(router
->dir_port
> 0 && router
->is_running
)
68 log_fn(LOG_INFO
,"No dirservers are reachable. Trying them all again.");
69 /* no running dir servers found? go through and mark them all as up,
70 * and we'll cycle through the list again. */
71 for(i
=0;i
<routerlist
->n_routers
;i
++) {
72 router
= routerlist
->routers
[i
];
73 if(router
->dir_port
> 0) {
74 router
->is_running
= 1;
81 j
= crypto_pseudo_rand_int(num_dirservers
);
82 for (i
=0;i
<routerlist
->n_routers
;i
++) {
83 router
= routerlist
->routers
[i
];
84 if (router
->dir_port
> 0 && router
->is_running
) {
88 log_fn(LOG_DEBUG
, "Chose server '%s'", router
->nickname
);
97 routerinfo_t
*router_pick_randomly_from_running(void) {
104 for(i
=0;i
<routerlist
->n_routers
;i
++) {
105 if(routerlist
->routers
[i
]->is_running
)
110 log_fn(LOG_INFO
,"No routers are running. Returning NULL.");
113 j
= crypto_pseudo_rand_int(num_running
);
114 for (i
=0;i
<routerlist
->n_routers
;i
++) {
115 if (routerlist
->routers
[i
]->is_running
) {
119 log_fn(LOG_DEBUG
, "Chose server '%s'", routerlist
->routers
[i
]->nickname
);
120 return routerlist
->routers
[i
];
128 void router_upload_desc_to_dirservers(void) {
130 routerinfo_t
*router
;
135 if (!router_get_my_descriptor()) {
136 log_fn(LOG_WARN
, "No descriptor; skipping upload");
140 for(i
=0;i
<routerlist
->n_routers
;i
++) {
141 router
= routerlist
->routers
[i
];
142 if(router
->dir_port
> 0)
143 directory_initiate_command(router
, DIR_CONN_STATE_CONNECTING_UPLOAD
);
147 routerinfo_t
*router_get_by_addr_port(uint32_t addr
, uint16_t port
) {
149 routerinfo_t
*router
;
153 for(i
=0;i
<routerlist
->n_routers
;i
++) {
154 router
= routerlist
->routers
[i
];
155 if ((router
->addr
== addr
) && (router
->or_port
== port
))
161 routerinfo_t
*router_get_by_link_pk(crypto_pk_env_t
*pk
)
164 routerinfo_t
*router
;
168 for(i
=0;i
<routerlist
->n_routers
;i
++) {
169 router
= routerlist
->routers
[i
];
170 if (0 == crypto_pk_cmp_keys(router
->link_pkey
, pk
))
176 routerinfo_t
*router_get_by_nickname(char *nickname
)
179 routerinfo_t
*router
;
183 for(i
=0;i
<routerlist
->n_routers
;i
++) {
184 router
= routerlist
->routers
[i
];
185 if (0 == strcmp(router
->nickname
, nickname
))
191 /* a way to access routerlist outside this file */
192 void router_get_routerlist(routerlist_t
**prouterlist
) {
193 *prouterlist
= routerlist
;
196 /* delete a router from memory */
197 void routerinfo_free(routerinfo_t
*router
)
199 struct exit_policy_t
*e
;
204 tor_free(router
->address
);
205 tor_free(router
->nickname
);
206 if (router
->onion_pkey
)
207 crypto_free_pk_env(router
->onion_pkey
);
208 if (router
->link_pkey
)
209 crypto_free_pk_env(router
->link_pkey
);
210 if (router
->identity_pkey
)
211 crypto_free_pk_env(router
->identity_pkey
);
212 while (router
->exit_policy
) {
213 e
= router
->exit_policy
;
214 router
->exit_policy
= e
->next
;
221 void routerlist_free(routerlist_t
*rl
)
224 for (i
= 0; i
< rl
->n_routers
; ++i
)
225 routerinfo_free(rl
->routers
[i
]);
226 tor_free(rl
->routers
);
227 tor_free(rl
->software_versions
);
231 void router_mark_as_down(char *nickname
) {
232 routerinfo_t
*router
= router_get_by_nickname(nickname
);
233 if(!router
) /* we don't seem to know about him in the first place */
235 log_fn(LOG_DEBUG
,"Marking %s as down.",router
->nickname
);
236 router
->is_running
= 0;
239 /* load the router list */
240 int router_set_routerlist_from_file(char *routerfile
)
244 string
= read_file_to_str(routerfile
);
246 log_fn(LOG_WARN
,"Failed to load routerfile %s.",routerfile
);
250 if(router_set_routerlist_from_string(string
) < 0) {
251 log_fn(LOG_WARN
,"The routerfile itself was corrupt.");
262 K_DIRECTORY_SIGNATURE
,
263 K_RECOMMENDED_SOFTWARE
,
280 struct token_table_ent
{ char *t
; int v
; };
282 static struct token_table_ent token_table
[] = {
283 { "accept", K_ACCEPT
},
284 { "directory-signature", K_DIRECTORY_SIGNATURE
},
285 { "reject", K_REJECT
},
286 { "router", K_ROUTER
},
287 { "recommended-software", K_RECOMMENDED_SOFTWARE
},
288 { "signed-directory", K_SIGNED_DIRECTORY
},
289 { "signing-key", K_SIGNING_KEY
},
290 { "onion-key", K_ONION_KEY
},
291 { "link-key", K_LINK_KEY
},
292 { "router-signature", K_ROUTER_SIGNATURE
},
293 { "published", K_PUBLISHED
},
294 { "running-routers", K_RUNNING_ROUTERS
},
295 { "platform", K_PLATFORM
},
299 #define MAX_ARGS 1024
300 struct directory_token
{
301 directory_keyword tp
;
304 char *args
[MAX_ARGS
+1];
309 crypto_pk_env_t
*public_key
;
313 /* Free any malloced resources allocated for a token. Don't call this if
314 you inherit the reference to those resources.
317 router_release_token(directory_token_t
*tok
)
322 free(tok
->val
.signature
);
325 crypto_free_pk_env(tok
->val
.public_key
);
333 _router_get_next_token(char **s
, directory_token_t
*tok
) {
335 crypto_pk_env_t
*pkey
= NULL
;
336 char *signature
= NULL
;
342 *s
= eat_whitespace(*s
);
346 } else if (**s
== '-') {
347 next
= strchr(*s
, '\n');
348 if (! next
) { tok
->val
.error
= "No newline at EOF"; return -1; }
350 if (! strncmp(*s
, OR_PUBLICKEY_BEGIN_TAG
, next
-*s
)) {
351 next
= strstr(*s
, OR_PUBLICKEY_END_TAG
);
352 if (!next
) { tok
->val
.error
= "No public key end tag found"; return -1; }
353 next
= strchr(next
, '\n'); /* Part of OR_PUBLICKEY_END_TAG; can't fail.*/
355 if (!(pkey
= crypto_new_pk_env(CRYPTO_PK_RSA
)))
357 if (crypto_pk_read_public_key_from_string(pkey
, *s
, next
-*s
)) {
358 crypto_free_pk_env(pkey
);
359 tok
->val
.error
= "Couldn't parse public key.";
362 tok
->tp
= _PUBLIC_KEY
;
363 tok
->val
.public_key
= pkey
;
366 } else if (! strncmp(*s
, OR_SIGNATURE_BEGIN_TAG
, next
-*s
)) {
367 /* Advance past newline; can't fail. */
368 *s
= strchr(*s
, '\n');
370 /* Find end of base64'd data */
371 next
= strstr(*s
, OR_SIGNATURE_END_TAG
);
372 if (!next
) { tok
->val
.error
= "No signature end tag found"; return -1; }
374 signature
= tor_malloc(256);
375 i
= base64_decode(signature
, 256, *s
, next
-*s
);
378 tok
->val
.error
= "Error decoding signature."; return -1;
379 } else if (i
!= 128) {
381 tok
->val
.error
= "Bad length on decoded signature."; return -1;
383 tok
->tp
= _SIGNATURE
;
384 tok
->val
.signature
= signature
;
386 next
= strchr(next
, '\n'); /* Part of OR_SIGNATURE_END_TAG; can't fail.*/
390 tok
->val
.error
= "Unrecognized begin line"; return -1;
393 next
= find_whitespace(*s
);
395 tok
->val
.error
= "Unexpected EOF"; return -1;
397 for (i
= 0 ; token_table
[i
].t
; ++i
) {
398 if (!strncmp(token_table
[i
].t
, *s
, next
-*s
)) {
399 tok
->tp
= token_table
[i
].v
;
401 done
= (*next
== '\n');
402 *s
= eat_whitespace_no_nl(next
);
403 while (**s
!= '\n' && i
<= MAX_ARGS
&& !done
) {
404 next
= find_whitespace(*s
);
408 tok
->val
.cmd
.args
[i
++] = *s
;
409 *s
= eat_whitespace_no_nl(next
+1);
411 tok
->val
.cmd
.n_args
= i
;
414 tok
->val
.error
= "Too many arguments"; return -1;
419 tok
->val
.error
= "Unrecognized command"; return -1;
423 #ifdef DEBUG_ROUTER_TOKENS
425 router_dump_token(directory_token_t
*tok
) {
433 puts("(public key)");
436 printf("(Error: %s\n)", tok
->val
.error
);
441 case K_ACCEPT
: printf("Accept"); break;
442 case K_DIRECTORY_SIGNATURE
: printf("Directory-Signature"); break;
443 case K_REJECT
: printf("Reject"); break;
444 case K_RECOMMENDED_SOFTWARE
: printf("Server-Software"); break;
445 case K_ROUTER
: printf("Router"); break;
446 case K_SIGNED_DIRECTORY
: printf("Signed-Directory"); break;
447 case K_SIGNING_KEY
: printf("Signing-Key"); break;
448 case K_ONION_KEY
: printf("Onion-key"); break;
449 case K_LINK_KEY
: printf("Link-key"); break;
450 case K_ROUTER_SIGNATURE
: printf("Router-signature"); break;
451 case K_PUBLISHED
: printf("Published"); break;
452 case K_RUNNING_ROUTERS
: printf("Running-routers"); break;
453 case K_PLATFORM
: printf("Platform"); break;
455 printf("?????? %d\n", tok
->tp
); return;
457 for (i
= 0; i
< tok
->val
.cmd
.n_args
; ++i
) {
458 printf(" \"%s\"", tok
->val
.cmd
.args
[i
]);
464 router_get_next_token(char **s
, directory_token_t
*tok
) {
466 i
= _router_get_next_token(s
, tok
);
467 router_dump_token(tok
);
471 #define router_get_next_token _router_get_next_token
474 /* read routerinfo elements from s, and throw out the ones that
475 * don't parse and resolve. */
476 int router_set_routerlist_from_string(char *s
)
478 if (router_get_list_from_string_impl(&s
, &routerlist
, -1, NULL
)) {
479 log(LOG_WARN
, "Error parsing router file");
482 if (router_resolve_routerlist(routerlist
)) {
483 log(LOG_WARN
, "Error resolving routerlist");
489 static int router_get_hash_impl(char *s
, char *digest
, const char *start_str
,
493 start
= strstr(s
, start_str
);
495 log_fn(LOG_WARN
,"couldn't find \"%s\"",start_str
);
498 end
= strstr(start
+strlen(start_str
), end_str
);
500 log_fn(LOG_WARN
,"couldn't find \"%s\"",end_str
);
503 end
= strchr(end
, '\n');
505 log_fn(LOG_WARN
,"couldn't find EOL");
510 if (crypto_SHA_digest(start
, end
-start
, digest
)) {
511 log_fn(LOG_WARN
,"couldn't compute digest");
518 int router_get_dir_hash(char *s
, char *digest
)
520 return router_get_hash_impl(s
,digest
,
521 "signed-directory","directory-signature");
523 int router_get_router_hash(char *s
, char *digest
)
525 return router_get_hash_impl(s
,digest
,
526 "router ","router-signature");
529 /* return 0 if myversion is in start. Else return -1. */
530 int compare_recommended_versions(char *myversion
, char *start
) {
531 int len_myversion
= strlen(myversion
);
533 char *end
= start
+ strlen(start
);
535 log_fn(LOG_DEBUG
,"checking '%s' in '%s'.", myversion
, start
);
538 comma
= strchr(start
, ',');
539 if( ((comma
? comma
: end
) - start
== len_myversion
) &&
540 !strncmp(start
, myversion
, len_myversion
))
541 /* only do strncmp if the length matches */
542 return 0; /* success, it's there */
544 return -1; /* nope */
549 int router_set_routerlist_from_directory(char *s
, crypto_pk_env_t
*pkey
)
551 if (router_get_routerlist_from_directory_impl(s
, &routerlist
, pkey
)) {
552 log_fn(LOG_WARN
, "Couldn't parse directory.");
555 if (router_resolve_routerlist(routerlist
)) {
556 log_fn(LOG_WARN
, "Error resolving routerlist");
559 if (compare_recommended_versions(VERSION
, routerlist
->software_versions
) < 0) {
560 log(options
.IgnoreVersion
? LOG_WARN
: LOG_ERR
,
561 "You are running Tor version %s, which is not recommended.\n"
562 "Please upgrade to one of %s.",
563 VERSION
, routerlist
->software_versions
);
564 if(options
.IgnoreVersion
) {
565 log(LOG_WARN
, "IgnoreVersion is set. If it breaks, we told you so.");
575 int router_get_routerlist_from_directory_impl(char *s
, routerlist_t
**dest
,
576 crypto_pk_env_t
*pkey
)
578 directory_token_t tok
;
580 char signed_digest
[128];
581 routerlist_t
*new_dir
= NULL
;
585 const char *good_nickname_lst
[1024];
586 int n_good_nicknames
;
590 if (router_get_next_token(&s, &tok)) { \
591 log_fn(LOG_WARN, "Error reading directory: %s", tok.val.error);\
594 #define TOK_IS(type,name) \
596 if (tok.tp != type) { \
597 router_release_token(&tok); \
598 log_fn(LOG_WARN, "Error reading directory: expected %s", name);\
602 if (router_get_dir_hash(s
, digest
)) {
603 log_fn(LOG_WARN
, "Unable to compute digest of directory");
606 log(LOG_DEBUG
,"Received directory hashes to %02x:%02x:%02x:%02x",
607 ((int)digest
[0])&0xff,((int)digest
[1])&0xff,
608 ((int)digest
[2])&0xff,((int)digest
[3])&0xff);
611 TOK_IS(K_SIGNED_DIRECTORY
, "signed-directory");
614 TOK_IS(K_PUBLISHED
, "published");
615 if (tok
.val
.cmd
.n_args
!= 2) {
616 log_fn(LOG_WARN
, "Invalid published line");
619 tok
.val
.cmd
.args
[1][-1] = ' ';
620 if (!strptime(tok
.val
.cmd
.args
[0], "%Y-%m-%d %H:%M:%S", &published
)) {
621 log_fn(LOG_WARN
, "Published time was unparseable"); goto err
;
623 published_on
= tor_timegm(&published
);
626 TOK_IS(K_RECOMMENDED_SOFTWARE
, "recommended-software");
627 if (tok
.val
.cmd
.n_args
!= 1) {
628 log_fn(LOG_WARN
, "Invalid recommended-software line");
631 versions
= tor_strdup(tok
.val
.cmd
.args
[0]);
634 TOK_IS(K_RUNNING_ROUTERS
, "running-routers");
635 n_good_nicknames
= tok
.val
.cmd
.n_args
;
636 memcpy(good_nickname_lst
, tok
.val
.cmd
.args
, n_good_nicknames
*sizeof(char *));
638 if (router_get_list_from_string_impl(&s
, &new_dir
,
639 n_good_nicknames
, good_nickname_lst
)) {
640 log_fn(LOG_WARN
, "Error reading routers from directory");
643 new_dir
->software_versions
= versions
;
644 new_dir
->published_on
= published_on
;
647 TOK_IS(K_DIRECTORY_SIGNATURE
, "directory-signature");
649 TOK_IS(_SIGNATURE
, "signature");
651 if (crypto_pk_public_checksig(pkey
, tok
.val
.signature
, 128, signed_digest
)
653 log_fn(LOG_WARN
, "Error reading directory: invalid signature.");
654 free(tok
.val
.signature
);
657 log(LOG_DEBUG
,"Signed directory hash starts %02x:%02x:%02x:%02x",
658 ((int)signed_digest
[0])&0xff,((int)signed_digest
[1])&0xff,
659 ((int)signed_digest
[2])&0xff,((int)signed_digest
[3])&0xff);
660 if (memcmp(digest
, signed_digest
, 20)) {
661 log_fn(LOG_WARN
, "Error reading directory: signature does not match.");
662 free(tok
.val
.signature
);
666 free(tok
.val
.signature
);
669 TOK_IS(_EOF
, "end of directory");
672 routerlist_free(*dest
);
679 routerlist_free(new_dir
);
685 int router_get_list_from_string_impl(char **s
, routerlist_t
**dest
,
686 int n_good_nicknames
,
687 const char **good_nickname_lst
)
689 routerinfo_t
*router
;
690 routerinfo_t
**rarray
;
696 rarray
= (routerinfo_t
**)tor_malloc((sizeof(routerinfo_t
*))*MAX_ROUTERS_IN_DIR
);
699 *s
= eat_whitespace(*s
);
700 if (strncmp(*s
, "router ", 7)!=0)
702 router
= router_get_entry_from_string(s
);
704 log_fn(LOG_WARN
, "Error reading router");
705 for(i
=0;i
<rarray_len
;i
++)
706 routerinfo_free(rarray
[i
]);
710 if (rarray_len
>= MAX_ROUTERS_IN_DIR
) {
711 log_fn(LOG_WARN
, "too many routers");
712 routerinfo_free(router
);
715 if (n_good_nicknames
>=0) {
716 router
->is_running
= 0;
717 for (i
= 0; i
< n_good_nicknames
; ++i
) {
718 if (0==strcasecmp(good_nickname_lst
[i
], router
->nickname
)) {
719 router
->is_running
= 1;
724 router
->is_running
= 1; /* start out assuming all dirservers are up */
726 rarray
[rarray_len
++] = router
;
727 log_fn(LOG_DEBUG
,"just added router #%d.",rarray_len
);
731 routerlist_free(*dest
);
732 *dest
= (routerlist_t
*)tor_malloc(sizeof(routerlist_t
));
733 (*dest
)->routers
= rarray
;
734 (*dest
)->n_routers
= rarray_len
;
735 (*dest
)->software_versions
= NULL
;
740 router_resolve(routerinfo_t
*router
)
742 struct hostent
*rent
;
744 rent
= (struct hostent
*)gethostbyname(router
->address
);
746 log_fn(LOG_WARN
,"Could not get address for router %s.",router
->address
);
749 assert(rent
->h_length
== 4);
750 memcpy(&router
->addr
, rent
->h_addr
,rent
->h_length
);
751 router
->addr
= ntohl(router
->addr
); /* get it back into host order */
757 router_resolve_routerlist(routerlist_t
*rl
)
764 for (i
= 0; i
< max
; ++i
) {
766 if (router_resolve(rl
->routers
[i
])) {
767 log_fn(LOG_WARN
, "Couldn't resolve router %s; not using",
768 rl
->routers
[i
]->address
);
770 } else if (options
.Nickname
&&
771 !strcmp(rl
->routers
[i
]->nickname
, options
.Nickname
)) {
775 routerinfo_free(rl
->routers
[i
]);
776 rl
->routers
[i
] = rl
->routers
[--max
];
785 /* reads a single router entry from s.
786 * updates s so it points to after the router it just read.
787 * mallocs a new router and returns it if all goes well, else returns NULL.
789 routerinfo_t
*router_get_entry_from_string(char**s
) {
790 routerinfo_t
*router
= NULL
;
791 char signed_digest
[128];
793 directory_token_t _tok
;
794 directory_token_t
*tok
= &_tok
;
798 #define NEXT_TOKEN() \
799 do { if (router_get_next_token(s, tok)) { \
800 log_fn(LOG_WARN, "Error reading directory: %s", tok->val.error);\
804 #define ARGS tok->val.cmd.args
806 if (router_get_router_hash(*s
, digest
) < 0) {
807 log_fn(LOG_WARN
, "Couldn't compute router hash.");
813 if (tok
->tp
!= K_ROUTER
) {
814 router_release_token(tok
);
815 log_fn(LOG_WARN
,"Entry does not start with \"router\"");
819 router
= tor_malloc_zero(sizeof(routerinfo_t
));
820 router
->onion_pkey
= router
->identity_pkey
= router
->link_pkey
= NULL
;
822 if (tok
->val
.cmd
.n_args
!= 6) {
823 log_fn(LOG_WARN
,"Wrong # of arguments to \"router\"");
826 router
->nickname
= tor_strdup(ARGS
[0]);
827 if (strlen(router
->nickname
) > MAX_NICKNAME_LEN
) {
828 log_fn(LOG_WARN
,"Router nickname too long.");
831 if (strspn(router
->nickname
, LEGAL_NICKNAME_CHARACTERS
) !=
832 strlen(router
->nickname
)) {
833 log_fn(LOG_WARN
, "Router nickname contains illegal characters.");
837 /* read router.address */
838 router
->address
= tor_strdup(ARGS
[1]);
841 /* Read router->or_port */
842 router
->or_port
= atoi(ARGS
[2]);
843 if(!router
->or_port
) {
844 log_fn(LOG_WARN
,"or_port unreadable or 0. Failing.");
848 /* Router->socks_port */
849 router
->socks_port
= atoi(ARGS
[3]);
851 /* Router->dir_port */
852 router
->dir_port
= atoi(ARGS
[4]);
854 /* Router->bandwidth */
855 router
->bandwidth
= atoi(ARGS
[5]);
856 if (!router
->bandwidth
) {
857 log_fn(LOG_WARN
,"bandwidth unreadable or 0. Failing.");
861 log_fn(LOG_DEBUG
,"or_port %d, socks_port %d, dir_port %d, bandwidth %d.",
862 router
->or_port
, router
->socks_port
, router
->dir_port
, router
->bandwidth
);
864 /* XXX Later, require platform before published. */
866 if (tok
->tp
== K_PLATFORM
) {
870 if (tok
->tp
!= K_PUBLISHED
) {
871 log_fn(LOG_WARN
, "Missing published time"); goto err
;
873 if (tok
->val
.cmd
.n_args
!= 2) {
874 log_fn(LOG_WARN
, "Wrong number of arguments to published"); goto err
;
876 ARGS
[1][-1] = ' '; /* Re-insert space. */
877 if (!strptime(ARGS
[0], "%Y-%m-%d %H:%M:%S", &published
)) {
878 log_fn(LOG_WARN
, "Published time was unparseable"); goto err
;
880 router
->published_on
= tor_timegm(&published
);
883 if (tok
->tp
!= K_ONION_KEY
) {
884 log_fn(LOG_WARN
, "Missing onion-key"); goto err
;
887 if (tok
->tp
!= _PUBLIC_KEY
) {
888 log_fn(LOG_WARN
, "Missing onion key"); goto err
;
889 } /* XXX Check key length */
890 router
->onion_pkey
= tok
->val
.public_key
;
893 if (tok
->tp
!= K_LINK_KEY
) {
894 log_fn(LOG_WARN
, "Missing link-key"); goto err
;
897 if (tok
->tp
!= _PUBLIC_KEY
) {
898 log_fn(LOG_WARN
, "Missing link key"); goto err
;
899 } /* XXX Check key length */
900 router
->link_pkey
= tok
->val
.public_key
;
903 if (tok
->tp
!= K_SIGNING_KEY
) {
904 log_fn(LOG_WARN
, "Missing signing-key"); goto err
;
907 if (tok
->tp
!= _PUBLIC_KEY
) {
908 log_fn(LOG_WARN
, "Missing signing key"); goto err
;
910 router
->identity_pkey
= tok
->val
.public_key
;
913 while (tok
->tp
== K_ACCEPT
|| tok
->tp
== K_REJECT
) {
914 router_add_exit_policy(router
, tok
);
918 if (tok
->tp
!= K_ROUTER_SIGNATURE
) {
919 log_fn(LOG_WARN
,"Missing router signature");
923 if (tok
->tp
!= _SIGNATURE
) {
924 log_fn(LOG_WARN
,"Missing router signature");
927 assert (router
->identity_pkey
);
929 if ((t
=crypto_pk_public_checksig(router
->identity_pkey
, tok
->val
.signature
,
930 128, signed_digest
)) != 20) {
931 log_fn(LOG_WARN
, "Invalid signature %d",t
);
934 if (memcmp(digest
, signed_digest
, 20)) {
935 log_fn(LOG_WARN
, "Mismatched signature");
939 router_release_token(tok
); /* free the signature */
943 router_release_token(tok
);
944 routerinfo_free(router
);
950 void router_add_exit_policy_from_config(routerinfo_t
*router
) {
951 char *s
= options
.ExitPolicy
, *e
;
956 log_fn(LOG_INFO
,"No exit policy configured. Ok.");
957 return; /* nothing to see here */
960 log_fn(LOG_INFO
,"Exit policy is empty. Ok.");
961 return; /* nothing to see here */
968 strncpy(line
,s
,1023);
970 memcpy(line
,s
, ((e
-s
)<1023)?(e
-s
):1023);
974 log_fn(LOG_DEBUG
,"Adding new entry '%s'",line
);
975 if(router_add_exit_policy_from_string(router
,line
) < 0)
976 log_fn(LOG_WARN
,"Malformed exit policy %s; skipping.", line
);
984 router_add_exit_policy_from_string(routerinfo_t
*router
,
987 directory_token_t tok
;
993 tmp
= cp
= tor_malloc(len
+2);
994 for (idx
= 0; idx
< len
; ++idx
) {
995 tmp
[idx
] = tolower(s
[idx
]);
999 if (router_get_next_token(&cp
, &tok
)) {
1000 log_fn(LOG_WARN
, "Error reading exit policy: %s", tok
.val
.error
);
1004 if (tok
.tp
!= K_ACCEPT
&& tok
.tp
!= K_REJECT
) {
1005 log_fn(LOG_WARN
, "Expected 'accept' or 'reject'.");
1009 r
= router_add_exit_policy(router
, &tok
);
1014 static int router_add_exit_policy(routerinfo_t
*router
,
1015 directory_token_t
*tok
) {
1016 struct exit_policy_t
*tmpe
, *newe
;
1018 char *arg
, *address
, *mask
, *port
, *endptr
;
1021 if (tok
->val
.cmd
.n_args
!= 1)
1023 arg
= tok
->val
.cmd
.args
[0];
1025 newe
= tor_malloc_zero(sizeof(struct exit_policy_t
));
1027 newe
->string
= tor_malloc(8+strlen(arg
));
1028 if (tok
->tp
== K_REJECT
) {
1029 strcpy(newe
->string
, "reject ");
1030 newe
->policy_type
= EXIT_POLICY_REJECT
;
1032 assert(tok
->tp
== K_ACCEPT
);
1033 strcpy(newe
->string
, "accept ");
1034 newe
->policy_type
= EXIT_POLICY_ACCEPT
;
1036 strcat(newe
->string
, arg
);
1039 mask
= strchr(arg
,'/');
1040 port
= strchr(mask
?mask
:arg
,':');
1042 goto policy_read_failed
;
1047 if (strcmp(address
, "*") == 0) {
1049 } else if (inet_aton(address
, &in
) != 0) {
1050 newe
->addr
= ntohl(in
.s_addr
);
1052 log_fn(LOG_WARN
, "Malformed IP %s in exit policy; rejecting.",
1054 goto policy_read_failed
;
1057 if (strcmp(address
, "*") == 0)
1060 newe
->msk
= 0xFFFFFFFFu
;
1063 bits
= (int) strtol(mask
, &endptr
, 10);
1065 /* strtol handled the whole mask. */
1066 newe
->msk
= ~((1<<(32-bits
))-1);
1067 } else if (inet_aton(mask
, &in
) != 0) {
1068 newe
->msk
= ntohl(in
.s_addr
);
1070 log_fn(LOG_WARN
, "Malformed mask %s on exit policy; rejecting.",
1072 goto policy_read_failed
;
1075 if (strcmp(port
, "*") == 0) {
1079 newe
->prt
= strtol(port
, &endptr
, 10);
1081 log_fn(LOG_WARN
, "Malformed port %s on exit policy; rejecting.",
1083 goto policy_read_failed
;
1087 in
.s_addr
= htonl(newe
->addr
);
1088 address
= tor_strdup(inet_ntoa(in
));
1089 in
.s_addr
= htonl(newe
->msk
);
1090 log_fn(LOG_DEBUG
,"%s %s/%s:%d",
1091 newe
->policy_type
== EXIT_POLICY_REJECT
? "reject" : "accept",
1092 address
, inet_ntoa(in
), newe
->prt
);
1095 /* now link newe onto the end of exit_policy */
1097 if(!router
->exit_policy
) {
1098 router
->exit_policy
= newe
;
1102 for(tmpe
=router
->exit_policy
; tmpe
->next
; tmpe
=tmpe
->next
) ;
1108 assert(newe
->string
);
1109 log_fn(LOG_WARN
,"Couldn't parse line '%s'. Dropping", newe
->string
);
1110 tor_free(newe
->string
);
1115 /* Addr is 0 for "IP unknown".
1117 * Returns -1 for 'rejected', 0 for accepted, 1 for 'maybe' (since IP is
1120 int router_supports_exit_address(uint32_t addr
, uint16_t port
,
1121 routerinfo_t
*router
)
1123 return router_compare_addr_to_exit_policy(addr
, port
, router
->exit_policy
);
1126 /* Addr is 0 for "IP unknown".
1128 * Returns -1 for 'rejected', 0 for accepted, 1 for 'maybe' (since IP is
1131 int router_compare_addr_to_exit_policy(uint32_t addr
, uint16_t port
,
1132 struct exit_policy_t
*policy
)
1134 int maybe_reject
= 0;
1137 struct exit_policy_t
*tmpe
;
1139 for(tmpe
=policy
; tmpe
; tmpe
=tmpe
->next
) {
1140 log_fn(LOG_DEBUG
,"Considering exit policy %s", tmpe
->string
);
1142 /* Address is unknown. */
1143 if (tmpe
->msk
== 0 && (!tmpe
|| port
== tmpe
->prt
)) {
1144 /* The exit policy is accept/reject *:port */
1146 } else if ((!tmpe
->prt
|| port
== tmpe
->prt
) &&
1147 tmpe
->policy_type
== EXIT_POLICY_REJECT
) {
1148 /* The exit policy is reject ???:port */
1152 /* Address is known */
1153 if ( (addr
& tmpe
->msk
) == (tmpe
->addr
& tmpe
->msk
) &&
1154 (!tmpe
->prt
|| port
== tmpe
->prt
) ) {
1155 /* Exact match for the policy */
1160 in
.s_addr
= htonl(addr
);
1161 log_fn(LOG_INFO
,"Address %s:%d matches exit policy '%s'",
1162 inet_ntoa(in
), port
, tmpe
->string
);
1163 if(tmpe
->policy_type
== EXIT_POLICY_ACCEPT
)
1172 return 0; /* accept all by default. */
1175 /* Return 0 if my exit policy says to allow connection to conn.
1178 int router_compare_to_my_exit_policy(connection_t
*conn
) {
1179 assert(desc_routerinfo
);
1180 assert(conn
->addr
); /* make sure it's resolved to something. this
1181 way we can't get a 'maybe' below. */
1183 if (router_compare_addr_to_exit_policy(conn
->addr
, conn
->port
,
1184 desc_routerinfo
->exit_policy
) == 0)
1190 /* return 1 if all running routers will reject addr:port, return 0 if
1191 any might accept it. */
1192 int router_exit_policy_all_routers_reject(uint32_t addr
, uint16_t port
) {
1194 routerinfo_t
*router
;
1196 for (i
=0;i
<routerlist
->n_routers
;i
++) {
1197 router
= routerlist
->routers
[i
];
1198 if (router
->is_running
&& router_compare_addr_to_exit_policy(addr
,
1199 port
, router
->exit_policy
) >= 0)
1200 return 0; /* this one could be ok. good enough. */
1202 return 1; /* all will reject. */
1205 int router_exit_policy_rejects_all(routerinfo_t
*router
) {
1206 if (router_compare_addr_to_exit_policy(0, 0, router
->exit_policy
) < 0)
1207 return 1; /* yes, rejects all */
1209 return 0; /* no, might accept some */
1212 const char *router_get_my_descriptor(void) {
1213 if (!desc_routerinfo
) {
1214 if (router_rebuild_descriptor())
1217 log_fn(LOG_DEBUG
,"my desc is '%s'",descriptor
);
1221 int router_rebuild_descriptor(void) {
1223 char localhostname
[256];
1224 char *address
= options
.Address
;
1226 if(!address
) { /* if not specified in config, we find a default */
1227 if(gethostname(localhostname
,sizeof(localhostname
)) < 0) {
1228 log_fn(LOG_WARN
,"Error obtaining local hostname");
1231 address
= localhostname
;
1232 if(!strchr(address
,'.')) {
1233 log_fn(LOG_WARN
,"fqdn '%s' has only one element. Misconfigured machine?",address
);
1234 log_fn(LOG_WARN
,"Try setting the Address line in your config file.");
1238 ri
= tor_malloc(sizeof(routerinfo_t
));
1239 ri
->address
= tor_strdup(address
);
1240 ri
->nickname
= tor_strdup(options
.Nickname
);
1241 /* No need to set addr. */
1242 ri
->or_port
= options
.ORPort
;
1243 ri
->socks_port
= options
.SocksPort
;
1244 ri
->dir_port
= options
.DirPort
;
1245 ri
->published_on
= time(NULL
);
1246 ri
->onion_pkey
= crypto_pk_dup_key(get_onion_key());
1247 ri
->link_pkey
= crypto_pk_dup_key(get_link_key());
1248 ri
->identity_pkey
= crypto_pk_dup_key(get_identity_key());
1249 ri
->bandwidth
= options
.TotalBandwidth
;
1250 ri
->exit_policy
= NULL
; /* zero it out first */
1251 router_add_exit_policy_from_config(ri
);
1252 if (desc_routerinfo
)
1253 routerinfo_free(desc_routerinfo
);
1254 desc_routerinfo
= ri
;
1255 if (router_dump_router_to_string(descriptor
, 8192, ri
, get_identity_key())<0) {
1256 log_fn(LOG_WARN
, "Couldn't dump router to string.");
1262 static void get_platform_str(char *platform
, int len
)
1264 snprintf(platform
, len
-1, "Tor %s on %s", VERSION
, get_uname());
1265 platform
[len
-1] = '\0';
1269 /* XXX need to audit this thing and count fenceposts. maybe
1270 * refactor so we don't have to keep asking if we're
1271 * near the end of maxlen?
1273 #define DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
1274 int router_dump_router_to_string(char *s
, int maxlen
, routerinfo_t
*router
,
1275 crypto_pk_env_t
*ident_key
) {
1278 char *identity_pkey
;
1282 char signature
[128];
1284 int onion_pkeylen
, link_pkeylen
, identity_pkeylen
;
1287 struct exit_policy_t
*tmpe
;
1288 #ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
1289 char *s_tmp
, *s_dup
;
1290 routerinfo_t
*ri_tmp
;
1293 get_platform_str(platform
, sizeof(platform
));
1295 if (crypto_pk_cmp_keys(ident_key
, router
->identity_pkey
)) {
1296 log_fn(LOG_WARN
,"Tried to sign a router with a private key that didn't match router's public key!");
1300 if(crypto_pk_write_public_key_to_string(router
->onion_pkey
,
1301 &onion_pkey
,&onion_pkeylen
)<0) {
1302 log_fn(LOG_WARN
,"write onion_pkey to string failed!");
1306 if(crypto_pk_write_public_key_to_string(router
->identity_pkey
,
1307 &identity_pkey
,&identity_pkeylen
)<0) {
1308 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
1312 if(crypto_pk_write_public_key_to_string(router
->link_pkey
,
1313 &link_pkey
,&link_pkeylen
)<0) {
1314 log_fn(LOG_WARN
,"write link_pkey to string failed!");
1317 strftime(published
, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router
->published_on
));
1319 result
= snprintf(s
, maxlen
,
1320 "router %s %s %d %d %d %d\n"
1334 onion_pkey
, link_pkey
, identity_pkey
);
1338 free(identity_pkey
);
1340 if(result
< 0 || result
>= maxlen
) {
1341 /* apparently different glibcs do different things on snprintf error.. so check both */
1346 for(tmpe
=router
->exit_policy
; tmpe
; tmpe
=tmpe
->next
) {
1347 in
.s_addr
= htonl(tmpe
->addr
);
1348 result
= snprintf(s
+written
, maxlen
-written
, "%s %s",
1349 tmpe
->policy_type
== EXIT_POLICY_ACCEPT
? "accept" : "reject",
1350 tmpe
->msk
== 0 ? "*" : inet_ntoa(in
));
1351 if(result
< 0 || result
+written
> maxlen
) {
1352 /* apparently different glibcs do different things on snprintf error.. so check both */
1356 if (tmpe
->msk
!= 0xFFFFFFFFu
&& tmpe
->msk
!= 0) {
1357 in
.s_addr
= htonl(tmpe
->msk
);
1358 result
= snprintf(s
+written
, maxlen
-written
, "/%s", inet_ntoa(in
));
1359 if (result
<0 || result
+written
> maxlen
)
1364 result
= snprintf(s
+written
, maxlen
-written
, ":%d\n", tmpe
->prt
);
1365 if (result
<0 || result
+written
> maxlen
)
1369 if (written
> maxlen
-4)
1371 strcat(s
+written
, ":*\n");
1375 if (written
> maxlen
-256) /* Not enough room for signature. */
1378 strcat(s
+written
, "router-signature\n");
1379 written
+= strlen(s
+written
);
1381 if (router_get_router_hash(s
, digest
) < 0)
1384 if (crypto_pk_private_sign(ident_key
, digest
, 20, signature
) < 0) {
1385 log_fn(LOG_WARN
, "Error signing digest");
1388 strcat(s
+written
, "-----BEGIN SIGNATURE-----\n");
1389 written
+= strlen(s
+written
);
1390 if (base64_encode(s
+written
, maxlen
-written
, signature
, 128) < 0) {
1391 log_fn(LOG_WARN
, "Couldn't base64-encode signature");
1394 written
+= strlen(s
+written
);
1395 strcat(s
+written
, "-----END SIGNATURE-----\n");
1396 written
+= strlen(s
+written
);
1398 if (written
> maxlen
-2)
1400 /* include a last '\n' */
1404 #ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
1405 s_tmp
= s_dup
= tor_strdup(s
);
1406 ri_tmp
= router_get_entry_from_string(&s_tmp
);
1408 log_fn(LOG_ERR
, "We just generated a router descriptor we can't parse: <<%s>>",
1413 routerinfo_free(ri_tmp
);
1422 indent-tabs-mode:nil