ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
(Generate patch)

Comparing gvpe/src/conf.C (file contents):
Revision 1.50 by pcg, Mon Mar 23 15:22:00 2009 UTC vs.
Revision 1.62 by root, Wed Jul 17 16:40:57 2013 UTC

1/* 1/*
2 conf.c -- configuration code 2 conf.C -- configuration code
3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2011 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE. 5 This file is part of GVPE.
6 6
7 GVPE is free software; you can redistribute it and/or modify it 7 GVPE is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
38#include <errno.h> 38#include <errno.h>
39#include <netdb.h> 39#include <netdb.h>
40#include <sys/stat.h> 40#include <sys/stat.h>
41#include <sys/types.h> 41#include <sys/types.h>
42#include <unistd.h> 42#include <unistd.h>
43#include <pwd.h>
43 44
44#include "netcompat.h" 45#include "netcompat.h"
45 46
46#include <openssl/err.h> 47#include <openssl/err.h>
47#include <openssl/pem.h> 48#include <openssl/pem.h>
57char *thisnode; 58char *thisnode;
58char *identname; 59char *identname;
59 60
60struct configuration conf; 61struct configuration conf;
61 62
63u8
62u8 best_protocol (u8 protset) 64best_protocol (u8 protset)
63{ 65{
64 if (protset & PROT_IPv4 ) return PROT_IPv4; 66 if (protset & PROT_IPv4 ) return PROT_IPv4;
65 if (protset & PROT_ICMPv4) return PROT_ICMPv4; 67 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
66 if (protset & PROT_UDPv4 ) return PROT_UDPv4; 68 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
67 if (protset & PROT_TCPv4 ) return PROT_TCPv4; 69 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
68 if (protset & PROT_DNSv4 ) return PROT_DNSv4; 70 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
69 71
70 return 0; 72 return 0;
71} 73}
72 74
75const char *
73const char *strprotocol (u8 protocol) 76strprotocol (u8 protocol)
74{ 77{
75 if (protocol & PROT_IPv4 ) return "rawip"; 78 if (protocol & PROT_IPv4 ) return "rawip";
76 if (protocol & PROT_ICMPv4) return "icmp"; 79 if (protocol & PROT_ICMPv4) return "icmp";
77 if (protocol & PROT_UDPv4 ) return "udp"; 80 if (protocol & PROT_UDPv4 ) return "udp";
78 if (protocol & PROT_TCPv4 ) return "tcp"; 81 if (protocol & PROT_TCPv4 ) return "tcp";
103 return false; 106 return false;
104 107
105 return true; 108 return true;
106} 109}
107 110
108void
109conf_node::print ()
110{
111 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
112 id,
113 id >> 8, id & 0xff,
114 compress ? 'Y' : 'N',
115 connectmode == C_ONDEMAND ? "ondemand"
116 : connectmode == C_NEVER ? "never"
117 : connectmode == C_ALWAYS ? "always"
118 : connectmode == C_DISABLED ? "disabled"
119 : "",
120 nodename,
121 hostname ? hostname : "",
122 hostname ? ":" : "",
123 hostname ? udp_port : 0
124 );
125}
126
127conf_node::~conf_node () 111conf_node::~conf_node ()
128{ 112{
129#if 0 113#if 0
130 // does not work, because string pointers etc. are shared 114 // does not work, because string pointers etc. are shared
131 // is not called, however 115 // is not called, however
140 free (dns_hostname); 124 free (dns_hostname);
141#endif 125#endif
142#endif 126#endif
143} 127}
144 128
129void
145void configuration::init () 130configuration::init ()
146{ 131{
147 memset (this, 0, sizeof (*this)); 132 memset (this, 0, sizeof (*this));
148 133
149 mtu = DEFAULT_MTU; 134 mtu = DEFAULT_MTU;
150 nfmark = 0; 135 nfmark = 0;
167 default_node.if_up_data = strdup (""); 152 default_node.if_up_data = strdup ("");
168 153
169#if ENABLE_DNS 154#if ENABLE_DNS
170 default_node.dns_port = 0; // default is 0 == client 155 default_node.dns_port = 0; // default is 0 == client
171 156
157 dns_case_preserving = true;
172 dns_forw_host = strdup ("127.0.0.1"); 158 dns_forw_host = strdup ("127.0.0.1");
173 dns_forw_port = 53; 159 dns_forw_port = 53;
174 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR; 160 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
175 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 161 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
176 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 162 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
177 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING; 163 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING;
178#endif 164#endif
179 165
180 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 166 pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
167 seed_dev = strdup ("/dev/urandom");
168 reseed = DEFAULT_RESEED;
181} 169}
182 170
171void
183void configuration::cleanup() 172configuration::cleanup ()
184{ 173{
185 if (rsa_key) 174 if (rsa_key)
186 RSA_free (rsa_key); 175 RSA_free (rsa_key);
187 176
188 rsa_key = 0; 177 rsa_key = 0;
189 178
179 free (seed_dev); seed_dev = 0;
190 free (pidfilename); pidfilename = 0; 180 free (pidfilename); pidfilename = 0;
191 free (ifname); ifname = 0; 181 free (ifname); ifname = 0;
192#if ENABLE_HTTP_PROXY 182#if ENABLE_HTTP_PROXY
193 free (proxy_host); proxy_host = 0; 183 free (proxy_host); proxy_host = 0;
194 free (proxy_auth); proxy_auth = 0; 184 free (proxy_auth); proxy_auth = 0;
195#endif 185#endif
196#if ENABLE_DNS 186#if ENABLE_DNS
197 free (dns_forw_host); dns_forw_host = 0; 187 free (dns_forw_host); dns_forw_host = 0;
198#endif 188#endif
189 free (change_root); change_root = 0;
190 free (script_if_up); script_if_up = 0;
191 free (script_node_up); script_node_up = 0;
192 free (script_node_change); script_node_change = 0;
193 free (script_node_down); script_node_down = 0;
199} 194}
200 195
201void 196void
202configuration::clear () 197configuration::clear ()
203{ 198{
207 nodes.clear (); 202 nodes.clear ();
208 203
209 cleanup (); 204 cleanup ();
210 init (); 205 init ();
211} 206}
207
208conf_node *
209configuration::find_node (const char *name)
210{
211 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
212 if (!strcmp ((*i)->nodename, name))
213 return *i;
214
215 return 0;
216}
217
218//static bool
219//is_true (const char *name)
220//{
221 //re
222//}
212 223
213#define parse_bool(target,name,trueval,falseval) do { \ 224#define parse_bool(target,name,trueval,falseval) do { \
214 if (!strcmp (val, "yes")) target = trueval; \ 225 if (!strcmp (val, "yes")) target = trueval; \
215 else if (!strcmp (val, "no")) target = falseval; \ 226 else if (!strcmp (val, "no")) target = falseval; \
216 else if (!strcmp (val, "true")) target = trueval; \ 227 else if (!strcmp (val, "true")) target = trueval; \
217 else if (!strcmp (val, "false")) target = falseval; \ 228 else if (!strcmp (val, "false")) target = falseval; \
218 else if (!strcmp (val, "on")) target = trueval; \ 229 else if (!strcmp (val, "on")) target = trueval; \
219 else if (!strcmp (val, "off")) target = falseval; \ 230 else if (!strcmp (val, "off")) target = falseval; \
220 else \ 231 else \
221 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed. (ignored)"); \ 232 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed, ignored"); \
222} while (0) 233} while (0)
223 234
224const char * 235const char *
225configuration_parser::parse_line (char *line) 236configuration_parser::parse_line (char *line)
226{ 237{
244 return 0; /* comment: ignore */ 255 return 0; /* comment: ignore */
245 256
246 char *val = strtok (NULL, "\t\n\r ="); 257 char *val = strtok (NULL, "\t\n\r =");
247 258
248 if (!val || val[0] == '#') 259 if (!val || val[0] == '#')
249 return _("no value given for variable. (ignored)"); 260 return _("no value given for variable, ignored");
250 261
251 if (!strcmp (var, "on")) 262 else if (!strcmp (var, "on"))
252 { 263 {
253 if (!::thisnode 264 if (::thisnode
254 || (val[0] == '!' && strcmp (val + 1, ::thisnode)) 265 && ((val[0] == '!' && strcmp (val + 1, ::thisnode))
255 || !strcmp (val, ::thisnode)) 266 || !strcmp (val, ::thisnode)))
256 return parse_line (strtok (NULL, "\n\r")); 267 return parse_line (strtok (NULL, "\n\r"));
257 else 268 }
258 return 0; 269
270 else if (!strcmp (var, "include"))
271 {
272 char *fname = conf.config_filename (val);
273 parse_file (fname);
274 free (fname);
259 } 275 }
260 276
261 // truly global 277 // truly global
262 if (!strcmp (var, "loglevel")) 278 else if (!strcmp (var, "loglevel"))
263 { 279 {
264 loglevel l = string_to_loglevel (val); 280 loglevel l = string_to_loglevel (val);
265 281
266 if (l == L_NONE) 282 if (l == L_NONE)
267 return _("unknown loglevel. (skipping)"); 283 return _("unknown loglevel, ignored");
268 } 284 }
269 else if (!strcmp (var, "ip-proto")) 285 else if (!strcmp (var, "ip-proto"))
270 conf.ip_proto = atoi (val); 286 conf.ip_proto = atoi (val);
271 else if (!strcmp (var, "icmp-type")) 287 else if (!strcmp (var, "icmp-type"))
272 { 288 {
273#if ENABLE_ICMP 289#if ENABLE_ICMP
274 conf.icmp_type = atoi (val); 290 conf.icmp_type = atoi (val);
275#endif 291#endif
276 } 292 }
293 else if (!strcmp (var, "chuser"))
294 {
295 struct passwd *pw = getpwnam (val);
296 if (!pw)
297 return _("user specified for chuser not found");
277 298
278 // per config 299 conf.change_uid = pw->pw_uid;
300 conf.change_gid = pw->pw_gid;
301 }
302 else if (!strcmp (var, "chuid"))
303 conf.change_uid = atoi (val);
304 else if (!strcmp (var, "chgid"))
305 conf.change_gid = atoi (val);
306 else if (!strcmp (var, "chroot"))
307 free (conf.change_root), conf.change_root = strdup (val);
308
309 // per node
310 else if (!strcmp (var, "global"))
311 node = &conf.default_node;
279 else if (!strcmp (var, "node")) 312 else if (!strcmp (var, "node"))
280 { 313 {
281 parse_argv (); 314 node = conf.find_node (val);
282 315
316 if (!node)
317 {
283 conf.default_node.id++; 318 conf.default_node.id++;
284 node = new conf_node (conf.default_node); 319 node = new conf_node (conf.default_node);
285 conf.nodes.push_back (node); 320 conf.nodes.push_back (node);
286 node->nodename = strdup (val); 321 node->nodename = strdup (val);
287
288 {
289 char *fname;
290 FILE *f;
291
292 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
293
294 f = fopen (fname, "r");
295 if (f)
296 {
297 node->rsa_key = RSA_new ();
298
299 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
300 {
301 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
302 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
303 exit (EXIT_FAILURE);
304 }
305
306 require (RSA_blinding_on (node->rsa_key, 0));
307
308 fclose (f);
309 } 322 }
310 else
311 {
312 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
313
314 if (need_keys)
315 exit (EXIT_FAILURE);
316 }
317
318 free (fname);
319 }
320
321 if (::thisnode && !strcmp (node->nodename, ::thisnode))
322 conf.thisnode = node;
323 } 323 }
324 else if (!strcmp (var, "private-key")) 324 else if (!strcmp (var, "private-key"))
325 free (conf.prikeyfile), conf.prikeyfile = strdup (val); 325 free (conf.prikeyfile), conf.prikeyfile = strdup (val);
326 else if (!strcmp (var, "ifpersist")) 326 else if (!strcmp (var, "ifpersist"))
327 parse_bool (conf.ifpersist, "ifpersist", true, false); 327 parse_bool (conf.ifpersist, "ifpersist", true, false);
333 conf.keepalive = atoi (val); 333 conf.keepalive = atoi (val);
334 else if (!strcmp (var, "mtu")) 334 else if (!strcmp (var, "mtu"))
335 conf.mtu = atoi (val); 335 conf.mtu = atoi (val);
336 else if (!strcmp (var, "nfmark")) 336 else if (!strcmp (var, "nfmark"))
337 conf.nfmark = atoi (val); 337 conf.nfmark = atoi (val);
338 else if (!strcmp (var, "seed-device"))
339 free (conf.seed_dev), conf.seed_dev = strdup (val);
340 else if (!strcmp (var, "seed-interval"))
341 conf.reseed = atoi (val);
338 else if (!strcmp (var, "if-up")) 342 else if (!strcmp (var, "if-up"))
339 free (conf.script_if_up), conf.script_if_up = strdup (val); 343 free (conf.script_if_up), conf.script_if_up = strdup (val);
340 else if (!strcmp (var, "node-up")) 344 else if (!strcmp (var, "node-up"))
341 free (conf.script_node_up), conf.script_node_up = strdup (val); 345 free (conf.script_node_up), conf.script_node_up = strdup (val);
346 else if (!strcmp (var, "node-change"))
347 free (conf.script_node_change), conf.script_node_change = strdup (val);
342 else if (!strcmp (var, "node-down")) 348 else if (!strcmp (var, "node-down"))
343 free (conf.script_node_down), conf.script_node_down = strdup (val); 349 free (conf.script_node_down), conf.script_node_down = strdup (val);
344 else if (!strcmp (var, "pid-file")) 350 else if (!strcmp (var, "pid-file"))
345 free (conf.pidfilename), conf.pidfilename = strdup (val); 351 free (conf.pidfilename), conf.pidfilename = strdup (val);
346 else if (!strcmp (var, "dns-forw-host")) 352 else if (!strcmp (var, "dns-forw-host"))
375 } 381 }
376 else if (!strcmp (var, "dns-max-outstanding")) 382 else if (!strcmp (var, "dns-max-outstanding"))
377 { 383 {
378#if ENABLE_DNS 384#if ENABLE_DNS
379 conf.dns_max_outstanding = atoi (val); 385 conf.dns_max_outstanding = atoi (val);
386#endif
387 }
388 else if (!strcmp (var, "dns-case-preserving"))
389 {
390#if ENABLE_DNS
391 parse_bool (conf.dns_case_preserving, "dns-case-preserving", true, false);
380#endif 392#endif
381 } 393 }
382 else if (!strcmp (var, "http-proxy-host")) 394 else if (!strcmp (var, "http-proxy-host"))
383 { 395 {
384#if ENABLE_HTTP_PROXY 396#if ENABLE_HTTP_PROXY
440 else if (!strcmp (val, "always")) 452 else if (!strcmp (val, "always"))
441 node->connectmode = conf_node::C_ALWAYS; 453 node->connectmode = conf_node::C_ALWAYS;
442 else if (!strcmp (val, "disabled")) 454 else if (!strcmp (val, "disabled"))
443 node->connectmode = conf_node::C_DISABLED; 455 node->connectmode = conf_node::C_DISABLED;
444 else 456 else
445 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled'. (ignored)"); 457 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', ignored");
446 } 458 }
447 else if (!strcmp (var, "inherit-tos")) 459 else if (!strcmp (var, "inherit-tos"))
448 parse_bool (node->inherit_tos, "inherit-tos", true, false); 460 parse_bool (node->inherit_tos, "inherit-tos", true, false);
449 else if (!strcmp (var, "compress")) 461 else if (!strcmp (var, "compress"))
450 parse_bool (node->compress, "compress", true, false); 462 parse_bool (node->compress, "compress", true, false);
484 else if (!strcmp (var, "max-queue")) 496 else if (!strcmp (var, "max-queue"))
485 node->max_queue = atoi (val); 497 node->max_queue = atoi (val);
486 498
487 // unknown or misplaced 499 // unknown or misplaced
488 else 500 else
489 return _("unknown configuration directive. (ignored)"); 501 return _("unknown configuration directive - ignored");
490 502
491 return 0; 503 return 0;
492} 504}
493 505
506void
494void conf_node::finalise () 507conf_node::finalise ()
495{ 508{
496 if (max_queue < 1) 509 if (max_queue < 1)
497 { 510 {
498 slog (L_WARN, _("%s: max-queue value invalid, setting it to 1."), nodename); 511 slog (L_WARN, _("%s: max-queue value invalid, setting it to 1."), nodename);
499 max_queue = 1; 512 max_queue = 1;
504 //slog (L_WARN, _("%s: has non-zero router-priority but either 'never' or 'ondemand' as connectmode, setting it to 'always'."), nodename); 517 //slog (L_WARN, _("%s: has non-zero router-priority but either 'never' or 'ondemand' as connectmode, setting it to 'always'."), nodename);
505 connectmode = C_ALWAYS; 518 connectmode = C_ALWAYS;
506 } 519 }
507} 520}
508 521
509void configuration_parser::parse_argv () 522void
523configuration_parser::parse_file (const char *fname)
510{ 524{
511 for (int i = 0; i < argc; ++i) 525 if (FILE *f = fopen (fname, "r"))
512 { 526 {
513 char *v = argv [i]; 527 char line [2048];
528 int lineno = 0;
514 529
515 if (!*v) 530 while (fgets (line, sizeof (line), f))
516 continue;
517
518 char *enode = v;
519
520 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
521 enode++;
522
523 if (*enode != '.')
524 enode = 0;
525
526 char *wnode = node == &conf.default_node
527 ? 0
528 : node->nodename;
529
530 if ((!wnode && !enode)
531 || (wnode && enode && !strncmp (wnode, v, enode - v)))
532 { 531 {
532 lineno++;
533
533 const char *warn = parse_line (enode ? enode + 1 : v); 534 const char *warn = parse_line (line);
534 535
535 if (warn) 536 if (warn)
536 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); 537 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
537
538 *v = 0;
539 } 538 }
539
540 fclose (f);
541 }
542 else
543 {
544 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
545 exit (EXIT_FAILURE);
540 } 546 }
541} 547}
542 548
543configuration_parser::configuration_parser (configuration &conf, 549configuration_parser::configuration_parser (configuration &conf,
544 bool need_keys, 550 bool need_keys,
545 int argc, 551 int argc,
546 char **argv) 552 char **argv)
547: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 553: conf (conf), need_keys (need_keys), argc (argc), argv (argv)
548{ 554{
549 char *fname; 555 char *fname;
550 FILE *f;
551 556
552 conf.clear (); 557 conf.clear ();
558 node = &conf.default_node;
553 559
554 asprintf (&fname, "%s/gvpe.conf", confbase); 560 asprintf (&fname, "%s/gvpe.conf", confbase);
555 f = fopen (fname, "r"); 561 parse_file (fname);
556
557 if (f)
558 {
559 char line[16384];
560 int lineno = 0;
561 node = &conf.default_node;
562
563 while (fgets (line, sizeof (line), f))
564 {
565 lineno++;
566
567 const char *warn = parse_line (line);
568
569 if (warn)
570 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
571 }
572
573 fclose (f);
574
575 parse_argv ();
576 }
577 else
578 {
579 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
580 exit (EXIT_FAILURE);
581 }
582
583 free (fname); 562 free (fname);
584 563
585 fname = conf.config_filename (conf.prikeyfile, "hostkey"); 564 fname = conf.config_filename (conf.prikeyfile, "hostkey");
586 565
587 f = fopen (fname, "r"); 566 if (FILE *f = fopen (fname, "r"))
588 if (f)
589 { 567 {
590 conf.rsa_key = RSA_new (); 568 conf.rsa_key = RSA_new ();
591 569
592 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL)) 570 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
593 { 571 {
600 578
601 fclose (f); 579 fclose (f);
602 } 580 }
603 else 581 else
604 { 582 {
605 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
606
607 if (need_keys) 583 if (need_keys)
584 {
585 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
608 exit (EXIT_FAILURE); 586 exit (EXIT_FAILURE);
609 }
610
611 if (need_keys && ::thisnode
612 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
613 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
614 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
615 {
616 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
617 exit (EXIT_FAILURE);
618 } 587 }
588 }
619 589
620 free (fname); 590 free (fname);
621 591
592 fname = conf.config_filename (conf.pidfilename);
593 free (conf.pidfilename); conf.pidfilename = fname;
594
622 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i) 595 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
596 {
597 conf_node *node = *i;
598 char *fname;
599 FILE *f;
600
601 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
602
603 f = fopen (fname, "r");
604 if (f)
605 {
606 node->rsa_key = RSA_new ();
607
608 if (!PEM_read_RSAPublicKey (f, &node->rsa_key, NULL, NULL))
609 {
610 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
611 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
612 exit (EXIT_FAILURE);
613 }
614
615 require (RSA_blinding_on (node->rsa_key, 0));
616
617 fclose (f);
618 }
619 else
620 {
621 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
622
623 if (need_keys)
624 exit (EXIT_FAILURE);
625 }
626
627 free (fname);
628
623 (*i)->finalise (); 629 (*i)->finalise ();
624} 630 }
625 631
632 if (::thisnode)
633 {
634 conf.thisnode = conf.find_node (::thisnode);
635
636 if (need_keys)
637 {
638 if (!conf.thisnode)
639 {
640 slog (L_NOTICE, _("local node ('%s') not found in config file, aborting."), ::thisnode);
641 exit (EXIT_FAILURE);
642 }
643
644 if (conf.rsa_key && conf.thisnode->rsa_key)
645 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
646 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
647 {
648 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
649 exit (EXIT_FAILURE);
650 }
651 }
652 }
653
654 parse_argv ();
655}
656
657void
658configuration_parser::parse_argv ()
659{
660 for (int i = 0; i < argc; ++i)
661 {
662 char *v = argv [i];
663
664 if (!*v)
665 continue;
666
667 char *enode = v;
668
669 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
670 enode++;
671
672 if (*enode != '.')
673 enode = 0;
674
675 if (enode)
676 {
677 char *val = strdup (v);
678 val [enode - v] = 0;
679 node = conf.find_node (val);
680 free (val);
681
682 if (!node)
683 {
684 slog (L_WARN, _("command line option '%s' refers to unknown node, ignoring."), v);
685 continue;
686 }
687 }
688 else
689 node = &conf.default_node;
690
691 const char *warn = parse_line (enode ? enode + 1 : v);
692
693 if (warn)
694 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
695 }
696}
697
698char *
626char *configuration::config_filename (const char *name, const char *dflt) 699configuration::config_filename (const char *name, const char *dflt)
627{ 700{
628 char *fname; 701 char *fname;
629 702
630 asprintf (&fname, name ? name : dflt, ::thisnode); 703 asprintf (&fname, name ? name : dflt, ::thisnode ? ::thisnode : "<unset>");
631 704
632 if (!ABSOLUTE_PATH (fname)) 705 if (!ABSOLUTE_PATH (fname))
633 { 706 {
634 char *rname = fname; 707 char *rname = fname;
635 asprintf (&fname, "%s/%s", confbase, rname); 708 asprintf (&fname, "%s/%s", confbase, rname);
636 free (rname); 709 free (rname);
637 } 710 }
638 711
639 return fname; 712 return fname;
713}
714
715void
716conf_node::print ()
717{
718 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %02x %s%s%d\n",
719 id,
720 id >> 8, id & 0xff,
721 compress ? 'Y' : 'N',
722 connectmode == C_ONDEMAND ? "ondemand"
723 : connectmode == C_NEVER ? "never"
724 : connectmode == C_ALWAYS ? "always"
725 : connectmode == C_DISABLED ? "disabled"
726 : "",
727 nodename,
728 protocols,
729 hostname ? hostname : "",
730 hostname ? ":" : "",
731 hostname ? udp_port : 0
732 );
640} 733}
641 734
642void 735void
643configuration::print () 736configuration::print ()
644{ 737{
651 printf (_("interface: %s\n"), ifname); 744 printf (_("interface: %s\n"), ifname);
652 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 745 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
653 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1); 746 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
654 printf ("\n"); 747 printf ("\n");
655 748
656 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 749 printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n",
657 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 750 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port"));
658 751
659 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) 752 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
660 (*i)->print (); 753 (*i)->print ();
661 754
662 printf ("\n"); 755 printf ("\n");
672configuration::~configuration () 765configuration::~configuration ()
673{ 766{
674 cleanup (); 767 cleanup ();
675} 768}
676 769
677

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines