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 directory_t
*directory
= 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 void routerlist_free(routerinfo_t
*list
);
32 static int router_add_exit_policy_from_string(routerinfo_t
*router
, char *s
);
33 static int router_add_exit_policy(routerinfo_t
*router
,
34 directory_token_t
*tok
);
35 static int router_resolve_directory(directory_t
*dir
);
37 /****************************************************************************/
39 void router_retry_connections(void) {
43 for (i
=0;i
<directory
->n_routers
;i
++) {
44 router
= directory
->routers
[i
];
45 if(!connection_exact_get_by_addr_port(router
->addr
,router
->or_port
)) { /* not in the list */
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 the first running router with a positive dir_port */
55 routerinfo_t
*router
, *dirserver
=NULL
;
60 for(i
=0;i
<directory
->n_routers
;i
++) {
61 router
= directory
->routers
[i
];
62 if(router
->dir_port
> 0 && router
->is_running
)
66 log_fn(LOG_INFO
,"No dirservers are reachable. Trying them all again.");
67 /* no running dir servers found? go through and mark them all as up,
68 * and we'll cycle through the list again. */
69 for(i
=0;i
<directory
->n_routers
;i
++) {
70 router
= directory
->routers
[i
];
71 if(router
->dir_port
> 0) {
72 router
->is_running
= 1;
80 void router_upload_desc_to_dirservers(void) {
87 if (!router_get_my_descriptor()) {
88 log_fn(LOG_WARN
, "No descriptor; skipping upload");
92 for(i
=0;i
<directory
->n_routers
;i
++) {
93 router
= directory
->routers
[i
];
94 if(router
->dir_port
> 0)
95 directory_initiate_command(router
, DIR_CONN_STATE_CONNECTING_UPLOAD
);
99 routerinfo_t
*router_get_by_addr_port(uint32_t addr
, uint16_t port
) {
101 routerinfo_t
*router
;
105 for(i
=0;i
<directory
->n_routers
;i
++) {
106 router
= directory
->routers
[i
];
107 if ((router
->addr
== addr
) && (router
->or_port
== port
))
113 routerinfo_t
*router_get_by_link_pk(crypto_pk_env_t
*pk
)
116 routerinfo_t
*router
;
120 for(i
=0;i
<directory
->n_routers
;i
++) {
121 router
= directory
->routers
[i
];
122 if (0 == crypto_pk_cmp_keys(router
->link_pkey
, pk
))
128 routerinfo_t
*router_get_by_nickname(char *nickname
)
131 routerinfo_t
*router
;
135 for(i
=0;i
<directory
->n_routers
;i
++) {
136 router
= directory
->routers
[i
];
137 if (0 == strcmp(router
->nickname
, nickname
))
143 void router_get_directory(directory_t
**pdirectory
) {
144 *pdirectory
= directory
;
147 /* delete a router from memory */
148 void routerinfo_free(routerinfo_t
*router
)
150 struct exit_policy_t
*e
;
155 tor_free(router
->address
);
156 tor_free(router
->nickname
);
157 if (router
->onion_pkey
)
158 crypto_free_pk_env(router
->onion_pkey
);
159 if (router
->link_pkey
)
160 crypto_free_pk_env(router
->link_pkey
);
161 if (router
->identity_pkey
)
162 crypto_free_pk_env(router
->identity_pkey
);
163 while (router
->exit_policy
) {
164 e
= router
->exit_policy
;
165 router
->exit_policy
= e
->next
;
172 void directory_free(directory_t
*dir
)
175 for (i
= 0; i
< dir
->n_routers
; ++i
)
176 routerinfo_free(dir
->routers
[i
]);
177 tor_free(dir
->routers
);
178 tor_free(dir
->software_versions
);
182 void router_mark_as_down(char *nickname
) {
183 routerinfo_t
*router
= router_get_by_nickname(nickname
);
184 if(!router
) /* we don't seem to know about him in the first place */
186 log_fn(LOG_DEBUG
,"Marking %s as down.",router
->nickname
);
187 router
->is_running
= 0;
190 /* load the router list */
191 int router_get_list_from_file(char *routerfile
)
195 string
= read_file_to_str(routerfile
);
197 log_fn(LOG_WARN
,"Failed to load routerfile %s.",routerfile
);
201 if(router_get_list_from_string(string
) < 0) {
202 log_fn(LOG_WARN
,"The routerfile itself was corrupt.");
214 K_DIRECTORY_SIGNATURE
,
215 K_RECOMMENDED_SOFTWARE
,
232 struct token_table_ent
{ char *t
; int v
; };
234 static struct token_table_ent token_table
[] = {
235 { "accept", K_ACCEPT
},
236 { "directory-signature", K_DIRECTORY_SIGNATURE
},
237 { "reject", K_REJECT
},
238 { "router", K_ROUTER
},
239 { "recommended-software", K_RECOMMENDED_SOFTWARE
},
240 { "signed-directory", K_SIGNED_DIRECTORY
},
241 { "signing-key", K_SIGNING_KEY
},
242 { "onion-key", K_ONION_KEY
},
243 { "link-key", K_LINK_KEY
},
244 { "router-signature", K_ROUTER_SIGNATURE
},
245 { "published", K_PUBLISHED
},
246 { "running-routers", K_RUNNING_ROUTERS
},
247 { "platform", K_PLATFORM
},
251 #define MAX_ARGS 1024
252 struct directory_token
{
253 directory_keyword tp
;
256 char *args
[MAX_ARGS
+1];
261 crypto_pk_env_t
*public_key
;
265 /* Free any malloced resources allocated for a token. Don't call this if
266 you inherit the reference to those resources.
269 router_release_token(directory_token_t
*tok
)
274 free(tok
->val
.signature
);
277 crypto_free_pk_env(tok
->val
.public_key
);
285 _router_get_next_token(char **s
, directory_token_t
*tok
) {
287 crypto_pk_env_t
*pkey
= NULL
;
288 char *signature
= NULL
;
294 *s
= eat_whitespace(*s
);
298 } else if (**s
== '-') {
299 next
= strchr(*s
, '\n');
300 if (! next
) { tok
->val
.error
= "No newline at EOF"; return -1; }
302 if (! strncmp(*s
, OR_PUBLICKEY_BEGIN_TAG
, next
-*s
)) {
303 next
= strstr(*s
, OR_PUBLICKEY_END_TAG
);
304 if (!next
) { tok
->val
.error
= "No public key end tag found"; return -1; }
305 next
= strchr(next
, '\n'); /* Part of OR_PUBLICKEY_END_TAG; can't fail.*/
307 if (!(pkey
= crypto_new_pk_env(CRYPTO_PK_RSA
)))
309 if (crypto_pk_read_public_key_from_string(pkey
, *s
, next
-*s
)) {
310 crypto_free_pk_env(pkey
);
311 tok
->val
.error
= "Couldn't parse public key.";
314 tok
->tp
= _PUBLIC_KEY
;
315 tok
->val
.public_key
= pkey
;
318 } else if (! strncmp(*s
, OR_SIGNATURE_BEGIN_TAG
, next
-*s
)) {
319 /* Advance past newline; can't fail. */
320 *s
= strchr(*s
, '\n');
322 /* Find end of base64'd data */
323 next
= strstr(*s
, OR_SIGNATURE_END_TAG
);
324 if (!next
) { tok
->val
.error
= "No signature end tag found"; return -1; }
326 signature
= tor_malloc(256);
327 i
= base64_decode(signature
, 256, *s
, next
-*s
);
330 tok
->val
.error
= "Error decoding signature."; return -1;
331 } else if (i
!= 128) {
333 tok
->val
.error
= "Bad length on decoded signature."; return -1;
335 tok
->tp
= _SIGNATURE
;
336 tok
->val
.signature
= signature
;
338 next
= strchr(next
, '\n'); /* Part of OR_SIGNATURE_END_TAG; can't fail.*/
342 tok
->val
.error
= "Unrecognized begin line"; return -1;
345 next
= find_whitespace(*s
);
347 tok
->val
.error
= "Unexpected EOF"; return -1;
349 for (i
= 0 ; token_table
[i
].t
; ++i
) {
350 if (!strncmp(token_table
[i
].t
, *s
, next
-*s
)) {
351 tok
->tp
= token_table
[i
].v
;
353 done
= (*next
== '\n');
354 *s
= eat_whitespace_no_nl(next
);
355 while (**s
!= '\n' && i
<= MAX_ARGS
&& !done
) {
356 next
= find_whitespace(*s
);
360 tok
->val
.cmd
.args
[i
++] = *s
;
361 *s
= eat_whitespace_no_nl(next
+1);
363 tok
->val
.cmd
.n_args
= i
;
366 tok
->val
.error
= "Too many arguments"; return -1;
371 tok
->val
.error
= "Unrecognized command"; return -1;
375 #ifdef DEBUG_ROUTER_TOKENS
377 router_dump_token(directory_token_t
*tok
) {
385 puts("(public key)");
388 printf("(Error: %s\n)", tok
->val
.error
);
393 case K_ACCEPT
: printf("Accept"); break;
394 case K_DIRECTORY_SIGNATURE
: printf("Directory-Signature"); break;
395 case K_REJECT
: printf("Reject"); break;
396 case K_RECOMMENDED_SOFTWARE
: printf("Server-Software"); break;
397 case K_ROUTER
: printf("Router"); break;
398 case K_SIGNED_DIRECTORY
: printf("Signed-Directory"); break;
399 case K_SIGNING_KEY
: printf("Signing-Key"); break;
400 case K_ONION_KEY
: printf("Onion-key"); break;
401 case K_LINK_KEY
: printf("Link-key"); break;
402 case K_ROUTER_SIGNATURE
: printf("Router-signature"); break;
403 case K_PUBLISHED
: printf("Published"); break;
404 case K_RUNNING_ROUTERS
: printf("Running-routers"); break;
405 case K_PLATFORM
: printf("Platform"); break;
407 printf("?????? %d\n", tok
->tp
); return;
409 for (i
= 0; i
< tok
->val
.cmd
.n_args
; ++i
) {
410 printf(" \"%s\"", tok
->val
.cmd
.args
[i
]);
416 router_get_next_token(char **s
, directory_token_t
*tok
) {
418 i
= _router_get_next_token(s
, tok
);
419 router_dump_token(tok
);
423 #define router_get_next_token _router_get_next_token
426 int router_get_list_from_string(char *s
)
428 if (router_get_list_from_string_impl(&s
, &directory
, -1, NULL
)) {
429 log(LOG_WARN
, "Error parsing router file");
432 if (router_resolve_directory(directory
)) {
433 log(LOG_WARN
, "Error resolving directory");
439 static int router_get_hash_impl(char *s
, char *digest
, const char *start_str
,
443 start
= strstr(s
, start_str
);
445 log_fn(LOG_WARN
,"couldn't find \"%s\"",start_str
);
448 end
= strstr(start
+strlen(start_str
), end_str
);
450 log_fn(LOG_WARN
,"couldn't find \"%s\"",end_str
);
453 end
= strchr(end
, '\n');
455 log_fn(LOG_WARN
,"couldn't find EOL");
460 if (crypto_SHA_digest(start
, end
-start
, digest
)) {
461 log_fn(LOG_WARN
,"couldn't compute digest");
468 int router_get_dir_hash(char *s
, char *digest
)
470 return router_get_hash_impl(s
,digest
,
471 "signed-directory","directory-signature");
473 int router_get_router_hash(char *s
, char *digest
)
475 return router_get_hash_impl(s
,digest
,
476 "router ","router-signature");
479 /* return 0 if myversion is in start. Else return -1. */
480 int compare_recommended_versions(char *myversion
, char *start
) {
481 int len_myversion
= strlen(myversion
);
483 char *end
= start
+ strlen(start
);
485 log_fn(LOG_DEBUG
,"checking '%s' in '%s'.", myversion
, start
);
488 comma
= strchr(start
, ',');
489 if( ((comma
? comma
: end
) - start
== len_myversion
) &&
490 !strncmp(start
, myversion
, len_myversion
)) /* only do strncmp if the length matches */
491 return 0; /* success, it's there */
493 return -1; /* nope */
498 int router_get_dir_from_string(char *s
, crypto_pk_env_t
*pkey
)
500 if (router_get_dir_from_string_impl(s
, &directory
, pkey
)) {
501 log_fn(LOG_WARN
, "Couldn't parse directory.");
504 if (router_resolve_directory(directory
)) {
505 log_fn(LOG_WARN
, "Error resolving directory");
508 if (compare_recommended_versions(VERSION
, directory
->software_versions
) < 0) {
509 log(options
.IgnoreVersion
? LOG_WARN
: LOG_ERR
,
510 "You are running Tor version %s, which is not recommended.\n"
511 "Please upgrade to one of %s.",
512 VERSION
, directory
->software_versions
);
513 if(options
.IgnoreVersion
) {
514 log(LOG_WARN
, "IgnoreVersion is set. If it breaks, we told you so.");
524 int router_get_dir_from_string_impl(char *s
, directory_t
**dest
,
525 crypto_pk_env_t
*pkey
)
527 directory_token_t tok
;
529 char signed_digest
[128];
530 directory_t
*new_dir
= NULL
;
534 const char *good_nickname_lst
[1024];
535 int n_good_nicknames
;
539 if (router_get_next_token(&s, &tok)) { \
540 log_fn(LOG_WARN, "Error reading directory: %s", tok.val.error);\
543 #define TOK_IS(type,name) \
545 if (tok.tp != type) { \
546 router_release_token(&tok); \
547 log_fn(LOG_WARN, "Error reading directory: expected %s", name);\
551 if (router_get_dir_hash(s
, digest
)) {
552 log_fn(LOG_WARN
, "Unable to compute digest of directory");
555 log(LOG_DEBUG
,"Received directory hashes to %02x:%02x:%02x:%02x",
556 ((int)digest
[0])&0xff,((int)digest
[1])&0xff,
557 ((int)digest
[2])&0xff,((int)digest
[3])&0xff);
560 TOK_IS(K_SIGNED_DIRECTORY
, "signed-directory");
563 TOK_IS(K_PUBLISHED
, "published");
564 if (tok
.val
.cmd
.n_args
!= 2) {
565 log_fn(LOG_WARN
, "Invalid published line");
568 tok
.val
.cmd
.args
[1][-1] = ' ';
569 if (!strptime(tok
.val
.cmd
.args
[0], "%Y-%m-%d %H:%M:%S", &published
)) {
570 log_fn(LOG_WARN
, "Published time was unparseable"); goto err
;
572 published_on
= tor_timegm(&published
);
575 TOK_IS(K_RECOMMENDED_SOFTWARE
, "recommended-software");
576 if (tok
.val
.cmd
.n_args
!= 1) {
577 log_fn(LOG_WARN
, "Invalid recommended-software line");
580 versions
= tor_strdup(tok
.val
.cmd
.args
[0]);
583 TOK_IS(K_RUNNING_ROUTERS
, "running-routers");
584 n_good_nicknames
= tok
.val
.cmd
.n_args
;
585 memcpy(good_nickname_lst
, tok
.val
.cmd
.args
, n_good_nicknames
*sizeof(char *));
587 if (router_get_list_from_string_impl(&s
, &new_dir
,
588 n_good_nicknames
, good_nickname_lst
)) {
589 log_fn(LOG_WARN
, "Error reading routers from directory");
592 new_dir
->software_versions
= versions
;
593 new_dir
->published_on
= published_on
;
596 TOK_IS(K_DIRECTORY_SIGNATURE
, "directory-signature");
598 TOK_IS(_SIGNATURE
, "signature");
600 if (crypto_pk_public_checksig(pkey
, tok
.val
.signature
, 128, signed_digest
)
602 log_fn(LOG_WARN
, "Error reading directory: invalid signature.");
603 free(tok
.val
.signature
);
606 log(LOG_DEBUG
,"Signed directory hash starts %02x:%02x:%02x:%02x",
607 ((int)signed_digest
[0])&0xff,((int)signed_digest
[1])&0xff,
608 ((int)signed_digest
[2])&0xff,((int)signed_digest
[3])&0xff);
609 if (memcmp(digest
, signed_digest
, 20)) {
610 log_fn(LOG_WARN
, "Error reading directory: signature does not match.");
611 free(tok
.val
.signature
);
615 free(tok
.val
.signature
);
618 TOK_IS(_EOF
, "end of directory");
621 directory_free(*dest
);
628 directory_free(new_dir
);
634 int router_get_list_from_string_impl(char **s
, directory_t
**dest
,
635 int n_good_nicknames
,
636 const char **good_nickname_lst
)
638 routerinfo_t
*router
;
639 routerinfo_t
**rarray
;
645 rarray
= (routerinfo_t
**)tor_malloc((sizeof(routerinfo_t
*))*MAX_ROUTERS_IN_DIR
);
648 *s
= eat_whitespace(*s
);
649 if (strncmp(*s
, "router ", 7)!=0)
651 router
= router_get_entry_from_string(s
);
653 log_fn(LOG_WARN
, "Error reading router");
654 for(i
=0;i
<rarray_len
;i
++)
655 routerinfo_free(rarray
[i
]);
659 if (rarray_len
>= MAX_ROUTERS_IN_DIR
) {
660 log_fn(LOG_WARN
, "too many routers");
661 routerinfo_free(router
);
664 if (n_good_nicknames
>=0) {
665 router
->is_running
= 0;
666 for (i
= 0; i
< n_good_nicknames
; ++i
) {
667 if (0==strcasecmp(good_nickname_lst
[i
], router
->nickname
)) {
668 router
->is_running
= 1;
673 router
->is_running
= 1; /* start out assuming all dirservers are up */
675 rarray
[rarray_len
++] = router
;
676 log_fn(LOG_DEBUG
,"just added router #%d.",rarray_len
);
680 directory_free(*dest
);
681 *dest
= (directory_t
*)tor_malloc(sizeof(directory_t
));
682 (*dest
)->routers
= rarray
;
683 (*dest
)->n_routers
= rarray_len
;
684 (*dest
)->software_versions
= NULL
;
689 router_resolve(routerinfo_t
*router
)
691 struct hostent
*rent
;
693 rent
= (struct hostent
*)gethostbyname(router
->address
);
695 log_fn(LOG_WARN
,"Could not get address for router %s.",router
->address
);
698 assert(rent
->h_length
== 4);
699 memcpy(&router
->addr
, rent
->h_addr
,rent
->h_length
);
700 router
->addr
= ntohl(router
->addr
); /* get it back into host order */
706 router_resolve_directory(directory_t
*dir
)
712 max
= dir
->n_routers
;
713 for (i
= 0; i
< max
; ++i
) {
715 if (router_resolve(dir
->routers
[i
])) {
716 log_fn(LOG_WARN
, "Couldn't resolve router %s; not using",
717 dir
->routers
[i
]->address
);
719 } else if (options
.Nickname
&&
720 !strcmp(dir
->routers
[i
]->nickname
, options
.Nickname
)) {
724 routerinfo_free(dir
->routers
[i
]);
725 dir
->routers
[i
] = dir
->routers
[--max
];
734 /* reads a single router entry from s.
735 * updates s so it points to after the router it just read.
736 * mallocs a new router, returns it if all goes well, else returns NULL.
738 routerinfo_t
*router_get_entry_from_string(char**s
) {
739 routerinfo_t
*router
= NULL
;
740 char signed_digest
[128];
742 directory_token_t _tok
;
743 directory_token_t
*tok
= &_tok
;
747 #define NEXT_TOKEN() \
748 do { if (router_get_next_token(s, tok)) { \
749 log_fn(LOG_WARN, "Error reading directory: %s", tok->val.error);\
753 #define ARGS tok->val.cmd.args
755 if (router_get_router_hash(*s
, digest
) < 0) {
756 log_fn(LOG_WARN
, "Couldn't compute router hash.");
762 if (tok
->tp
!= K_ROUTER
) {
763 router_release_token(tok
);
764 log_fn(LOG_WARN
,"Entry does not start with \"router\"");
768 router
= tor_malloc_zero(sizeof(routerinfo_t
));
769 router
->onion_pkey
= router
->identity_pkey
= router
->link_pkey
= NULL
;
771 if (tok
->val
.cmd
.n_args
!= 6) {
772 log_fn(LOG_WARN
,"Wrong # of arguments to \"router\"");
775 router
->nickname
= tor_strdup(ARGS
[0]);
776 if (strlen(router
->nickname
) > MAX_NICKNAME_LEN
) {
777 log_fn(LOG_WARN
,"Router nickname too long.");
780 if (strspn(router
->nickname
, LEGAL_NICKNAME_CHARACTERS
) !=
781 strlen(router
->nickname
)) {
782 log_fn(LOG_WARN
, "Router nickname contains illegal characters.");
786 /* read router.address */
787 router
->address
= tor_strdup(ARGS
[1]);
790 /* Read router->or_port */
791 router
->or_port
= atoi(ARGS
[2]);
792 if(!router
->or_port
) {
793 log_fn(LOG_WARN
,"or_port unreadable or 0. Failing.");
797 /* Router->socks_port */
798 router
->socks_port
= atoi(ARGS
[3]);
800 /* Router->dir_port */
801 router
->dir_port
= atoi(ARGS
[4]);
803 /* Router->bandwidth */
804 router
->bandwidth
= atoi(ARGS
[5]);
805 if (!router
->bandwidth
) {
806 log_fn(LOG_WARN
,"bandwidth unreadable or 0. Failing.");
810 log_fn(LOG_DEBUG
,"or_port %d, socks_port %d, dir_port %d, bandwidth %d.",
811 router
->or_port
, router
->socks_port
, router
->dir_port
, router
->bandwidth
);
813 /* XXX Later, require platform before published. */
815 if (tok
->tp
== K_PLATFORM
) {
819 if (tok
->tp
!= K_PUBLISHED
) {
820 log_fn(LOG_WARN
, "Missing published time"); goto err
;
822 if (tok
->val
.cmd
.n_args
!= 2) {
823 log_fn(LOG_WARN
, "Wrong number of arguments to published"); goto err
;
825 ARGS
[1][-1] = ' '; /* Re-insert space. */
826 if (!strptime(ARGS
[0], "%Y-%m-%d %H:%M:%S", &published
)) {
827 log_fn(LOG_WARN
, "Published time was unparseable"); goto err
;
829 router
->published_on
= tor_timegm(&published
);
832 if (tok
->tp
!= K_ONION_KEY
) {
833 log_fn(LOG_WARN
, "Missing onion-key"); goto err
;
836 if (tok
->tp
!= _PUBLIC_KEY
) {
837 log_fn(LOG_WARN
, "Missing onion key"); goto err
;
838 } /* XXX Check key length */
839 router
->onion_pkey
= tok
->val
.public_key
;
842 if (tok
->tp
!= K_LINK_KEY
) {
843 log_fn(LOG_WARN
, "Missing link-key"); goto err
;
846 if (tok
->tp
!= _PUBLIC_KEY
) {
847 log_fn(LOG_WARN
, "Missing link key"); goto err
;
848 } /* XXX Check key length */
849 router
->link_pkey
= tok
->val
.public_key
;
852 if (tok
->tp
!= K_SIGNING_KEY
) {
853 log_fn(LOG_WARN
, "Missing signing-key"); goto err
;
856 if (tok
->tp
!= _PUBLIC_KEY
) {
857 log_fn(LOG_WARN
, "Missing signing key"); goto err
;
859 router
->identity_pkey
= tok
->val
.public_key
;
862 while (tok
->tp
== K_ACCEPT
|| tok
->tp
== K_REJECT
) {
863 router_add_exit_policy(router
, tok
);
867 if (tok
->tp
!= K_ROUTER_SIGNATURE
) {
868 log_fn(LOG_WARN
,"Missing router signature");
872 if (tok
->tp
!= _SIGNATURE
) {
873 log_fn(LOG_WARN
,"Missing router signature");
876 assert (router
->identity_pkey
);
878 if ((t
=crypto_pk_public_checksig(router
->identity_pkey
, tok
->val
.signature
,
879 128, signed_digest
)) != 20) {
880 log_fn(LOG_WARN
, "Invalid signature %d",t
);
883 if (memcmp(digest
, signed_digest
, 20)) {
884 log_fn(LOG_WARN
, "Mismatched signature");
888 router_release_token(tok
); /* free the signature */
892 router_release_token(tok
);
893 routerinfo_free(router
);
899 void router_add_exit_policy_from_config(routerinfo_t
*router
) {
900 char *s
= options
.ExitPolicy
, *e
;
905 log_fn(LOG_INFO
,"No exit policy configured. Ok.");
906 return; /* nothing to see here */
909 log_fn(LOG_INFO
,"Exit policy is empty. Ok.");
910 return; /* nothing to see here */
917 strncpy(line
,s
,1023);
919 memcpy(line
,s
, ((e
-s
)<1023)?(e
-s
):1023);
923 log_fn(LOG_DEBUG
,"Adding new entry '%s'",line
);
924 if(router_add_exit_policy_from_string(router
,line
) < 0)
925 log_fn(LOG_WARN
,"Malformed exit policy %s; skipping.", line
);
933 router_add_exit_policy_from_string(routerinfo_t
*router
,
936 directory_token_t tok
;
942 tmp
= cp
= tor_malloc(len
+2);
943 for (idx
= 0; idx
< len
; ++idx
) {
944 tmp
[idx
] = tolower(s
[idx
]);
948 if (router_get_next_token(&cp
, &tok
)) {
949 log_fn(LOG_WARN
, "Error reading exit policy: %s", tok
.val
.error
);
953 if (tok
.tp
!= K_ACCEPT
&& tok
.tp
!= K_REJECT
) {
954 log_fn(LOG_WARN
, "Expected 'accept' or 'reject'.");
958 r
= router_add_exit_policy(router
, &tok
);
963 static int router_add_exit_policy(routerinfo_t
*router
,
964 directory_token_t
*tok
) {
965 struct exit_policy_t
*tmpe
, *newe
;
967 char *arg
, *address
, *mask
, *port
, *endptr
;
970 if (tok
->val
.cmd
.n_args
!= 1)
972 arg
= tok
->val
.cmd
.args
[0];
974 newe
= tor_malloc_zero(sizeof(struct exit_policy_t
));
976 newe
->string
= tor_malloc(8+strlen(arg
));
977 if (tok
->tp
== K_REJECT
) {
978 strcpy(newe
->string
, "reject ");
979 newe
->policy_type
= EXIT_POLICY_REJECT
;
981 assert(tok
->tp
== K_ACCEPT
);
982 strcpy(newe
->string
, "accept ");
983 newe
->policy_type
= EXIT_POLICY_ACCEPT
;
985 strcat(newe
->string
, arg
);
988 mask
= strchr(arg
,'/');
989 port
= strchr(mask
?mask
:arg
,':');
991 goto policy_read_failed
;
996 if (strcmp(address
, "*") == 0) {
998 } else if (inet_aton(address
, &in
) != 0) {
999 newe
->addr
= ntohl(in
.s_addr
);
1001 log_fn(LOG_WARN
, "Malformed IP %s in exit policy; rejecting.",
1003 goto policy_read_failed
;
1006 if (strcmp(address
, "*") == 0)
1009 newe
->msk
= 0xFFFFFFFFu
;
1012 bits
= (int) strtol(mask
, &endptr
, 10);
1014 /* strtol handled the whole mask. */
1015 newe
->msk
= ~((1<<(32-bits
))-1);
1016 } else if (inet_aton(mask
, &in
) != 0) {
1017 newe
->msk
= ntohl(in
.s_addr
);
1019 log_fn(LOG_WARN
, "Malformed mask %s on exit policy; rejecting.",
1021 goto policy_read_failed
;
1024 if (strcmp(port
, "*") == 0) {
1028 newe
->prt
= strtol(port
, &endptr
, 10);
1030 log_fn(LOG_WARN
, "Malformed port %s on exit policy; rejecting.",
1032 goto policy_read_failed
;
1036 in
.s_addr
= htonl(newe
->addr
);
1037 address
= tor_strdup(inet_ntoa(in
));
1038 in
.s_addr
= htonl(newe
->msk
);
1039 log_fn(LOG_DEBUG
,"%s %s/%s:%d",
1040 newe
->policy_type
== EXIT_POLICY_REJECT
? "reject" : "accept",
1041 address
, inet_ntoa(in
), newe
->prt
);
1044 /* now link newe onto the end of exit_policy */
1046 if(!router
->exit_policy
) {
1047 router
->exit_policy
= newe
;
1051 for(tmpe
=router
->exit_policy
; tmpe
->next
; tmpe
=tmpe
->next
) ;
1057 assert(newe
->string
);
1058 log_fn(LOG_WARN
,"Couldn't parse line '%s'. Dropping", newe
->string
);
1059 tor_free(newe
->string
);
1064 /* Addr is 0 for "IP unknown".
1066 * Returns -1 for 'rejected', 0 for accepted, 1 for 'maybe' (since IP is
1069 int router_supports_exit_address(uint32_t addr
, uint16_t port
,
1070 routerinfo_t
*router
)
1072 return router_compare_addr_to_exit_policy(addr
, port
, router
->exit_policy
);
1075 /* Addr is 0 for "IP unknown".
1077 * Returns -1 for 'rejected', 0 for accepted, 1 for 'maybe' (since IP is
1080 int router_compare_addr_to_exit_policy(uint32_t addr
, uint16_t port
,
1081 struct exit_policy_t
*policy
)
1083 int maybe_reject
= 0;
1086 struct exit_policy_t
*tmpe
;
1088 for(tmpe
=policy
; tmpe
; tmpe
=tmpe
->next
) {
1089 log_fn(LOG_DEBUG
,"Considering exit policy %s", tmpe
->string
);
1091 /* Address is unknown. */
1092 if (tmpe
->msk
== 0 && port
== tmpe
->prt
) {
1093 /* The exit policy is accept/reject *:port */
1095 } else if ((!tmpe
->prt
|| port
== tmpe
->prt
) &&
1096 tmpe
->policy_type
== EXIT_POLICY_REJECT
) {
1097 /* The exit policy is reject ???:port */
1101 /* Address is known */
1102 if ( (addr
& tmpe
->msk
) == (tmpe
->addr
& tmpe
->msk
) &&
1103 (!tmpe
->prt
|| port
== tmpe
->prt
) ) {
1104 /* Exact match for the policy */
1109 in
.s_addr
= htonl(addr
);
1110 log_fn(LOG_INFO
,"Address %s:%d matches exit policy '%s'",
1111 inet_ntoa(in
), port
, tmpe
->string
);
1112 if(tmpe
->policy_type
== EXIT_POLICY_ACCEPT
)
1121 return 0; /* accept all by default. */
1124 /* Return 0 if my exit policy says to allow connection to conn.
1127 int router_compare_to_exit_policy(connection_t
*conn
) {
1128 assert(desc_routerinfo
);
1130 if (router_compare_addr_to_exit_policy(conn
->addr
, conn
->port
,
1131 desc_routerinfo
->exit_policy
))
1137 const char *router_get_my_descriptor(void) {
1138 if (!desc_routerinfo
) {
1139 if (router_rebuild_descriptor())
1142 log_fn(LOG_DEBUG
,"my desc is '%s'",descriptor
);
1145 const routerinfo_t
*router_get_desc_routerinfo(void) {
1146 if (!desc_routerinfo
) {
1147 if (router_rebuild_descriptor())
1150 return desc_routerinfo
;
1153 int router_rebuild_descriptor(void) {
1155 char localhostname
[256];
1156 char *address
= options
.Address
;
1158 if(!address
) { /* if not specified in config, we find a default */
1159 if(gethostname(localhostname
,sizeof(localhostname
)) < 0) {
1160 log_fn(LOG_WARN
,"Error obtaining local hostname");
1163 address
= localhostname
;
1164 if(!strchr(address
,'.')) {
1165 log_fn(LOG_WARN
,"fqdn '%s' has only one element. Misconfigured machine?",address
);
1166 log_fn(LOG_WARN
,"Try setting the Address line in your config file.");
1170 ri
= tor_malloc(sizeof(routerinfo_t
));
1171 ri
->address
= tor_strdup(address
);
1172 ri
->nickname
= tor_strdup(options
.Nickname
);
1173 /* No need to set addr. */
1174 ri
->or_port
= options
.ORPort
;
1175 ri
->socks_port
= options
.SocksPort
;
1176 ri
->dir_port
= options
.DirPort
;
1177 ri
->published_on
= time(NULL
);
1178 ri
->onion_pkey
= crypto_pk_dup_key(get_onion_key());
1179 ri
->link_pkey
= crypto_pk_dup_key(get_link_key());
1180 ri
->identity_pkey
= crypto_pk_dup_key(get_identity_key());
1181 ri
->bandwidth
= options
.TotalBandwidth
;
1182 ri
->exit_policy
= NULL
; /* zero it out first */
1183 router_add_exit_policy_from_config(ri
);
1184 if (desc_routerinfo
)
1185 routerinfo_free(desc_routerinfo
);
1186 desc_routerinfo
= ri
;
1187 if (router_dump_router_to_string(descriptor
, 8192, ri
, get_identity_key())<0) {
1188 log_fn(LOG_WARN
, "Couldn't dump router to string.");
1194 static void get_platform_str(char *platform
, int len
)
1196 snprintf(platform
, len
-1, "Tor %s on %s", VERSION
, get_uname());
1197 platform
[len
-1] = '\0';
1201 /* XXX need to audit this thing and count fenceposts. maybe
1202 * refactor so we don't have to keep asking if we're
1203 * near the end of maxlen?
1205 #define DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
1206 int router_dump_router_to_string(char *s
, int maxlen
, routerinfo_t
*router
,
1207 crypto_pk_env_t
*ident_key
) {
1210 char *identity_pkey
;
1214 char signature
[128];
1216 int onion_pkeylen
, link_pkeylen
, identity_pkeylen
;
1219 struct exit_policy_t
*tmpe
;
1220 #ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
1221 char *s_tmp
, *s_dup
;
1222 routerinfo_t
*ri_tmp
;
1225 get_platform_str(platform
, sizeof(platform
));
1227 if (crypto_pk_cmp_keys(ident_key
, router
->identity_pkey
)) {
1228 log_fn(LOG_WARN
,"Tried to sign a router with a private key that didn't match router's public key!");
1232 if(crypto_pk_write_public_key_to_string(router
->onion_pkey
,
1233 &onion_pkey
,&onion_pkeylen
)<0) {
1234 log_fn(LOG_WARN
,"write onion_pkey to string failed!");
1238 if(crypto_pk_write_public_key_to_string(router
->identity_pkey
,
1239 &identity_pkey
,&identity_pkeylen
)<0) {
1240 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
1244 if(crypto_pk_write_public_key_to_string(router
->link_pkey
,
1245 &link_pkey
,&link_pkeylen
)<0) {
1246 log_fn(LOG_WARN
,"write link_pkey to string failed!");
1249 strftime(published
, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router
->published_on
));
1251 result
= snprintf(s
, maxlen
,
1252 "router %s %s %d %d %d %d\n"
1266 onion_pkey
, link_pkey
, identity_pkey
);
1270 free(identity_pkey
);
1272 if(result
< 0 || result
>= maxlen
) {
1273 /* apparently different glibcs do different things on snprintf error.. so check both */
1278 for(tmpe
=router
->exit_policy
; tmpe
; tmpe
=tmpe
->next
) {
1279 in
.s_addr
= htonl(tmpe
->addr
);
1280 result
= snprintf(s
+written
, maxlen
-written
, "%s %s",
1281 tmpe
->policy_type
== EXIT_POLICY_ACCEPT
? "accept" : "reject",
1282 tmpe
->msk
== 0 ? "*" : inet_ntoa(in
));
1283 if(result
< 0 || result
+written
> maxlen
) {
1284 /* apparently different glibcs do different things on snprintf error.. so check both */
1288 if (tmpe
->msk
!= 0xFFFFFFFFu
&& tmpe
->msk
!= 0) {
1289 in
.s_addr
= htonl(tmpe
->msk
);
1290 result
= snprintf(s
+written
, maxlen
-written
, "/%s", inet_ntoa(in
));
1291 if (result
<0 || result
+written
> maxlen
)
1296 result
= snprintf(s
+written
, maxlen
-written
, ":%d\n", tmpe
->prt
);
1297 if (result
<0 || result
+written
> maxlen
)
1301 if (written
> maxlen
-4)
1303 strcat(s
+written
, ":*\n");
1307 if (written
> maxlen
-256) /* Not enough room for signature. */
1310 strcat(s
+written
, "router-signature\n");
1311 written
+= strlen(s
+written
);
1313 if (router_get_router_hash(s
, digest
) < 0)
1316 if (crypto_pk_private_sign(ident_key
, digest
, 20, signature
) < 0) {
1317 log_fn(LOG_WARN
, "Error signing digest");
1320 strcat(s
+written
, "-----BEGIN SIGNATURE-----\n");
1321 written
+= strlen(s
+written
);
1322 if (base64_encode(s
+written
, maxlen
-written
, signature
, 128) < 0) {
1323 log_fn(LOG_WARN
, "Couldn't base64-encode signature");
1326 written
+= strlen(s
+written
);
1327 strcat(s
+written
, "-----END SIGNATURE-----\n");
1328 written
+= strlen(s
+written
);
1330 if (written
> maxlen
-2)
1332 /* include a last '\n' */
1336 #ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
1337 s_tmp
= s_dup
= tor_strdup(s
);
1338 ri_tmp
= router_get_entry_from_string(&s_tmp
);
1340 log_fn(LOG_ERR
, "We just generated a router descriptor we can't parse: <<%s>>",
1345 routerinfo_free(ri_tmp
);
1354 indent-tabs-mode:nil