/* * parse a ca section */ static void load_ca(starter_ca_t *ca, starter_config_t *cfg, conf_parser_t *parser) { enumerator_t *enumerator; dictionary_t *dict; const kw_entry_t *entry; kw_token_t token; char *key, *value; DBG2(DBG_APP, "Loading ca '%s'", ca->name); dict = parser->get_section(parser, CONF_PARSER_CA, ca->name); if (!dict) { return; } enumerator = dict->create_enumerator(dict); while (enumerator->enumerate(enumerator, &key, &value)) { bool assigned = FALSE; entry = in_word_set(key, strlen(key)); if (!entry) { DBG1(DBG_APP, "# unknown keyword '%s'", key); cfg->non_fatal_err++; continue; } token = entry->token; if (token == KW_AUTO) { token = KW_CA_SETUP; } if (token < KW_CA_FIRST || token > KW_CA_LAST) { DBG1(DBG_APP, "# unsupported keyword '%s' in ca '%s'", key, ca->name); cfg->err++; continue; } if (is_deprecated(token, key, ca->name)) { cfg->non_fatal_err++; continue; } if (!assign_arg(token, KW_CA_FIRST, key, value, ca, &assigned)) { DBG1(DBG_APP, " bad argument value in ca '%s'", ca->name); cfg->err++; } } enumerator->destroy(enumerator); dict->destroy(dict); /* treat 'route' and 'start' as 'add' */ if (ca->startup != STARTUP_NO) { ca->startup = STARTUP_ADD; } }
/* * parse a ca section */ static void load_ca(starter_ca_t *ca, kw_list_t *kw, starter_config_t *cfg) { char *ca_name = (ca->name == NULL)? "%default":ca->name; for ( ; kw; kw = kw->next) { bool assigned = FALSE; kw_token_t token = kw->entry->token; if (token == KW_AUTO) { token = KW_CA_SETUP; } else if (token == KW_ALSO) { if (cfg->parse_also) { also_t *also = malloc_thing(also_t); also->name = strdupnull(kw->value); also->next = ca->also; ca->also = also; DBG2(DBG_APP, " also=%s", kw->value); } continue; } if (token < KW_CA_FIRST || token > KW_CA_LAST) { DBG1(DBG_APP, "# unsupported keyword '%s' in ca '%s'", kw->entry->name, ca_name); cfg->err++; continue; } if (is_deprecated(token, kw, ca_name)) { cfg->non_fatal_err++; continue; } if (!assign_arg(token, KW_CA_FIRST, kw, (char *)ca, &assigned)) { DBG1(DBG_APP, " bad argument value in ca '%s'", ca_name); cfg->err++; } } /* treat 'route' and 'start' as 'add' */ if (ca->startup != STARTUP_NO) ca->startup = STARTUP_ADD; }
/* * parse config setup section */ static void load_setup(starter_config_t *cfg, conf_parser_t *parser) { enumerator_t *enumerator; dictionary_t *dict; const kw_entry_t *entry; char *key, *value; DBG2(DBG_APP, "Loading config setup"); dict = parser->get_section(parser, CONF_PARSER_CONFIG_SETUP, NULL); if (!dict) { return; } enumerator = dict->create_enumerator(dict); while (enumerator->enumerate(enumerator, &key, &value)) { bool assigned = FALSE; entry = in_word_set(key, strlen(key)); if (!entry) { DBG1(DBG_APP, "# unknown keyword '%s'", key); cfg->non_fatal_err++; continue; } if ((int)entry->token < KW_SETUP_FIRST || entry->token > KW_SETUP_LAST) { DBG1(DBG_APP, "# unsupported keyword '%s' in config setup", key); cfg->err++; continue; } if (is_deprecated(entry->token, key, "")) { cfg->non_fatal_err++; continue; } if (!assign_arg(entry->token, KW_SETUP_FIRST, key, value, cfg, &assigned)) { DBG1(DBG_APP, " bad argument value in config setup"); cfg->err++; } } enumerator->destroy(enumerator); dict->destroy(dict); }
static void load_setup(starter_config_t *cfg, config_parsed_t *cfgp) { kw_list_t *kw; DBG2(DBG_APP, "Loading config setup"); for (kw = cfgp->config_setup; kw; kw = kw->next) { bool assigned = FALSE; kw_token_t token = kw->entry->token; if ((int)token < KW_SETUP_FIRST || token > KW_SETUP_LAST) { DBG1(DBG_APP, "# unsupported keyword '%s' in config setup", kw->entry->name); cfg->err++; continue; } if (is_deprecated(token, kw, "")) { cfg->non_fatal_err++; continue; } if (!assign_arg(token, KW_SETUP_FIRST, kw, (char *)cfg, &assigned)) { DBG1(DBG_APP, " bad argument value in config setup"); cfg->err++; continue; } } /* verify the executables are actually available */ #ifdef START_CHARON cfg->setup.charonstart = cfg->setup.charonstart && daemon_exists(daemon_name, cmd); #else cfg->setup.charonstart = FALSE; #endif }
/* * parse a conn section */ static void load_conn(starter_conn_t *conn, starter_config_t *cfg, conf_parser_t *parser) { enumerator_t *enumerator; dictionary_t *dict; const kw_entry_t *entry; kw_token_t token; char *key, *value; DBG2(DBG_APP, "Loading conn '%s'", conn->name); dict = parser->get_section(parser, CONF_PARSER_CONN, conn->name); if (!dict) { return; } enumerator = dict->create_enumerator(dict); while (enumerator->enumerate(enumerator, &key, &value)) { bool assigned = FALSE; entry = in_word_set(key, strlen(key)); if (!entry) { DBG1(DBG_APP, "# unknown keyword '%s'", key); cfg->non_fatal_err++; continue; } token = entry->token; if (token >= KW_LEFT_FIRST && token <= KW_LEFT_LAST) { kw_end(conn, &conn->left, token - KW_LEFT_FIRST + KW_END_FIRST, key, value, cfg); continue; } else if (token >= KW_RIGHT_FIRST && token <= KW_RIGHT_LAST) { kw_end(conn, &conn->right, token - KW_RIGHT_FIRST + KW_END_FIRST, key, value, cfg); continue; } if (token == KW_AUTO) { token = KW_CONN_SETUP; } if (token < KW_CONN_FIRST || token > KW_CONN_LAST) { DBG1(DBG_APP, "# unsupported keyword '%s' in conn '%s'", key, conn->name); cfg->err++; continue; } if (is_deprecated(token, key, conn->name)) { cfg->non_fatal_err++; continue; } if (!assign_arg(token, KW_CONN_FIRST, key, value, conn, &assigned)) { DBG1(DBG_APP, " bad argument value in conn '%s'", conn->name); cfg->err++; continue; } if (!assigned) { handle_keyword(token, conn, key, value, cfg); } } enumerator->destroy(enumerator); dict->destroy(dict); handle_firewall("left", &conn->left, cfg); handle_firewall("right", &conn->right, cfg); }
/* * parse left|right specific options */ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token, char *key, char *value, starter_config_t *cfg) { bool assigned = FALSE; if (is_deprecated(token, key, conn->name)) { cfg->non_fatal_err++; return; } if (!assign_arg(token, KW_END_FIRST, key, value, end, &assigned)) { goto err; } /* post processing of some keywords that were assigned automatically */ switch (token) { case KW_HOST: if (value && strlen(value) > 0 && value[0] == '%') { if (streq(value, "%defaultroute")) { value = "%any"; } if (!streq(value, "%any") && !streq(value, "%any4") && !streq(value, "%any6")) { /* allow_any prefix */ end->allow_any = TRUE; value++; } } free(end->host); end->host = strdupnull(value); break; case KW_SOURCEIP: conn->mode = MODE_TUNNEL; conn->proxy_mode = FALSE; break; case KW_SENDCERT: if (end->sendcert == CERT_YES_SEND) { end->sendcert = CERT_ALWAYS_SEND; } else if (end->sendcert == CERT_NO_SEND) { end->sendcert = CERT_NEVER_SEND; } break; default: break; } if (assigned) { return; } /* individual processing of keywords that were not assigned automatically */ switch (token) { case KW_PROTOPORT: { struct protoent *proto; struct servent *svc; char *sep, *port = "", *endptr; long int p; sep = strchr(value, '/'); if (sep) { /* protocol/port */ *sep = '\0'; port = sep + 1; } if (streq(value, "%any")) { end->protocol = 0; } else { proto = getprotobyname(value); if (proto) { end->protocol = proto->p_proto; } else { p = strtol(value, &endptr, 0); if ((*value && *endptr) || p < 0 || p > 0xff) { DBG1(DBG_APP, "# bad protocol: %s=%s", key, value); goto err; } end->protocol = (uint8_t)p; } } if (streq(port, "%any")) { end->from_port = 0; end->to_port = 0xffff; } else if (streq(port, "%opaque")) { end->from_port = 0xffff; end->to_port = 0; } else if (*port) { svc = getservbyname(port, NULL); if (svc) { end->from_port = end->to_port = ntohs(svc->s_port); } else { p = strtol(port, &endptr, 0); if (p < 0 || p > 0xffff) { DBG1(DBG_APP, "# bad port: %s=%s", key, port); goto err; } end->from_port = p; if (*endptr == '-') { port = endptr + 1; p = strtol(port, &endptr, 0); if (p < 0 || p > 0xffff) { DBG1(DBG_APP, "# bad port: %s=%s", key, port); goto err; } } end->to_port = p; if (*endptr) { DBG1(DBG_APP, "# bad port: %s=%s", key, port); goto err; } } } if (sep) { /* restore the original text in case also= is used */ *sep = '/'; } break; } default: break; } return; err: DBG1(DBG_APP, " bad argument value in conn '%s'", conn->name); cfg->err++; }
/* * parse a conn section */ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg) { char *conn_name = (conn->name == NULL)? "%default":conn->name; for ( ; kw; kw = kw->next) { bool assigned = FALSE; kw_token_t token = kw->entry->token; if (token >= KW_LEFT_FIRST && token <= KW_LEFT_LAST) { kw_end(conn, &conn->left, token - KW_LEFT_FIRST + KW_END_FIRST , kw, conn_name, cfg); continue; } else if (token >= KW_RIGHT_FIRST && token <= KW_RIGHT_LAST) { kw_end(conn, &conn->right, token - KW_RIGHT_FIRST + KW_END_FIRST , kw, conn_name, cfg); continue; } if (token == KW_AUTO) { token = KW_CONN_SETUP; } else if (token == KW_ALSO) { if (cfg->parse_also) { also_t *also = malloc_thing(also_t); also->name = strdupnull(kw->value); also->next = conn->also; conn->also = also; DBG2(DBG_APP, " also=%s", kw->value); } continue; } if (token < KW_CONN_FIRST || token > KW_CONN_LAST) { DBG1(DBG_APP, "# unsupported keyword '%s' in conn '%s'", kw->entry->name, conn_name); cfg->err++; continue; } if (is_deprecated(token, kw, conn_name)) { cfg->non_fatal_err++; continue; } if (!assign_arg(token, KW_CONN_FIRST, kw, (char *)conn, &assigned)) { DBG1(DBG_APP, " bad argument value in conn '%s'", conn_name); cfg->err++; continue; } if (assigned) continue; switch (token) { case KW_TYPE: conn->mode = MODE_TRANSPORT; conn->proxy_mode = FALSE; if (streq(kw->value, "tunnel")) { conn->mode = MODE_TUNNEL; } else if (streq(kw->value, "beet")) { conn->mode = MODE_BEET; } else if (streq(kw->value, "transport_proxy")) { conn->mode = MODE_TRANSPORT; conn->proxy_mode = TRUE; } else if (streq(kw->value, "passthrough") || streq(kw->value, "pass")) { conn->mode = MODE_PASS; } else if (streq(kw->value, "drop") || streq(kw->value, "reject")) { conn->mode = MODE_DROP; } else if (!streq(kw->value, "transport")) { DBG1(DBG_APP, "# bad policy value: %s=%s", kw->entry->name, kw->value); cfg->err++; } break; case KW_COMPRESS: KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_COMPRESS) break; case KW_AUTH: KW_SA_OPTION_FLAG("ah", "esp", SA_OPTION_AUTHENTICATE) break; case KW_MARK: if (!handle_mark(kw->value, &conn->mark_in)) { cfg->err++; break; } conn->mark_out = conn->mark_in; break; case KW_MARK_IN: if (!handle_mark(kw->value, &conn->mark_in)) { cfg->err++; } break; case KW_MARK_OUT: if (!handle_mark(kw->value, &conn->mark_out)) { cfg->err++; } break; case KW_TFC: if (streq(kw->value, "%mtu")) { conn->tfc = -1; } else { char *endptr; conn->tfc = strtoul(kw->value, &endptr, 10); if (*endptr != '\0') { DBG1(DBG_APP, "# bad integer value: %s=%s", kw->entry->name, kw->value); cfg->err++; } } break; case KW_KEYINGTRIES: if (streq(kw->value, "%forever")) { conn->sa_keying_tries = 0; } else { char *endptr; conn->sa_keying_tries = strtoul(kw->value, &endptr, 10); if (*endptr != '\0') { DBG1(DBG_APP, "# bad integer value: %s=%s", kw->entry->name, kw->value); cfg->err++; } } break; case KW_REKEY: KW_SA_OPTION_FLAG("no", "yes", SA_OPTION_DONT_REKEY) break; case KW_REAUTH: KW_SA_OPTION_FLAG("no", "yes", SA_OPTION_DONT_REAUTH) break; case KW_MOBIKE: KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_MOBIKE) break; case KW_FORCEENCAPS: KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_FORCE_ENCAP) break; case KW_MODECONFIG: KW_SA_OPTION_FLAG("push", "pull", SA_OPTION_MODECFG_PUSH) break; case KW_XAUTH: KW_SA_OPTION_FLAG("server", "client", SA_OPTION_XAUTH_SERVER) break; default: break; } } handle_firewall("left", &conn->left, cfg); handle_firewall("right", &conn->right, cfg); }