1 /* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
7 extern or_options_t options
; /* command-line and config-file options */
9 /************************************************************/
12 static crypto_pk_env_t
*onionkey
=NULL
;
13 static crypto_pk_env_t
*linkkey
=NULL
;
14 static crypto_pk_env_t
*identitykey
=NULL
;
16 void set_onion_key(crypto_pk_env_t
*k
) {
20 crypto_pk_env_t
*get_onion_key(void) {
25 void set_link_key(crypto_pk_env_t
*k
)
30 crypto_pk_env_t
*get_link_key(void)
36 void set_identity_key(crypto_pk_env_t
*k
) {
40 crypto_pk_env_t
*get_identity_key(void) {
45 /************************************************************/
47 static crypto_pk_env_t
*init_key_from_file(const char *fname
)
49 crypto_pk_env_t
*prkey
= NULL
;
53 if (!(prkey
= crypto_new_pk_env(CRYPTO_PK_RSA
))) {
54 log(LOG_ERR
, "Error creating crypto environment.");
58 switch(file_status(fname
)) {
61 log(LOG_ERR
, "Can't read key from %s", fname
);
64 log(LOG_INFO
, "No key found in %s; generating fresh key.", fname
);
65 if (crypto_pk_generate_key(prkey
)) {
66 log(LOG_ERR
, "Error generating key: %s", crypto_perror());
69 if (crypto_pk_check_key(prkey
) <= 0) {
70 log(LOG_ERR
, "Generated key seems invalid");
73 log(LOG_INFO
, "Generated key seems valid");
74 if (crypto_pk_write_private_key_to_filename(prkey
, fname
)) {
75 log(LOG_ERR
, "Couldn't write generated key to %s.", fname
);
80 if (crypto_pk_read_private_key_from_filename(prkey
, fname
)) {
81 log(LOG_ERR
, "Error loading private key.");
91 crypto_free_pk_env(prkey
);
101 char fingerprint
[FINGERPRINT_LEN
+MAX_NICKNAME_LEN
+3];
103 const char *tmp
, *mydesc
;
104 crypto_pk_env_t
*prkey
;
106 /* OP's don't need keys. Just initialize the TLS context.*/
107 if (!options
.ORPort
) {
108 assert(!options
.DirPort
);
109 if (tor_tls_context_new(NULL
, 0, NULL
)<0) {
110 log_fn(LOG_ERR
, "Error creating TLS context for OP.");
115 assert(options
.DataDirectory
);
116 if (strlen(options
.DataDirectory
) > (512-128)) {
117 log_fn(LOG_ERR
, "DataDirectory is too long.");
120 if (check_private_dir(options
.DataDirectory
, 1)) {
123 sprintf(keydir
,"%s/keys",options
.DataDirectory
);
124 if (check_private_dir(keydir
, 1)) {
127 cp
= keydir
+ strlen(keydir
); /* End of string. */
129 /* 1. Read identity key. Make it if none is found. */
130 strcpy(cp
, "/identity.key");
131 log_fn(LOG_INFO
,"Reading/making identity key %s...",keydir
);
132 prkey
= init_key_from_file(keydir
);
133 if (!prkey
) return -1;
134 set_identity_key(prkey
);
135 /* 2. Read onion key. Make it if none is found. */
136 strcpy(cp
, "/onion.key");
137 log_fn(LOG_INFO
,"Reading/making onion key %s...",keydir
);
138 prkey
= init_key_from_file(keydir
);
139 if (!prkey
) return -1;
140 set_onion_key(prkey
);
142 /* 3. Initialize link key and TLS context. */
143 strcpy(cp
, "/link.key");
144 log_fn(LOG_INFO
,"Reading/making link key %s...",keydir
);
145 prkey
= init_key_from_file(keydir
);
146 if (!prkey
) return -1;
148 if (tor_tls_context_new(prkey
, 1, options
.Nickname
) < 0) {
149 log_fn(LOG_ERR
, "Error initializing TLS context");
152 /* 4. Dump router descriptor to 'router.desc' */
153 /* Must be called after keys are initialized. */
154 if (!(router_get_my_descriptor())) {
155 log_fn(LOG_ERR
, "Error initializing descriptor.");
158 /* We need to add our own fingerprint so it gets recognized. */
159 if (dirserv_add_own_fingerprint(options
.Nickname
, get_identity_key())) {
160 log_fn(LOG_ERR
, "Error adding own fingerprint to approved set");
163 tmp
= mydesc
= router_get_my_descriptor();
164 if (dirserv_add_descriptor(&tmp
)) {
165 log(LOG_ERR
, "Unable to add own descriptor to directory.");
168 sprintf(keydir
,"%s/router.desc", options
.DataDirectory
);
169 log_fn(LOG_INFO
,"Dumping descriptor to %s...",keydir
);
170 if (write_str_to_file(keydir
, mydesc
)) {
173 /* 5. Dump fingerprint to 'fingerprint' */
174 sprintf(keydir
,"%s/fingerprint", options
.DataDirectory
);
175 log_fn(LOG_INFO
,"Dumping fingerprint to %s...",keydir
);
176 assert(strlen(options
.Nickname
) <= MAX_NICKNAME_LEN
);
177 strcpy(fingerprint
, options
.Nickname
);
178 strcat(fingerprint
, " ");
179 if (crypto_pk_get_fingerprint(get_identity_key(),
180 fingerprint
+strlen(fingerprint
))<0) {
181 log_fn(LOG_ERR
, "Error computing fingerprint");
184 strcat(fingerprint
, "\n");
185 if (write_str_to_file(keydir
, fingerprint
))
189 /* 6. [dirserver only] load approved-routers file */
190 sprintf(keydir
,"%s/approved-routers", options
.DataDirectory
);
191 log_fn(LOG_INFO
,"Loading approved fingerprints from %s...",keydir
);
192 if(dirserv_parse_fingerprint_file(keydir
) < 0) {
193 log_fn(LOG_ERR
, "Error loading fingerprints");
196 /* 7. [dirserver only] load old directory, if it's there */
197 sprintf(keydir
,"%s/cached-directory", options
.DataDirectory
);
198 log_fn(LOG_INFO
,"Loading cached directory from %s...",keydir
);
199 cp
= read_file_to_str(keydir
);
201 log_fn(LOG_INFO
,"Cached directory %s not present. Ok.",keydir
);
203 if(dirserv_init_from_directory_string(cp
) < 0) {
204 log_fn(LOG_ERR
, "Cached directory %s is corrupt", keydir
);
214 /************************************************************/
216 static routerinfo_t
*desc_routerinfo
= NULL
; /* my descriptor */
217 static char descriptor
[8192]; /* string representation of my descriptor */
219 void router_retry_connections(void) {
221 routerinfo_t
*router
;
224 router_get_routerlist(&rl
);
225 for (i
=0;i
<rl
->n_routers
;i
++) {
226 router
= rl
->routers
[i
];
227 if(!connection_exact_get_by_addr_port(router
->addr
,router
->or_port
)) {
228 /* not in the list */
229 log_fn(LOG_DEBUG
,"connecting to OR %s:%u.",router
->address
,router
->or_port
);
230 connection_or_connect(router
);
235 void router_upload_desc_to_dirservers(void) {
237 routerinfo_t
*router
;
240 router_get_routerlist(&rl
);
244 if (!router_get_my_descriptor()) {
245 log_fn(LOG_WARN
, "No descriptor; skipping upload");
249 for(i
=0;i
<rl
->n_routers
;i
++) {
250 router
= rl
->routers
[i
];
251 if(router
->dir_port
> 0)
252 directory_initiate_command(router
, DIR_CONN_STATE_CONNECTING_UPLOAD
);
256 static void router_add_exit_policy_from_config(routerinfo_t
*router
) {
257 char *s
= options
.ExitPolicy
, *e
;
262 log_fn(LOG_INFO
,"No exit policy configured. Ok.");
263 return; /* nothing to see here */
266 log_fn(LOG_INFO
,"Exit policy is empty. Ok.");
267 return; /* nothing to see here */
274 strncpy(line
,s
,1023);
276 memcpy(line
,s
, ((e
-s
)<1023)?(e
-s
):1023);
280 log_fn(LOG_DEBUG
,"Adding new entry '%s'",line
);
281 if(router_add_exit_policy_from_string(router
,line
) < 0)
282 log_fn(LOG_WARN
,"Malformed exit policy %s; skipping.", line
);
289 /* Return 0 if my exit policy says to allow connection to conn.
292 int router_compare_to_my_exit_policy(connection_t
*conn
) {
293 assert(desc_routerinfo
);
294 assert(conn
->addr
); /* make sure it's resolved to something. this
295 way we can't get a 'maybe' below. */
297 if (router_compare_addr_to_exit_policy(conn
->addr
, conn
->port
,
298 desc_routerinfo
->exit_policy
) == 0)
304 const char *router_get_my_descriptor(void) {
305 if (!desc_routerinfo
) {
306 if (router_rebuild_descriptor())
309 log_fn(LOG_DEBUG
,"my desc is '%s'",descriptor
);
313 int router_rebuild_descriptor(void) {
315 char localhostname
[256];
316 char *address
= options
.Address
;
318 if(!address
) { /* if not specified in config, we find a default */
319 if(gethostname(localhostname
,sizeof(localhostname
)) < 0) {
320 log_fn(LOG_WARN
,"Error obtaining local hostname");
323 address
= localhostname
;
324 if(!strchr(address
,'.')) {
325 log_fn(LOG_WARN
,"fqdn '%s' has only one element. Misconfigured machine?",address
);
326 log_fn(LOG_WARN
,"Try setting the Address line in your config file.");
330 ri
= tor_malloc(sizeof(routerinfo_t
));
331 ri
->address
= tor_strdup(address
);
332 ri
->nickname
= tor_strdup(options
.Nickname
);
333 /* No need to set addr. */
334 ri
->or_port
= options
.ORPort
;
335 ri
->socks_port
= options
.SocksPort
;
336 ri
->dir_port
= options
.DirPort
;
337 ri
->published_on
= time(NULL
);
338 ri
->onion_pkey
= crypto_pk_dup_key(get_onion_key());
339 ri
->link_pkey
= crypto_pk_dup_key(get_link_key());
340 ri
->identity_pkey
= crypto_pk_dup_key(get_identity_key());
341 ri
->bandwidth
= options
.TotalBandwidth
;
342 ri
->exit_policy
= NULL
; /* zero it out first */
343 router_add_exit_policy_from_config(ri
);
345 routerinfo_free(desc_routerinfo
);
346 desc_routerinfo
= ri
;
347 if (router_dump_router_to_string(descriptor
, 8192, ri
, get_identity_key())<0) {
348 log_fn(LOG_WARN
, "Couldn't dump router to string.");
354 static void get_platform_str(char *platform
, int len
)
356 snprintf(platform
, len
-1, "Tor %s on %s", VERSION
, get_uname());
357 platform
[len
-1] = '\0';
361 /* XXX need to audit this thing and count fenceposts. maybe
362 * refactor so we don't have to keep asking if we're
363 * near the end of maxlen?
365 #define DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
366 int router_dump_router_to_string(char *s
, int maxlen
, routerinfo_t
*router
,
367 crypto_pk_env_t
*ident_key
) {
376 int onion_pkeylen
, link_pkeylen
, identity_pkeylen
;
379 struct exit_policy_t
*tmpe
;
380 #ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
383 routerinfo_t
*ri_tmp
;
386 get_platform_str(platform
, sizeof(platform
));
388 if (crypto_pk_cmp_keys(ident_key
, router
->identity_pkey
)) {
389 log_fn(LOG_WARN
,"Tried to sign a router with a private key that didn't match router's public key!");
393 if(crypto_pk_write_public_key_to_string(router
->onion_pkey
,
394 &onion_pkey
,&onion_pkeylen
)<0) {
395 log_fn(LOG_WARN
,"write onion_pkey to string failed!");
399 if(crypto_pk_write_public_key_to_string(router
->identity_pkey
,
400 &identity_pkey
,&identity_pkeylen
)<0) {
401 log_fn(LOG_WARN
,"write identity_pkey to string failed!");
405 if(crypto_pk_write_public_key_to_string(router
->link_pkey
,
406 &link_pkey
,&link_pkeylen
)<0) {
407 log_fn(LOG_WARN
,"write link_pkey to string failed!");
410 strftime(published
, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router
->published_on
));
412 result
= snprintf(s
, maxlen
,
413 "router %s %s %d %d %d %d\n"
427 onion_pkey
, link_pkey
, identity_pkey
);
433 if(result
< 0 || result
>= maxlen
) {
434 /* apparently different glibcs do different things on snprintf error.. so check both */
439 for(tmpe
=router
->exit_policy
; tmpe
; tmpe
=tmpe
->next
) {
440 in
.s_addr
= htonl(tmpe
->addr
);
441 result
= snprintf(s
+written
, maxlen
-written
, "%s %s",
442 tmpe
->policy_type
== EXIT_POLICY_ACCEPT
? "accept" : "reject",
443 tmpe
->msk
== 0 ? "*" : inet_ntoa(in
));
444 if(result
< 0 || result
+written
> maxlen
) {
445 /* apparently different glibcs do different things on snprintf error.. so check both */
449 if (tmpe
->msk
!= 0xFFFFFFFFu
&& tmpe
->msk
!= 0) {
450 in
.s_addr
= htonl(tmpe
->msk
);
451 result
= snprintf(s
+written
, maxlen
-written
, "/%s", inet_ntoa(in
));
452 if (result
<0 || result
+written
> maxlen
)
457 result
= snprintf(s
+written
, maxlen
-written
, ":%d\n", tmpe
->prt
);
458 if (result
<0 || result
+written
> maxlen
)
462 if (written
> maxlen
-4)
464 strcat(s
+written
, ":*\n");
468 if (written
> maxlen
-256) /* Not enough room for signature. */
471 strcat(s
+written
, "router-signature\n");
472 written
+= strlen(s
+written
);
474 if (router_get_router_hash(s
, digest
) < 0)
477 if (crypto_pk_private_sign(ident_key
, digest
, 20, signature
) < 0) {
478 log_fn(LOG_WARN
, "Error signing digest");
481 strcat(s
+written
, "-----BEGIN SIGNATURE-----\n");
482 written
+= strlen(s
+written
);
483 if (base64_encode(s
+written
, maxlen
-written
, signature
, 128) < 0) {
484 log_fn(LOG_WARN
, "Couldn't base64-encode signature");
487 written
+= strlen(s
+written
);
488 strcat(s
+written
, "-----END SIGNATURE-----\n");
489 written
+= strlen(s
+written
);
491 if (written
> maxlen
-2)
493 /* include a last '\n' */
497 #ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
498 cp
= s_tmp
= s_dup
= tor_strdup(s
);
499 ri_tmp
= router_get_entry_from_string(&cp
);
501 log_fn(LOG_ERR
, "We just generated a router descriptor we can't parse: <<%s>>",
506 routerinfo_free(ri_tmp
);