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.57 by root, Sat Dec 17 22:05:34 2011 UTC vs.
Revision 1.66 by root, Thu Jul 30 19:03:44 2015 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>
60struct configuration conf; 61struct configuration conf;
61 62
62u8 63u8
63best_protocol (u8 protset) 64best_protocol (u8 protset)
64{ 65{
65#if 1//D2
66 if (protset & PROT_IPv42 ) return PROT_IPv42;
67#endif
68 if (protset & PROT_IPv4 ) return PROT_IPv4; 66 if (protset & PROT_IPv4 ) return PROT_IPv4;
69 if (protset & PROT_ICMPv4) return PROT_ICMPv4; 67 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
70 if (protset & PROT_UDPv4 ) return PROT_UDPv4; 68 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
71 if (protset & PROT_TCPv4 ) return PROT_TCPv4; 69 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
72 if (protset & PROT_DNSv4 ) return PROT_DNSv4; 70 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
75} 73}
76 74
77const char * 75const char *
78strprotocol (u8 protocol) 76strprotocol (u8 protocol)
79{ 77{
80#if 1//D2
81 if (protocol & PROT_IPv42 ) return "rawip2";
82#endif
83 if (protocol & PROT_IPv4 ) return "rawip"; 78 if (protocol & PROT_IPv4 ) return "rawip";
84 if (protocol & PROT_ICMPv4) return "icmp"; 79 if (protocol & PROT_ICMPv4) return "icmp";
85 if (protocol & PROT_UDPv4 ) return "udp"; 80 if (protocol & PROT_UDPv4 ) return "udp";
86 if (protocol & PROT_TCPv4 ) return "tcp"; 81 if (protocol & PROT_TCPv4 ) return "tcp";
87 if (protocol & PROT_DNSv4 ) return "dns"; 82 if (protocol & PROT_DNSv4 ) return "dns";
140 nfmark = 0; 135 nfmark = 0;
141 rekey = DEFAULT_REKEY; 136 rekey = DEFAULT_REKEY;
142 keepalive = DEFAULT_KEEPALIVE; 137 keepalive = DEFAULT_KEEPALIVE;
143 llevel = L_INFO; 138 llevel = L_INFO;
144 ip_proto = IPPROTO_GRE; 139 ip_proto = IPPROTO_GRE;
145#if 1 //D2
146 ip2_proto = 7;
147#endif
148#if ENABLE_ICMP 140#if ENABLE_ICMP
149 icmp_type = ICMP_ECHOREPLY; 141 icmp_type = ICMP_ECHOREPLY;
150#endif 142#endif
151 143
152 default_node.udp_port = DEFAULT_UDPPORT; 144 default_node.udp_port = DEFAULT_UDPPORT;
169 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 161 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
170 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 162 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
171 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING; 163 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING;
172#endif 164#endif
173 165
174 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 166 pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
167 seed_dev = strdup ("/dev/urandom");
168 reseed = DEFAULT_RESEED;
175} 169}
176 170
177void 171void
178configuration::cleanup () 172configuration::cleanup ()
179{ 173{
180 if (rsa_key) 174 if (rsa_key)
181 RSA_free (rsa_key); 175 RSA_free (rsa_key);
182 176
183 rsa_key = 0; 177 rsa_key = 0;
184 178
179 free (seed_dev); seed_dev = 0;
185 free (pidfilename); pidfilename = 0; 180 free (pidfilename); pidfilename = 0;
186 free (ifname); ifname = 0; 181 free (ifname); ifname = 0;
187#if ENABLE_HTTP_PROXY 182#if ENABLE_HTTP_PROXY
188 free (proxy_host); proxy_host = 0; 183 free (proxy_host); proxy_host = 0;
189 free (proxy_auth); proxy_auth = 0; 184 free (proxy_auth); proxy_auth = 0;
190#endif 185#endif
191#if ENABLE_DNS 186#if ENABLE_DNS
192 free (dns_forw_host); dns_forw_host = 0; 187 free (dns_forw_host); dns_forw_host = 0;
193#endif 188#endif
189 free (change_root); change_root = 0;
194 free (script_if_up); script_if_up = 0; 190 free (script_if_up); script_if_up = 0;
195 free (script_node_up); script_node_up = 0; 191 free (script_node_up); script_node_up = 0;
196 free (script_node_change); script_node_change = 0; 192 free (script_node_change); script_node_change = 0;
197 free (script_node_down); script_node_down = 0; 193 free (script_node_down); script_node_down = 0;
198} 194}
205 201
206 nodes.clear (); 202 nodes.clear ();
207 203
208 cleanup (); 204 cleanup ();
209 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;
210} 216}
211 217
212//static bool 218//static bool
213//is_true (const char *name) 219//is_true (const char *name)
214//{ 220//{
230configuration_parser::parse_line (char *line) 236configuration_parser::parse_line (char *line)
231{ 237{
232 { 238 {
233 char *end = line + strlen (line); 239 char *end = line + strlen (line);
234 240
235 while (*end < ' ' && end >= line) 241 while (end >= line && *end < ' ')
236 end--; 242 end--;
237 243
238 *++end = 0; 244 *++end = 0;
239 } 245 }
240 246
245 if (!var || !var[0]) 251 if (!var || !var[0])
246 return 0; /* no tokens on this line */ 252 return 0; /* no tokens on this line */
247 253
248 if (var[0] == '#') 254 if (var[0] == '#')
249 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 }
250 262
251 char *val = strtok (NULL, "\t\n\r ="); 263 char *val = strtok (NULL, "\t\n\r =");
252 264
253 if (!val || val[0] == '#') 265 if (!val || val[0] == '#')
254 return _("no value given for variable, ignored"); 266 return _("no value given for variable, ignored");
274 loglevel l = string_to_loglevel (val); 286 loglevel l = string_to_loglevel (val);
275 287
276 if (l == L_NONE) 288 if (l == L_NONE)
277 return _("unknown loglevel, ignored"); 289 return _("unknown loglevel, ignored");
278 } 290 }
291 else if (!strcmp (var, "serial"))
292 strncpy (conf.serial, val, sizeof (conf.serial));
279 else if (!strcmp (var, "ip-proto")) 293 else if (!strcmp (var, "ip-proto"))
280 conf.ip_proto = atoi (val); 294 conf.ip_proto = atoi (val);
281#if 1 //D2
282 else if (!strcmp (var, "ip2-proto"))
283 conf.ip2_proto = atoi (val);
284#endif
285 else if (!strcmp (var, "icmp-type")) 295 else if (!strcmp (var, "icmp-type"))
286 { 296 {
287#if ENABLE_ICMP 297#if ENABLE_ICMP
288 conf.icmp_type = atoi (val); 298 conf.icmp_type = atoi (val);
289#endif 299#endif
290 } 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");
291 306
292 // 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
293 else if (!strcmp (var, "node")) 318 else if (!strcmp (var, "node"))
294 { 319 {
295 parse_argv (); 320 node = conf.find_node (val);
296 321
322 if (!node)
323 {
297 conf.default_node.id++; 324 conf.default_node.id++;
298 node = new conf_node (conf.default_node); 325 node = new conf_node (conf.default_node);
299 conf.nodes.push_back (node); 326 conf.nodes.push_back (node);
300 node->nodename = strdup (val); 327 node->nodename = strdup (val);
301
302 {
303 char *fname;
304 FILE *f;
305
306 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
307
308 f = fopen (fname, "r");
309 if (f)
310 {
311 node->rsa_key = RSA_new ();
312
313 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
314 {
315 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
316 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
317 exit (EXIT_FAILURE);
318 }
319
320 require (RSA_blinding_on (node->rsa_key, 0));
321
322 fclose (f);
323 } 328 }
324 else
325 {
326 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
327
328 if (need_keys)
329 exit (EXIT_FAILURE);
330 }
331
332 free (fname);
333 }
334
335 if (::thisnode && !strcmp (node->nodename, ::thisnode))
336 conf.thisnode = node;
337 } 329 }
338 else if (!strcmp (var, "private-key")) 330 else if (!strcmp (var, "private-key"))
339 free (conf.prikeyfile), conf.prikeyfile = strdup (val); 331 free (conf.prikeyfile), conf.prikeyfile = strdup (val);
340 else if (!strcmp (var, "ifpersist")) 332 else if (!strcmp (var, "ifpersist"))
341 parse_bool (conf.ifpersist, "ifpersist", true, false); 333 parse_bool (conf.ifpersist, "ifpersist", true, false);
347 conf.keepalive = atoi (val); 339 conf.keepalive = atoi (val);
348 else if (!strcmp (var, "mtu")) 340 else if (!strcmp (var, "mtu"))
349 conf.mtu = atoi (val); 341 conf.mtu = atoi (val);
350 else if (!strcmp (var, "nfmark")) 342 else if (!strcmp (var, "nfmark"))
351 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);
352 else if (!strcmp (var, "if-up")) 348 else if (!strcmp (var, "if-up"))
353 free (conf.script_if_up), conf.script_if_up = strdup (val); 349 free (conf.script_if_up), conf.script_if_up = strdup (val);
354 else if (!strcmp (var, "node-up")) 350 else if (!strcmp (var, "node-up"))
355 free (conf.script_node_up), conf.script_node_up = strdup (val); 351 free (conf.script_node_up), conf.script_node_up = strdup (val);
356 else if (!strcmp (var, "node-change")) 352 else if (!strcmp (var, "node-change"))
468 } 464 }
469 else if (!strcmp (var, "inherit-tos")) 465 else if (!strcmp (var, "inherit-tos"))
470 parse_bool (node->inherit_tos, "inherit-tos", true, false); 466 parse_bool (node->inherit_tos, "inherit-tos", true, false);
471 else if (!strcmp (var, "compress")) 467 else if (!strcmp (var, "compress"))
472 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);
473 // 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!
474 else if (!strcmp (var, "enable-tcp")) 472 else if (!strcmp (var, "enable-tcp"))
475 { 473 {
476#if ENABLE_TCP 474#if ENABLE_TCP
477 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;
495 } 493 }
496 else if (!strcmp (var, "enable-rawip")) 494 else if (!strcmp (var, "enable-rawip"))
497 { 495 {
498 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v; 496 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
499 } 497 }
500#if 1//D2
501 else if (!strcmp (var, "enable-rawip2"))
502 {
503 u8 v; parse_bool (v, "enable-rawip2", PROT_IPv42, 0); node->protocols = (node->protocols & ~PROT_IPv42 ) | v;
504 }
505#endif
506 else if (!strcmp (var, "allow-direct")) 498 else if (!strcmp (var, "allow-direct"))
507 node->allow_direct.push_back (strdup (val)); 499 node->allow_direct.push_back (strdup (val));
508 else if (!strcmp (var, "deny-direct")) 500 else if (!strcmp (var, "deny-direct"))
509 node->deny_direct.push_back (strdup (val)); 501 node->deny_direct.push_back (strdup (val));
510 else if (!strcmp (var, "max-ttl")) 502 else if (!strcmp (var, "max-ttl"))
534 connectmode = C_ALWAYS; 526 connectmode = C_ALWAYS;
535 } 527 }
536} 528}
537 529
538void 530void
539configuration_parser::parse_argv ()
540{
541 for (int i = 0; i < argc; ++i)
542 {
543 char *v = argv [i];
544
545 if (!*v)
546 continue;
547
548 char *enode = v;
549
550 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
551 enode++;
552
553 if (*enode != '.')
554 enode = 0;
555
556 char *wnode = node == &conf.default_node
557 ? 0
558 : node->nodename;
559
560 if ((!wnode && !enode)
561 || (wnode && enode && !strncmp (wnode, v, enode - v)))
562 {
563 const char *warn = parse_line (enode ? enode + 1 : v);
564
565 if (warn)
566 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
567
568 *v = 0;
569 }
570 }
571}
572
573void
574configuration_parser::parse_file (const char *fname) 531configuration_parser::parse_file (const char *fname)
575{ 532{
576 if (FILE *f = fopen (fname, "r")) 533 if (FILE *f = fopen (fname, "r"))
577 { 534 {
578 char line [2048]; 535 char line [2048];
587 if (warn) 544 if (warn)
588 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno); 545 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
589 } 546 }
590 547
591 fclose (f); 548 fclose (f);
592
593 parse_argv ();
594 } 549 }
595 else 550 else
596 { 551 {
597 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));
598 exit (EXIT_FAILURE); 553 exit (EXIT_FAILURE);
601 556
602configuration_parser::configuration_parser (configuration &conf, 557configuration_parser::configuration_parser (configuration &conf,
603 bool need_keys, 558 bool need_keys,
604 int argc, 559 int argc,
605 char **argv) 560 char **argv)
606: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 561: conf (conf), need_keys (need_keys), argc (argc), argv (argv)
607{ 562{
608 char *fname; 563 char *fname;
609 564
610 conf.clear (); 565 conf.clear ();
611 node = &conf.default_node; 566 node = &conf.default_node;
631 586
632 fclose (f); 587 fclose (f);
633 } 588 }
634 else 589 else
635 { 590 {
636 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
637
638 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));
639 exit (EXIT_FAILURE); 594 exit (EXIT_FAILURE);
595 }
640 } 596 }
641 597
642 free (fname); 598 free (fname);
643 599
644 if (need_keys && ::thisnode 600 fname = conf.config_filename (conf.pidfilename);
645 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key) 601 free (conf.pidfilename); conf.pidfilename = fname;
646 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
647 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
648 {
649 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
650 exit (EXIT_FAILURE);
651 }
652 602
653 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
654 (*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 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
654 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
655 {
656 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
657 exit (EXIT_FAILURE);
658 }
659 }
660 }
661
662 parse_argv ();
663}
664
665void
666configuration_parser::parse_argv ()
667{
668 for (int i = 0; i < argc; ++i)
669 {
670 char *v = argv [i];
671
672 if (!*v)
673 continue;
674
675 char *enode = v;
676
677 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
678 enode++;
679
680 if (*enode != '.')
681 enode = 0;
682
683 if (enode)
684 {
685 char *val = strdup (v);
686 val [enode - v] = 0;
687 node = conf.find_node (val);
688 free (val);
689
690 if (!node)
691 {
692 slog (L_WARN, _("command line option '%s' refers to unknown node, ignoring."), v);
693 continue;
694 }
695 }
696 else
697 node = &conf.default_node;
698
699 const char *warn = parse_line (enode ? enode + 1 : v);
700
701 if (warn)
702 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
703 }
655} 704}
656 705
657char * 706char *
658configuration::config_filename (const char *name, const char *dflt) 707configuration::config_filename (const char *name, const char *dflt)
659{ 708{
660 char *fname; 709 char *fname;
661 710
662 asprintf (&fname, name ? name : dflt, ::thisnode); 711 asprintf (&fname, name ? name : dflt, ::thisnode ? ::thisnode : "<unset>");
663 712
664 if (!ABSOLUTE_PATH (fname)) 713 if (!ABSOLUTE_PATH (fname))
665 { 714 {
666 char *rname = fname; 715 char *rname = fname;
667 asprintf (&fname, "%s/%s", confbase, rname); 716 asprintf (&fname, "%s/%s", confbase, rname);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines