--- gvpe/src/conf.C 2011/03/06 21:01:36 1.56 +++ gvpe/src/conf.C 2013/07/18 13:35:16 1.63 @@ -40,6 +40,7 @@ #include #include #include +#include #include "netcompat.h" @@ -162,7 +163,9 @@ dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING; #endif - conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); + pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); + seed_dev = strdup ("/dev/urandom"); + reseed = DEFAULT_RESEED; } void @@ -173,6 +176,7 @@ rsa_key = 0; + free (seed_dev); seed_dev = 0; free (pidfilename); pidfilename = 0; free (ifname); ifname = 0; #if ENABLE_HTTP_PROXY @@ -182,6 +186,7 @@ #if ENABLE_DNS free (dns_forw_host); dns_forw_host = 0; #endif + free (change_root); change_root = 0; free (script_if_up); script_if_up = 0; free (script_node_up); script_node_up = 0; free (script_node_change); script_node_change = 0; @@ -200,6 +205,16 @@ init (); } +conf_node * +configuration::find_node (const char *name) +{ + for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i) + if (!strcmp ((*i)->nodename, name)) + return *i; + + return 0; +} + //static bool //is_true (const char *name) //{ @@ -239,6 +254,12 @@ if (var[0] == '#') return 0; /* comment: ignore */ + if (!strcmp (var, "global")) + { + node = &conf.default_node; + return 0; + } + char *val = strtok (NULL, "\t\n\r ="); if (!val || val[0] == '#') @@ -275,52 +296,34 @@ conf.icmp_type = atoi (val); #endif } + else if (!strcmp (var, "chuser")) + { + struct passwd *pw = getpwnam (val); + if (!pw) + return _("user specified for chuser not found"); + + conf.change_uid = pw->pw_uid; + conf.change_gid = pw->pw_gid; + } + else if (!strcmp (var, "chuid")) + conf.change_uid = atoi (val); + else if (!strcmp (var, "chgid")) + conf.change_gid = atoi (val); + else if (!strcmp (var, "chroot")) + free (conf.change_root), conf.change_root = strdup (val); - // per config + // per node else if (!strcmp (var, "node")) { - parse_argv (); - - conf.default_node.id++; - node = new conf_node (conf.default_node); - conf.nodes.push_back (node); - node->nodename = strdup (val); - - { - char *fname; - FILE *f; + node = conf.find_node (val); - asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename); - - f = fopen (fname, "r"); - if (f) - { - node->rsa_key = RSA_new (); - - if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL)) - { - ERR_load_RSA_strings (); ERR_load_PEM_strings (); - slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0)); - exit (EXIT_FAILURE); - } - - require (RSA_blinding_on (node->rsa_key, 0)); - - fclose (f); - } - else - { - slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno)); - - if (need_keys) - exit (EXIT_FAILURE); - } - - free (fname); - } - - if (::thisnode && !strcmp (node->nodename, ::thisnode)) - conf.thisnode = node; + if (!node) + { + conf.default_node.id++; + node = new conf_node (conf.default_node); + conf.nodes.push_back (node); + node->nodename = strdup (val); + } } else if (!strcmp (var, "private-key")) free (conf.prikeyfile), conf.prikeyfile = strdup (val); @@ -336,6 +339,10 @@ conf.mtu = atoi (val); else if (!strcmp (var, "nfmark")) conf.nfmark = atoi (val); + else if (!strcmp (var, "seed-device")) + free (conf.seed_dev), conf.seed_dev = strdup (val); + else if (!strcmp (var, "seed-interval")) + conf.reseed = atoi (val); else if (!strcmp (var, "if-up")) free (conf.script_if_up), conf.script_if_up = strdup (val); else if (!strcmp (var, "node-up")) @@ -517,41 +524,6 @@ } void -configuration_parser::parse_argv () -{ - for (int i = 0; i < argc; ++i) - { - char *v = argv [i]; - - if (!*v) - continue; - - char *enode = v; - - while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode) - enode++; - - if (*enode != '.') - enode = 0; - - char *wnode = node == &conf.default_node - ? 0 - : node->nodename; - - if ((!wnode && !enode) - || (wnode && enode && !strncmp (wnode, v, enode - v))) - { - const char *warn = parse_line (enode ? enode + 1 : v); - - if (warn) - slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); - - *v = 0; - } - } -} - -void configuration_parser::parse_file (const char *fname) { if (FILE *f = fopen (fname, "r")) @@ -570,8 +542,6 @@ } fclose (f); - - parse_argv (); } else { @@ -584,7 +554,7 @@ bool need_keys, int argc, char **argv) -: conf (conf),need_keys (need_keys), argc (argc), argv (argv) +: conf (conf), need_keys (need_keys), argc (argc), argv (argv) { char *fname; @@ -614,25 +584,119 @@ } else { - slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); - if (need_keys) - exit (EXIT_FAILURE); + { + slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); + exit (EXIT_FAILURE); + } } free (fname); - if (need_keys && ::thisnode - && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key) - if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0 - || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0) - { - slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode); - exit (EXIT_FAILURE); - } + fname = conf.config_filename (conf.pidfilename); + free (conf.pidfilename); conf.pidfilename = fname; for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i) - (*i)->finalise (); + { + conf_node *node = *i; + char *fname; + FILE *f; + + asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename); + + f = fopen (fname, "r"); + if (f) + { + node->rsa_key = RSA_new (); + + if (!PEM_read_RSAPublicKey (f, &node->rsa_key, NULL, NULL)) + { + ERR_load_RSA_strings (); ERR_load_PEM_strings (); + slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0)); + exit (EXIT_FAILURE); + } + + require (RSA_blinding_on (node->rsa_key, 0)); + + fclose (f); + } + else + { + slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno)); + + if (need_keys) + exit (EXIT_FAILURE); + } + + free (fname); + + (*i)->finalise (); + } + + if (::thisnode) + { + conf.thisnode = conf.find_node (::thisnode); + + if (need_keys) + { + if (!conf.thisnode) + { + slog (L_NOTICE, _("local node ('%s') not found in config file, aborting."), ::thisnode); + exit (EXIT_FAILURE); + } + + if (conf.rsa_key && conf.thisnode->rsa_key) + if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0 + || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0) + { + slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode); + exit (EXIT_FAILURE); + } + } + } + + parse_argv (); +} + +void +configuration_parser::parse_argv () +{ + for (int i = 0; i < argc; ++i) + { + char *v = argv [i]; + + if (!*v) + continue; + + char *enode = v; + + while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode) + enode++; + + if (*enode != '.') + enode = 0; + + if (enode) + { + char *val = strdup (v); + val [enode - v] = 0; + node = conf.find_node (val); + free (val); + + if (!node) + { + slog (L_WARN, _("command line option '%s' refers to unknown node, ignoring."), v); + continue; + } + } + else + node = &conf.default_node; + + const char *warn = parse_line (enode ? enode + 1 : v); + + if (warn) + slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); + } } char * @@ -640,7 +704,7 @@ { char *fname; - asprintf (&fname, name ? name : dflt, ::thisnode); + asprintf (&fname, name ? name : dflt, ::thisnode ? ::thisnode : ""); if (!ABSOLUTE_PATH (fname)) {