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.58 by root, Tue Jan 17 21:38:10 2012 UTC vs.
Revision 1.64 by root, Thu Jul 18 17:35:10 2013 UTC

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>
160 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 161 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
161 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 162 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
162 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING; 163 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING;
163#endif 164#endif
164 165
165 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 166 pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
167 seed_dev = strdup ("/dev/urandom");
168 reseed = DEFAULT_RESEED;
166} 169}
167 170
168void 171void
169configuration::cleanup () 172configuration::cleanup ()
170{ 173{
171 if (rsa_key) 174 if (rsa_key)
172 RSA_free (rsa_key); 175 RSA_free (rsa_key);
173 176
174 rsa_key = 0; 177 rsa_key = 0;
175 178
179 free (seed_dev); seed_dev = 0;
176 free (pidfilename); pidfilename = 0; 180 free (pidfilename); pidfilename = 0;
177 free (ifname); ifname = 0; 181 free (ifname); ifname = 0;
178#if ENABLE_HTTP_PROXY 182#if ENABLE_HTTP_PROXY
179 free (proxy_host); proxy_host = 0; 183 free (proxy_host); proxy_host = 0;
180 free (proxy_auth); proxy_auth = 0; 184 free (proxy_auth); proxy_auth = 0;
181#endif 185#endif
182#if ENABLE_DNS 186#if ENABLE_DNS
183 free (dns_forw_host); dns_forw_host = 0; 187 free (dns_forw_host); dns_forw_host = 0;
184#endif 188#endif
189 free (change_root); change_root = 0;
185 free (script_if_up); script_if_up = 0; 190 free (script_if_up); script_if_up = 0;
186 free (script_node_up); script_node_up = 0; 191 free (script_node_up); script_node_up = 0;
187 free (script_node_change); script_node_change = 0; 192 free (script_node_change); script_node_change = 0;
188 free (script_node_down); script_node_down = 0; 193 free (script_node_down); script_node_down = 0;
189} 194}
196 201
197 nodes.clear (); 202 nodes.clear ();
198 203
199 cleanup (); 204 cleanup ();
200 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;
201} 216}
202 217
203//static bool 218//static bool
204//is_true (const char *name) 219//is_true (const char *name)
205//{ 220//{
237 return 0; /* no tokens on this line */ 252 return 0; /* no tokens on this line */
238 253
239 if (var[0] == '#') 254 if (var[0] == '#')
240 return 0; /* comment: ignore */ 255 return 0; /* comment: ignore */
241 256
257 if (!strcmp (var, "global"))
258 {
259 node = &conf.default_node;
260 return 0;
261 }
262
242 char *val = strtok (NULL, "\t\n\r ="); 263 char *val = strtok (NULL, "\t\n\r =");
243 264
244 if (!val || val[0] == '#') 265 if (!val || val[0] == '#')
245 return _("no value given for variable, ignored"); 266 return _("no value given for variable, ignored");
246 267
265 loglevel l = string_to_loglevel (val); 286 loglevel l = string_to_loglevel (val);
266 287
267 if (l == L_NONE) 288 if (l == L_NONE)
268 return _("unknown loglevel, ignored"); 289 return _("unknown loglevel, ignored");
269 } 290 }
291 else if (!strcmp (var, "serial"))
292 strncpy (conf.serial, val, sizeof (conf.serial));
270 else if (!strcmp (var, "ip-proto")) 293 else if (!strcmp (var, "ip-proto"))
271 conf.ip_proto = atoi (val); 294 conf.ip_proto = atoi (val);
272 else if (!strcmp (var, "icmp-type")) 295 else if (!strcmp (var, "icmp-type"))
273 { 296 {
274#if ENABLE_ICMP 297#if ENABLE_ICMP
275 conf.icmp_type = atoi (val); 298 conf.icmp_type = atoi (val);
276#endif 299#endif
277 } 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");
278 306
279 // 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
280 else if (!strcmp (var, "node")) 318 else if (!strcmp (var, "node"))
281 { 319 {
282 parse_argv (); 320 node = conf.find_node (val);
283 321
322 if (!node)
323 {
284 conf.default_node.id++; 324 conf.default_node.id++;
285 node = new conf_node (conf.default_node); 325 node = new conf_node (conf.default_node);
286 conf.nodes.push_back (node); 326 conf.nodes.push_back (node);
287 node->nodename = strdup (val); 327 node->nodename = strdup (val);
288
289 {
290 char *fname;
291 FILE *f;
292
293 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
294
295 f = fopen (fname, "r");
296 if (f)
297 {
298 node->rsa_key = RSA_new ();
299
300 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
301 {
302 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
303 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
304 exit (EXIT_FAILURE);
305 }
306
307 require (RSA_blinding_on (node->rsa_key, 0));
308
309 fclose (f);
310 } 328 }
311 else
312 {
313 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
314
315 if (need_keys)
316 exit (EXIT_FAILURE);
317 }
318
319 free (fname);
320 }
321
322 if (::thisnode && !strcmp (node->nodename, ::thisnode))
323 conf.thisnode = node;
324 } 329 }
325 else if (!strcmp (var, "private-key")) 330 else if (!strcmp (var, "private-key"))
326 free (conf.prikeyfile), conf.prikeyfile = strdup (val); 331 free (conf.prikeyfile), conf.prikeyfile = strdup (val);
327 else if (!strcmp (var, "ifpersist")) 332 else if (!strcmp (var, "ifpersist"))
328 parse_bool (conf.ifpersist, "ifpersist", true, false); 333 parse_bool (conf.ifpersist, "ifpersist", true, false);
334 conf.keepalive = atoi (val); 339 conf.keepalive = atoi (val);
335 else if (!strcmp (var, "mtu")) 340 else if (!strcmp (var, "mtu"))
336 conf.mtu = atoi (val); 341 conf.mtu = atoi (val);
337 else if (!strcmp (var, "nfmark")) 342 else if (!strcmp (var, "nfmark"))
338 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);
339 else if (!strcmp (var, "if-up")) 348 else if (!strcmp (var, "if-up"))
340 free (conf.script_if_up), conf.script_if_up = strdup (val); 349 free (conf.script_if_up), conf.script_if_up = strdup (val);
341 else if (!strcmp (var, "node-up")) 350 else if (!strcmp (var, "node-up"))
342 free (conf.script_node_up), conf.script_node_up = strdup (val); 351 free (conf.script_node_up), conf.script_node_up = strdup (val);
343 else if (!strcmp (var, "node-change")) 352 else if (!strcmp (var, "node-change"))
515 connectmode = C_ALWAYS; 524 connectmode = C_ALWAYS;
516 } 525 }
517} 526}
518 527
519void 528void
520configuration_parser::parse_argv ()
521{
522 for (int i = 0; i < argc; ++i)
523 {
524 char *v = argv [i];
525
526 if (!*v)
527 continue;
528
529 char *enode = v;
530
531 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
532 enode++;
533
534 if (*enode != '.')
535 enode = 0;
536
537 char *wnode = node == &conf.default_node
538 ? 0
539 : node->nodename;
540
541 if ((!wnode && !enode)
542 || (wnode && enode && !strncmp (wnode, v, enode - v)))
543 {
544 const char *warn = parse_line (enode ? enode + 1 : v);
545
546 if (warn)
547 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
548
549 *v = 0;
550 }
551 }
552}
553
554void
555configuration_parser::parse_file (const char *fname) 529configuration_parser::parse_file (const char *fname)
556{ 530{
557 if (FILE *f = fopen (fname, "r")) 531 if (FILE *f = fopen (fname, "r"))
558 { 532 {
559 char line [2048]; 533 char line [2048];
568 if (warn) 542 if (warn)
569 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno); 543 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
570 } 544 }
571 545
572 fclose (f); 546 fclose (f);
573
574 parse_argv ();
575 } 547 }
576 else 548 else
577 { 549 {
578 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno)); 550 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
579 exit (EXIT_FAILURE); 551 exit (EXIT_FAILURE);
582 554
583configuration_parser::configuration_parser (configuration &conf, 555configuration_parser::configuration_parser (configuration &conf,
584 bool need_keys, 556 bool need_keys,
585 int argc, 557 int argc,
586 char **argv) 558 char **argv)
587: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 559: conf (conf), need_keys (need_keys), argc (argc), argv (argv)
588{ 560{
589 char *fname; 561 char *fname;
590 562
591 conf.clear (); 563 conf.clear ();
592 node = &conf.default_node; 564 node = &conf.default_node;
612 584
613 fclose (f); 585 fclose (f);
614 } 586 }
615 else 587 else
616 { 588 {
617 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
618
619 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));
620 exit (EXIT_FAILURE); 592 exit (EXIT_FAILURE);
593 }
621 } 594 }
622 595
623 free (fname); 596 free (fname);
624 597
625 if (need_keys && ::thisnode 598 fname = conf.config_filename (conf.pidfilename);
626 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key) 599 free (conf.pidfilename); conf.pidfilename = fname;
627 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
628 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
629 {
630 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
631 exit (EXIT_FAILURE);
632 }
633 600
634 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
635 (*i)->finalise (); 635 (*i)->finalise ();
636 }
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 }
636} 702}
637 703
638char * 704char *
639configuration::config_filename (const char *name, const char *dflt) 705configuration::config_filename (const char *name, const char *dflt)
640{ 706{
641 char *fname; 707 char *fname;
642 708
643 asprintf (&fname, name ? name : dflt, ::thisnode); 709 asprintf (&fname, name ? name : dflt, ::thisnode ? ::thisnode : "<unset>");
644 710
645 if (!ABSOLUTE_PATH (fname)) 711 if (!ABSOLUTE_PATH (fname))
646 { 712 {
647 char *rname = fname; 713 char *rname = fname;
648 asprintf (&fname, "%s/%s", confbase, rname); 714 asprintf (&fname, "%s/%s", confbase, rname);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines