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.51 by pcg, Sat Jul 18 05:59:16 2009 UTC vs.
Revision 1.64 by root, Thu Jul 18 17:35:10 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;
199 free (script_if_up); script_if_up = 0; 190 free (script_if_up); script_if_up = 0;
200 free (script_node_up); script_node_up = 0; 191 free (script_node_up); script_node_up = 0;
201 free (script_node_change); script_node_change = 0; 192 free (script_node_change); script_node_change = 0;
202 free (script_node_down); script_node_down = 0; 193 free (script_node_down); script_node_down = 0;
203} 194}
211 nodes.clear (); 202 nodes.clear ();
212 203
213 cleanup (); 204 cleanup ();
214 init (); 205 init ();
215} 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//}
216 223
217#define parse_bool(target,name,trueval,falseval) do { \ 224#define parse_bool(target,name,trueval,falseval) do { \
218 if (!strcmp (val, "yes")) target = trueval; \ 225 if (!strcmp (val, "yes")) target = trueval; \
219 else if (!strcmp (val, "no")) target = falseval; \ 226 else if (!strcmp (val, "no")) target = falseval; \
220 else if (!strcmp (val, "true")) target = trueval; \ 227 else if (!strcmp (val, "true")) target = trueval; \
221 else if (!strcmp (val, "false")) target = falseval; \ 228 else if (!strcmp (val, "false")) target = falseval; \
222 else if (!strcmp (val, "on")) target = trueval; \ 229 else if (!strcmp (val, "on")) target = trueval; \
223 else if (!strcmp (val, "off")) target = falseval; \ 230 else if (!strcmp (val, "off")) target = falseval; \
224 else \ 231 else \
225 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"); \
226} while (0) 233} while (0)
227 234
228const char * 235const char *
229configuration_parser::parse_line (char *line) 236configuration_parser::parse_line (char *line)
230{ 237{
245 return 0; /* no tokens on this line */ 252 return 0; /* no tokens on this line */
246 253
247 if (var[0] == '#') 254 if (var[0] == '#')
248 return 0; /* comment: ignore */ 255 return 0; /* comment: ignore */
249 256
257 if (!strcmp (var, "global"))
258 {
259 node = &conf.default_node;
260 return 0;
261 }
262
250 char *val = strtok (NULL, "\t\n\r ="); 263 char *val = strtok (NULL, "\t\n\r =");
251 264
252 if (!val || val[0] == '#') 265 if (!val || val[0] == '#')
253 return _("no value given for variable. (ignored)"); 266 return _("no value given for variable, ignored");
254 267
255 if (!strcmp (var, "on")) 268 else if (!strcmp (var, "on"))
256 { 269 {
257 if (!::thisnode 270 if (::thisnode
258 || (val[0] == '!' && strcmp (val + 1, ::thisnode)) 271 && ((val[0] == '!' && strcmp (val + 1, ::thisnode))
259 || !strcmp (val, ::thisnode)) 272 || !strcmp (val, ::thisnode)))
260 return parse_line (strtok (NULL, "\n\r")); 273 return parse_line (strtok (NULL, "\n\r"));
261 else 274 }
262 return 0; 275
276 else if (!strcmp (var, "include"))
277 {
278 char *fname = conf.config_filename (val);
279 parse_file (fname);
280 free (fname);
263 } 281 }
264 282
265 // truly global 283 // truly global
266 if (!strcmp (var, "loglevel")) 284 else if (!strcmp (var, "loglevel"))
267 { 285 {
268 loglevel l = string_to_loglevel (val); 286 loglevel l = string_to_loglevel (val);
269 287
270 if (l == L_NONE) 288 if (l == L_NONE)
271 return _("unknown loglevel. (skipping)"); 289 return _("unknown loglevel, ignored");
272 } 290 }
291 else if (!strcmp (var, "serial"))
292 strncpy (conf.serial, val, sizeof (conf.serial));
273 else if (!strcmp (var, "ip-proto")) 293 else if (!strcmp (var, "ip-proto"))
274 conf.ip_proto = atoi (val); 294 conf.ip_proto = atoi (val);
275 else if (!strcmp (var, "icmp-type")) 295 else if (!strcmp (var, "icmp-type"))
276 { 296 {
277#if ENABLE_ICMP 297#if ENABLE_ICMP
278 conf.icmp_type = atoi (val); 298 conf.icmp_type = atoi (val);
279#endif 299#endif
280 } 300 }
301 else if (!strcmp (var, "chuser"))
302 {
303 struct passwd *pw = getpwnam (val);
304 if (!pw)
305 return _("user specified for chuser not found");
281 306
282 // per config 307 conf.change_uid = pw->pw_uid;
308 conf.change_gid = pw->pw_gid;
309 }
310 else if (!strcmp (var, "chuid"))
311 conf.change_uid = atoi (val);
312 else if (!strcmp (var, "chgid"))
313 conf.change_gid = atoi (val);
314 else if (!strcmp (var, "chroot"))
315 free (conf.change_root), conf.change_root = strdup (val);
316
317 // per node
283 else if (!strcmp (var, "node")) 318 else if (!strcmp (var, "node"))
284 { 319 {
285 parse_argv (); 320 node = conf.find_node (val);
286 321
322 if (!node)
323 {
287 conf.default_node.id++; 324 conf.default_node.id++;
288 node = new conf_node (conf.default_node); 325 node = new conf_node (conf.default_node);
289 conf.nodes.push_back (node); 326 conf.nodes.push_back (node);
290 node->nodename = strdup (val); 327 node->nodename = strdup (val);
291
292 {
293 char *fname;
294 FILE *f;
295
296 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
297
298 f = fopen (fname, "r");
299 if (f)
300 {
301 node->rsa_key = RSA_new ();
302
303 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
304 {
305 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
306 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
307 exit (EXIT_FAILURE);
308 }
309
310 require (RSA_blinding_on (node->rsa_key, 0));
311
312 fclose (f);
313 } 328 }
314 else
315 {
316 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
317
318 if (need_keys)
319 exit (EXIT_FAILURE);
320 }
321
322 free (fname);
323 }
324
325 if (::thisnode && !strcmp (node->nodename, ::thisnode))
326 conf.thisnode = node;
327 } 329 }
328 else if (!strcmp (var, "private-key")) 330 else if (!strcmp (var, "private-key"))
329 free (conf.prikeyfile), conf.prikeyfile = strdup (val); 331 free (conf.prikeyfile), conf.prikeyfile = strdup (val);
330 else if (!strcmp (var, "ifpersist")) 332 else if (!strcmp (var, "ifpersist"))
331 parse_bool (conf.ifpersist, "ifpersist", true, false); 333 parse_bool (conf.ifpersist, "ifpersist", true, false);
337 conf.keepalive = atoi (val); 339 conf.keepalive = atoi (val);
338 else if (!strcmp (var, "mtu")) 340 else if (!strcmp (var, "mtu"))
339 conf.mtu = atoi (val); 341 conf.mtu = atoi (val);
340 else if (!strcmp (var, "nfmark")) 342 else if (!strcmp (var, "nfmark"))
341 conf.nfmark = atoi (val); 343 conf.nfmark = atoi (val);
344 else if (!strcmp (var, "seed-device"))
345 free (conf.seed_dev), conf.seed_dev = strdup (val);
346 else if (!strcmp (var, "seed-interval"))
347 conf.reseed = atoi (val);
342 else if (!strcmp (var, "if-up")) 348 else if (!strcmp (var, "if-up"))
343 free (conf.script_if_up), conf.script_if_up = strdup (val); 349 free (conf.script_if_up), conf.script_if_up = strdup (val);
344 else if (!strcmp (var, "node-up")) 350 else if (!strcmp (var, "node-up"))
345 free (conf.script_node_up), conf.script_node_up = strdup (val); 351 free (conf.script_node_up), conf.script_node_up = strdup (val);
346 else if (!strcmp (var, "node-change")) 352 else if (!strcmp (var, "node-change"))
383 { 389 {
384#if ENABLE_DNS 390#if ENABLE_DNS
385 conf.dns_max_outstanding = atoi (val); 391 conf.dns_max_outstanding = atoi (val);
386#endif 392#endif
387 } 393 }
394 else if (!strcmp (var, "dns-case-preserving"))
395 {
396#if ENABLE_DNS
397 parse_bool (conf.dns_case_preserving, "dns-case-preserving", true, false);
398#endif
399 }
388 else if (!strcmp (var, "http-proxy-host")) 400 else if (!strcmp (var, "http-proxy-host"))
389 { 401 {
390#if ENABLE_HTTP_PROXY 402#if ENABLE_HTTP_PROXY
391 free (conf.proxy_host), conf.proxy_host = strdup (val); 403 free (conf.proxy_host), conf.proxy_host = strdup (val);
392#endif 404#endif
446 else if (!strcmp (val, "always")) 458 else if (!strcmp (val, "always"))
447 node->connectmode = conf_node::C_ALWAYS; 459 node->connectmode = conf_node::C_ALWAYS;
448 else if (!strcmp (val, "disabled")) 460 else if (!strcmp (val, "disabled"))
449 node->connectmode = conf_node::C_DISABLED; 461 node->connectmode = conf_node::C_DISABLED;
450 else 462 else
451 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled'. (ignored)"); 463 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', ignored");
452 } 464 }
453 else if (!strcmp (var, "inherit-tos")) 465 else if (!strcmp (var, "inherit-tos"))
454 parse_bool (node->inherit_tos, "inherit-tos", true, false); 466 parse_bool (node->inherit_tos, "inherit-tos", true, false);
455 else if (!strcmp (var, "compress")) 467 else if (!strcmp (var, "compress"))
456 parse_bool (node->compress, "compress", true, false); 468 parse_bool (node->compress, "compress", true, false);
490 else if (!strcmp (var, "max-queue")) 502 else if (!strcmp (var, "max-queue"))
491 node->max_queue = atoi (val); 503 node->max_queue = atoi (val);
492 504
493 // unknown or misplaced 505 // unknown or misplaced
494 else 506 else
495 return _("unknown configuration directive. (ignored)"); 507 return _("unknown configuration directive - ignored");
496 508
497 return 0; 509 return 0;
498} 510}
499 511
512void
500void conf_node::finalise () 513conf_node::finalise ()
501{ 514{
502 if (max_queue < 1) 515 if (max_queue < 1)
503 { 516 {
504 slog (L_WARN, _("%s: max-queue value invalid, setting it to 1."), nodename); 517 slog (L_WARN, _("%s: max-queue value invalid, setting it to 1."), nodename);
505 max_queue = 1; 518 max_queue = 1;
510 //slog (L_WARN, _("%s: has non-zero router-priority but either 'never' or 'ondemand' as connectmode, setting it to 'always'."), nodename); 523 //slog (L_WARN, _("%s: has non-zero router-priority but either 'never' or 'ondemand' as connectmode, setting it to 'always'."), nodename);
511 connectmode = C_ALWAYS; 524 connectmode = C_ALWAYS;
512 } 525 }
513} 526}
514 527
515void configuration_parser::parse_argv () 528void
529configuration_parser::parse_file (const char *fname)
516{ 530{
517 for (int i = 0; i < argc; ++i) 531 if (FILE *f = fopen (fname, "r"))
518 { 532 {
519 char *v = argv [i]; 533 char line [2048];
534 int lineno = 0;
520 535
521 if (!*v) 536 while (fgets (line, sizeof (line), f))
522 continue;
523
524 char *enode = v;
525
526 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
527 enode++;
528
529 if (*enode != '.')
530 enode = 0;
531
532 char *wnode = node == &conf.default_node
533 ? 0
534 : node->nodename;
535
536 if ((!wnode && !enode)
537 || (wnode && enode && !strncmp (wnode, v, enode - v)))
538 { 537 {
538 lineno++;
539
539 const char *warn = parse_line (enode ? enode + 1 : v); 540 const char *warn = parse_line (line);
540 541
541 if (warn) 542 if (warn)
542 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); 543 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
543
544 *v = 0;
545 } 544 }
545
546 fclose (f);
547 }
548 else
549 {
550 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
551 exit (EXIT_FAILURE);
546 } 552 }
547} 553}
548 554
549configuration_parser::configuration_parser (configuration &conf, 555configuration_parser::configuration_parser (configuration &conf,
550 bool need_keys, 556 bool need_keys,
551 int argc, 557 int argc,
552 char **argv) 558 char **argv)
553: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 559: conf (conf), need_keys (need_keys), argc (argc), argv (argv)
554{ 560{
555 char *fname; 561 char *fname;
556 FILE *f;
557 562
558 conf.clear (); 563 conf.clear ();
564 node = &conf.default_node;
559 565
560 asprintf (&fname, "%s/gvpe.conf", confbase); 566 asprintf (&fname, "%s/gvpe.conf", confbase);
561 f = fopen (fname, "r"); 567 parse_file (fname);
562
563 if (f)
564 {
565 char line[16384];
566 int lineno = 0;
567 node = &conf.default_node;
568
569 while (fgets (line, sizeof (line), f))
570 {
571 lineno++;
572
573 const char *warn = parse_line (line);
574
575 if (warn)
576 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
577 }
578
579 fclose (f);
580
581 parse_argv ();
582 }
583 else
584 {
585 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
586 exit (EXIT_FAILURE);
587 }
588
589 free (fname); 568 free (fname);
590 569
591 fname = conf.config_filename (conf.prikeyfile, "hostkey"); 570 fname = conf.config_filename (conf.prikeyfile, "hostkey");
592 571
593 f = fopen (fname, "r"); 572 if (FILE *f = fopen (fname, "r"))
594 if (f)
595 { 573 {
596 conf.rsa_key = RSA_new (); 574 conf.rsa_key = RSA_new ();
597 575
598 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL)) 576 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
599 { 577 {
606 584
607 fclose (f); 585 fclose (f);
608 } 586 }
609 else 587 else
610 { 588 {
611 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
612
613 if (need_keys) 589 if (need_keys)
590 {
591 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
614 exit (EXIT_FAILURE); 592 exit (EXIT_FAILURE);
615 }
616
617 if (need_keys && ::thisnode
618 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
619 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
620 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
621 {
622 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
623 exit (EXIT_FAILURE);
624 } 593 }
594 }
625 595
626 free (fname); 596 free (fname);
627 597
598 fname = conf.config_filename (conf.pidfilename);
599 free (conf.pidfilename); conf.pidfilename = fname;
600
628 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i) 601 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
602 {
603 conf_node *node = *i;
604 char *fname;
605 FILE *f;
606
607 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
608
609 f = fopen (fname, "r");
610 if (f)
611 {
612 node->rsa_key = RSA_new ();
613
614 if (!PEM_read_RSAPublicKey (f, &node->rsa_key, NULL, NULL))
615 {
616 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
617 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
618 exit (EXIT_FAILURE);
619 }
620
621 require (RSA_blinding_on (node->rsa_key, 0));
622
623 fclose (f);
624 }
625 else
626 {
627 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
628
629 if (need_keys)
630 exit (EXIT_FAILURE);
631 }
632
633 free (fname);
634
629 (*i)->finalise (); 635 (*i)->finalise ();
630} 636 }
631 637
638 if (::thisnode)
639 {
640 conf.thisnode = conf.find_node (::thisnode);
641
642 if (need_keys)
643 {
644 if (!conf.thisnode)
645 {
646 slog (L_NOTICE, _("local node ('%s') not found in config file, aborting."), ::thisnode);
647 exit (EXIT_FAILURE);
648 }
649
650 if (conf.rsa_key && conf.thisnode->rsa_key)
651 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
652 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
653 {
654 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
655 exit (EXIT_FAILURE);
656 }
657 }
658 }
659
660 parse_argv ();
661}
662
663void
664configuration_parser::parse_argv ()
665{
666 for (int i = 0; i < argc; ++i)
667 {
668 char *v = argv [i];
669
670 if (!*v)
671 continue;
672
673 char *enode = v;
674
675 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
676 enode++;
677
678 if (*enode != '.')
679 enode = 0;
680
681 if (enode)
682 {
683 char *val = strdup (v);
684 val [enode - v] = 0;
685 node = conf.find_node (val);
686 free (val);
687
688 if (!node)
689 {
690 slog (L_WARN, _("command line option '%s' refers to unknown node, ignoring."), v);
691 continue;
692 }
693 }
694 else
695 node = &conf.default_node;
696
697 const char *warn = parse_line (enode ? enode + 1 : v);
698
699 if (warn)
700 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
701 }
702}
703
704char *
632char *configuration::config_filename (const char *name, const char *dflt) 705configuration::config_filename (const char *name, const char *dflt)
633{ 706{
634 char *fname; 707 char *fname;
635 708
636 asprintf (&fname, name ? name : dflt, ::thisnode); 709 asprintf (&fname, name ? name : dflt, ::thisnode ? ::thisnode : "<unset>");
637 710
638 if (!ABSOLUTE_PATH (fname)) 711 if (!ABSOLUTE_PATH (fname))
639 { 712 {
640 char *rname = fname; 713 char *rname = fname;
641 asprintf (&fname, "%s/%s", confbase, rname); 714 asprintf (&fname, "%s/%s", confbase, rname);
642 free (rname); 715 free (rname);
643 } 716 }
644 717
645 return fname; 718 return fname;
719}
720
721void
722conf_node::print ()
723{
724 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %02x %s%s%d\n",
725 id,
726 id >> 8, id & 0xff,
727 compress ? 'Y' : 'N',
728 connectmode == C_ONDEMAND ? "ondemand"
729 : connectmode == C_NEVER ? "never"
730 : connectmode == C_ALWAYS ? "always"
731 : connectmode == C_DISABLED ? "disabled"
732 : "",
733 nodename,
734 protocols,
735 hostname ? hostname : "",
736 hostname ? ":" : "",
737 hostname ? udp_port : 0
738 );
646} 739}
647 740
648void 741void
649configuration::print () 742configuration::print ()
650{ 743{
657 printf (_("interface: %s\n"), ifname); 750 printf (_("interface: %s\n"), ifname);
658 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 751 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
659 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1); 752 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
660 printf ("\n"); 753 printf ("\n");
661 754
662 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 755 printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n",
663 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 756 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port"));
664 757
665 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) 758 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
666 (*i)->print (); 759 (*i)->print ();
667 760
668 printf ("\n"); 761 printf ("\n");
678configuration::~configuration () 771configuration::~configuration ()
679{ 772{
680 cleanup (); 773 cleanup ();
681} 774}
682 775
683

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines