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.59 by root, Tue Dec 4 10:29:43 2012 UTC vs.
Revision 1.67 by root, Thu Oct 25 04:32:27 2018 UTC

1/* 1/*
2 conf.C -- configuration code 2 conf.C -- configuration code
3 Copyright (C) 2003-2008,2011 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2011,2018 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
161 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 161 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
162 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 162 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
163 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING; 163 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING;
164#endif 164#endif
165 165
166 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 166 pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
167 seed_dev = strdup ("/dev/urandom");
168 reseed = DEFAULT_RESEED;
167} 169}
168 170
169void 171void
170configuration::cleanup () 172configuration::cleanup ()
171{ 173{
172 if (rsa_key) 174 if (rsa_key)
173 RSA_free (rsa_key); 175 RSA_free (rsa_key);
174 176
175 rsa_key = 0; 177 rsa_key = 0;
176 178
179 free (seed_dev); seed_dev = 0;
177 free (pidfilename); pidfilename = 0; 180 free (pidfilename); pidfilename = 0;
178 free (ifname); ifname = 0; 181 free (ifname); ifname = 0;
179#if ENABLE_HTTP_PROXY 182#if ENABLE_HTTP_PROXY
180 free (proxy_host); proxy_host = 0; 183 free (proxy_host); proxy_host = 0;
181 free (proxy_auth); proxy_auth = 0; 184 free (proxy_auth); proxy_auth = 0;
198 201
199 nodes.clear (); 202 nodes.clear ();
200 203
201 cleanup (); 204 cleanup ();
202 init (); 205 init ();
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;
203} 216}
204 217
205//static bool 218//static bool
206//is_true (const char *name) 219//is_true (const char *name)
207//{ 220//{
223configuration_parser::parse_line (char *line) 236configuration_parser::parse_line (char *line)
224{ 237{
225 { 238 {
226 char *end = line + strlen (line); 239 char *end = line + strlen (line);
227 240
228 while (*end < ' ' && end >= line) 241 while (end >= line && *end < ' ')
229 end--; 242 end--;
230 243
231 *++end = 0; 244 *++end = 0;
232 } 245 }
233 246
238 if (!var || !var[0]) 251 if (!var || !var[0])
239 return 0; /* no tokens on this line */ 252 return 0; /* no tokens on this line */
240 253
241 if (var[0] == '#') 254 if (var[0] == '#')
242 return 0; /* comment: ignore */ 255 return 0; /* comment: ignore */
256
257 if (!strcmp (var, "global"))
258 {
259 node = &conf.default_node;
260 return 0;
261 }
243 262
244 char *val = strtok (NULL, "\t\n\r ="); 263 char *val = strtok (NULL, "\t\n\r =");
245 264
246 if (!val || val[0] == '#') 265 if (!val || val[0] == '#')
247 return _("no value given for variable, ignored"); 266 return _("no value given for variable, ignored");
267 loglevel l = string_to_loglevel (val); 286 loglevel l = string_to_loglevel (val);
268 287
269 if (l == L_NONE) 288 if (l == L_NONE)
270 return _("unknown loglevel, ignored"); 289 return _("unknown loglevel, ignored");
271 } 290 }
291 else if (!strcmp (var, "serial"))
292 strncpy (conf.serial, val, sizeof (conf.serial));
272 else if (!strcmp (var, "ip-proto")) 293 else if (!strcmp (var, "ip-proto"))
273 conf.ip_proto = atoi (val); 294 conf.ip_proto = atoi (val);
274 else if (!strcmp (var, "icmp-type")) 295 else if (!strcmp (var, "icmp-type"))
275 { 296 {
276#if ENABLE_ICMP 297#if ENABLE_ICMP
294 free (conf.change_root), conf.change_root = strdup (val); 315 free (conf.change_root), conf.change_root = strdup (val);
295 316
296 // per node 317 // per node
297 else if (!strcmp (var, "node")) 318 else if (!strcmp (var, "node"))
298 { 319 {
299 parse_argv (); 320 node = conf.find_node (val);
300 321
322 if (!node)
323 {
301 conf.default_node.id++; 324 conf.default_node.id++;
302 node = new conf_node (conf.default_node); 325 node = new conf_node (conf.default_node);
303 conf.nodes.push_back (node); 326 conf.nodes.push_back (node);
304 node->nodename = strdup (val); 327 node->nodename = strdup (val);
305
306 {
307 char *fname;
308 FILE *f;
309
310 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
311
312 f = fopen (fname, "r");
313 if (f)
314 {
315 node->rsa_key = RSA_new ();
316
317 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
318 {
319 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
320 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
321 exit (EXIT_FAILURE);
322 }
323
324 require (RSA_blinding_on (node->rsa_key, 0));
325
326 fclose (f);
327 } 328 }
328 else
329 {
330 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
331
332 if (need_keys)
333 exit (EXIT_FAILURE);
334 }
335
336 free (fname);
337 }
338
339 if (::thisnode && !strcmp (node->nodename, ::thisnode))
340 conf.thisnode = node;
341 } 329 }
342 else if (!strcmp (var, "private-key")) 330 else if (!strcmp (var, "private-key"))
343 free (conf.prikeyfile), conf.prikeyfile = strdup (val); 331 free (conf.prikeyfile), conf.prikeyfile = strdup (val);
344 else if (!strcmp (var, "ifpersist")) 332 else if (!strcmp (var, "ifpersist"))
345 parse_bool (conf.ifpersist, "ifpersist", true, false); 333 parse_bool (conf.ifpersist, "ifpersist", true, false);
351 conf.keepalive = atoi (val); 339 conf.keepalive = atoi (val);
352 else if (!strcmp (var, "mtu")) 340 else if (!strcmp (var, "mtu"))
353 conf.mtu = atoi (val); 341 conf.mtu = atoi (val);
354 else if (!strcmp (var, "nfmark")) 342 else if (!strcmp (var, "nfmark"))
355 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);
356 else if (!strcmp (var, "if-up")) 348 else if (!strcmp (var, "if-up"))
357 free (conf.script_if_up), conf.script_if_up = strdup (val); 349 free (conf.script_if_up), conf.script_if_up = strdup (val);
358 else if (!strcmp (var, "node-up")) 350 else if (!strcmp (var, "node-up"))
359 free (conf.script_node_up), conf.script_node_up = strdup (val); 351 free (conf.script_node_up), conf.script_node_up = strdup (val);
360 else if (!strcmp (var, "node-change")) 352 else if (!strcmp (var, "node-change"))
472 } 464 }
473 else if (!strcmp (var, "inherit-tos")) 465 else if (!strcmp (var, "inherit-tos"))
474 parse_bool (node->inherit_tos, "inherit-tos", true, false); 466 parse_bool (node->inherit_tos, "inherit-tos", true, false);
475 else if (!strcmp (var, "compress")) 467 else if (!strcmp (var, "compress"))
476 parse_bool (node->compress, "compress", true, false); 468 parse_bool (node->compress, "compress", true, false);
469 else if (!strcmp (var, "low-power"))
470 parse_bool (node->low_power, "low-power", true, false);
477 // all these bool options really really cost a lot of executable size! 471 // all these bool options really really cost a lot of executable size!
478 else if (!strcmp (var, "enable-tcp")) 472 else if (!strcmp (var, "enable-tcp"))
479 { 473 {
480#if ENABLE_TCP 474#if ENABLE_TCP
481 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v; 475 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v;
532 connectmode = C_ALWAYS; 526 connectmode = C_ALWAYS;
533 } 527 }
534} 528}
535 529
536void 530void
537configuration_parser::parse_argv ()
538{
539 for (int i = 0; i < argc; ++i)
540 {
541 char *v = argv [i];
542
543 if (!*v)
544 continue;
545
546 char *enode = v;
547
548 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
549 enode++;
550
551 if (*enode != '.')
552 enode = 0;
553
554 char *wnode = node == &conf.default_node
555 ? 0
556 : node->nodename;
557
558 if ((!wnode && !enode)
559 || (wnode && enode && !strncmp (wnode, v, enode - v)))
560 {
561 const char *warn = parse_line (enode ? enode + 1 : v);
562
563 if (warn)
564 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
565
566 *v = 0;
567 }
568 }
569}
570
571void
572configuration_parser::parse_file (const char *fname) 531configuration_parser::parse_file (const char *fname)
573{ 532{
574 if (FILE *f = fopen (fname, "r")) 533 if (FILE *f = fopen (fname, "r"))
575 { 534 {
576 char line [2048]; 535 char line [2048];
585 if (warn) 544 if (warn)
586 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno); 545 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
587 } 546 }
588 547
589 fclose (f); 548 fclose (f);
590
591 parse_argv ();
592 } 549 }
593 else 550 else
594 { 551 {
595 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno)); 552 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
596 exit (EXIT_FAILURE); 553 exit (EXIT_FAILURE);
599 556
600configuration_parser::configuration_parser (configuration &conf, 557configuration_parser::configuration_parser (configuration &conf,
601 bool need_keys, 558 bool need_keys,
602 int argc, 559 int argc,
603 char **argv) 560 char **argv)
604: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 561: conf (conf), need_keys (need_keys), argc (argc), argv (argv)
605{ 562{
606 char *fname; 563 char *fname;
607 564
608 conf.clear (); 565 conf.clear ();
609 node = &conf.default_node; 566 node = &conf.default_node;
629 586
630 fclose (f); 587 fclose (f);
631 } 588 }
632 else 589 else
633 { 590 {
634 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
635
636 if (need_keys) 591 if (need_keys)
592 {
593 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
637 exit (EXIT_FAILURE); 594 exit (EXIT_FAILURE);
595 }
638 } 596 }
639 597
640 free (fname); 598 free (fname);
641 599
642 if (need_keys && ::thisnode 600 fname = conf.config_filename (conf.pidfilename);
643 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key) 601 free (conf.pidfilename); conf.pidfilename = fname;
644 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
645 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
646 {
647 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
648 exit (EXIT_FAILURE);
649 }
650 602
651 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i) 603 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
604 {
605 conf_node *node = *i;
606 char *fname;
607 FILE *f;
608
609 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
610
611 f = fopen (fname, "r");
612 if (f)
613 {
614 node->rsa_key = RSA_new ();
615
616 if (!PEM_read_RSAPublicKey (f, &node->rsa_key, NULL, NULL))
617 {
618 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
619 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
620 exit (EXIT_FAILURE);
621 }
622
623 require (RSA_blinding_on (node->rsa_key, 0));
624
625 fclose (f);
626 }
627 else
628 {
629 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
630
631 if (need_keys)
632 exit (EXIT_FAILURE);
633 }
634
635 free (fname);
636
652 (*i)->finalise (); 637 (*i)->finalise ();
638 }
639
640 if (::thisnode)
641 {
642 conf.thisnode = conf.find_node (::thisnode);
643
644 if (need_keys)
645 {
646 if (!conf.thisnode)
647 {
648 slog (L_NOTICE, _("local node ('%s') not found in config file, aborting."), ::thisnode);
649 exit (EXIT_FAILURE);
650 }
651
652 if (conf.rsa_key && conf.thisnode->rsa_key)
653 {
654 const BIGNUM *conf_n, *conf_e, *thisnode_n, *thisnode_e;
655
656#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !LIBRESSL_VERSION_NUMBER
657 RSA_get0_key (conf.rsa_key, &conf_n, &conf_e, 0);
658 RSA_get0_key (conf.thisnode->rsa_key, &thisnode_n, &thisnode_e, 0);
659#else
660 conf_n = conf.thisnode->rsa_key->n;
661 conf_e = conf.thisnode->rsa_key->e;
662 thisnode_n = conf.rsa_key->n;
663 thisnode_e = conf.rsa_key->e;
664#endif
665 if (BN_cmp (conf_n, thisnode_n) != 0 || BN_cmp (conf_e, thisnode_e) != 0)
666 {
667 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
668 exit (EXIT_FAILURE);
669 }
670 }
671 }
672 }
673
674 parse_argv ();
675}
676
677void
678configuration_parser::parse_argv ()
679{
680 for (int i = 0; i < argc; ++i)
681 {
682 char *v = argv [i];
683
684 if (!*v)
685 continue;
686
687 char *enode = v;
688
689 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
690 enode++;
691
692 if (*enode != '.')
693 enode = 0;
694
695 if (enode)
696 {
697 char *val = strdup (v);
698 val [enode - v] = 0;
699 node = conf.find_node (val);
700 free (val);
701
702 if (!node)
703 {
704 slog (L_WARN, _("command line option '%s' refers to unknown node, ignoring."), v);
705 continue;
706 }
707 }
708 else
709 node = &conf.default_node;
710
711 const char *warn = parse_line (enode ? enode + 1 : v);
712
713 if (warn)
714 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
715 }
653} 716}
654 717
655char * 718char *
656configuration::config_filename (const char *name, const char *dflt) 719configuration::config_filename (const char *name, const char *dflt)
657{ 720{
658 char *fname; 721 char *fname;
659 722
660 asprintf (&fname, name ? name : dflt, ::thisnode); 723 asprintf (&fname, name ? name : dflt, ::thisnode ? ::thisnode : "<unset>");
661 724
662 if (!ABSOLUTE_PATH (fname)) 725 if (!ABSOLUTE_PATH (fname))
663 { 726 {
664 char *rname = fname; 727 char *rname = fname;
665 asprintf (&fname, "%s/%s", confbase, rname); 728 asprintf (&fname, "%s/%s", confbase, rname);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines