static void load_setup(starter_config_t *cfg, config_parsed_t *cfgp) { kw_list_t *kw; DBG(DBG_CONTROL, DBG_log("Loading config setup") ) for (kw = cfgp->config_setup; kw; kw = kw->next) { bool assigned = FALSE; kw_token_t token = kw->entry->token; if (token < KW_SETUP_FIRST || token > KW_SETUP_LAST) { plog("# unsupported keyword '%s' in config setup", kw->entry->name); cfg->err++; continue; } if (!assign_arg(token, KW_SETUP_FIRST, kw, (char *)cfg, &assigned)) { plog(" bad argument value in config setup"); cfg->err++; continue; } } }
/* * 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, 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 = clone_str(kw->value); also->next = conn->also; conn->also = also; DBG(DBG_CONTROL, DBG_log(" also=%s", kw->value) ) } continue; } if (token < KW_CONN_FIRST || token > KW_CONN_LAST) { plog("# unsupported keyword '%s' in conn '%s'" , kw->entry->name, conn_name); cfg->err++; continue; } if (!assign_arg(token, KW_CONN_FIRST, kw, (char *)conn, &assigned)) { plog(" bad argument value in conn '%s'", conn_name); cfg->err++; continue; } if (assigned) continue; switch (token) { case KW_TYPE: conn->policy &= ~(POLICY_TUNNEL | POLICY_SHUNT_MASK); if (streq(kw->value, "tunnel")) { conn->policy |= POLICY_TUNNEL; } else if (streq(kw->value, "beet")) { conn->policy |= POLICY_BEET; } else if (streq(kw->value, "transport_proxy")) { conn->policy |= POLICY_PROXY; } else if (streq(kw->value, "passthrough") || streq(kw->value, "pass")) { conn->policy |= POLICY_SHUNT_PASS; } else if (streq(kw->value, "drop")) { conn->policy |= POLICY_SHUNT_DROP; } else if (streq(kw->value, "reject")) { conn->policy |= POLICY_SHUNT_REJECT; } else if (strcmp(kw->value, "transport") != 0) { plog("# bad policy value: %s=%s", kw->entry->name, kw->value); cfg->err++; } break; case KW_PFS: KW_POLICY_FLAG("yes", "no", POLICY_PFS) break; case KW_COMPRESS: KW_POLICY_FLAG("yes", "no", POLICY_COMPRESS) break; case KW_PMTUDISC: if (streq(kw->value, "no")) { conn->xfrm_flags |= XFRM_STATE_NOPMTUDISC; } break; case KW_IPSECDEV: conn->dev = get_ifindex(kw->value); if (conn->dev < 0) { cfg->err++; } break; case KW_ECN: if (streq(kw->value, "no")) { conn->xfrm_flags |= XFRM_STATE_NOECN; } break; case KW_AUTH: KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE) break; case KW_AUTHBY: conn->policy &= ~(POLICY_ID_AUTH_MASK | POLICY_ENCRYPT); if (!(streq(kw->value, "never") || streq(kw->value, "eap"))) { char *value = kw->value; char *second = strchr(kw->value, '|'); if (second != NULL) { *second = '\0'; } /* also handles the cases secret|rsasig and rsasig|secret */ for (;;) { if (streq(value, "rsa") || streq(value, "rsasig") || streq(value, "ecdsa") || streq(value, "ecdsasig") || streq(value, "pubkey")) { conn->policy |= POLICY_PUBKEY | POLICY_ENCRYPT; } else if (streq(value, "secret") || streq(value, "psk")) { conn->policy |= POLICY_PSK | POLICY_ENCRYPT; } else if (streq(value, "xauthrsasig")) { conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT; } else if (streq(value, "xauthpsk")) { conn->policy |= POLICY_XAUTH_PSK | POLICY_ENCRYPT; } else { plog("# bad policy value: %s=%s", kw->entry->name, kw->value); cfg->err++; break; } if (second == NULL) { break; } value = second; second = NULL; /* traverse the loop no more than twice */ } } break; case KW_EAP: { char *sep; /* check for vendor-type format */ sep = strchr(kw->value, '-'); if (sep) { *(sep++) = '\0'; conn->eap_type = atoi(kw->value); conn->eap_vendor = atoi(sep); if (conn->eap_type == 0 || conn->eap_vendor == 0) { plog("# invalid EAP type: %s=%s", kw->entry->name, kw->value); cfg->err++; } break; } if (streq(kw->value, "aka")) { conn->eap_type = 23; } else if (streq(kw->value, "sim")) { conn->eap_type = 18; } else if (streq(kw->value, "md5")) { conn->eap_type = 4; } else if (streq(kw->value, "gtc")) { conn->eap_type = 6; } else if (streq(kw->value, "mschapv2")) { conn->eap_type = 26; } else if (streq(kw->value, "radius")) { /* pseudo-type */ conn->eap_type = 253; } else { conn->eap_type = atoi(kw->value); if (conn->eap_type == 0) { plog("# unknown EAP type: %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') { plog("# bad integer value: %s=%s", kw->entry->name, kw->value); cfg->err++; } } break; case KW_REKEY: KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY) break; case KW_REAUTH: KW_POLICY_FLAG("no", "yes", POLICY_DONT_REAUTH) break; case KW_MOBIKE: KW_POLICY_FLAG("yes", "no", POLICY_MOBIKE) break; case KW_FORCEENCAPS: KW_POLICY_FLAG("yes", "no", POLICY_FORCE_ENCAP) break; case KW_MODECONFIG: KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH) break; case KW_XAUTH: KW_POLICY_FLAG("server", "client", POLICY_XAUTH_SERVER) break; default: break; } }
static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token, kw_list_t *kw, char *conn_name, starter_config_t *cfg) { err_t ugh = NULL; bool assigned = FALSE; bool has_port_wildcard; /* set if port is %any */ char *name = kw->entry->name; char *value = kw->value; if (!assign_arg(token, KW_END_FIRST, kw, (char *)end, &assigned)) goto err; /* post processing of some keywords that were assigned automatically */ switch (token) { case KW_SUBNET: if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0) || (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0)) { /* used by pluto only */ end->has_virt = TRUE; } else { ip_subnet net; char *pos; int len = 0; end->has_client = TRUE; conn->tunnel_addr_family = ip_version(value); pos = strchr(value, ','); if (pos) { len = pos - value; } ugh = ttosubnet(value, len, ip_version(value), &net); if (ugh != NULL) { plog("# bad subnet: %s=%s [%s]", name, value, ugh); goto err; } } break; case KW_SOURCEIP: if (end->has_natip) { plog("# natip and sourceip cannot be defined at the same time"); goto err; } if (value[0] == '%') { if (streq(value, "%modeconfig") || streq(value, "%modecfg") || streq(value, "%config") || streq(value, "%cfg")) { /* request ip via config payload */ free(end->sourceip); end->sourceip = NULL; end->sourceip_mask = 1; } else { /* %poolname, strip %, serve ip requests */ free(end->sourceip); end->sourceip = clone_str(value+1); end->sourceip_mask = 0; } end->modecfg = TRUE; } else { char *pos; ip_address addr; ip_subnet net; conn->tunnel_addr_family = ip_version(value); pos = strchr(value, '/'); if (pos) { /* CIDR notation, address pool */ ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &net); if (ugh != NULL) { plog("# bad subnet: %s=%s [%s]", name, value, ugh); goto err; } *pos = '\0'; free(end->sourceip); end->sourceip = clone_str(value); end->sourceip_mask = atoi(pos + 1); } else { /* fixed srcip */ ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr); if (ugh != NULL) { plog("# bad addr: %s=%s [%s]", name, value, ugh); goto err; } end->sourceip_mask = (conn->tunnel_addr_family == AF_INET) ? 32 : 128; } } conn->policy |= POLICY_TUNNEL; 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_HOST: if (streq(value, "%defaultroute")) { if (cfg->defaultroute.defined) { end->addr = cfg->defaultroute.addr; end->nexthop = cfg->defaultroute.nexthop; } else if (!cfg->defaultroute.supported) { plog("%%defaultroute not supported, fallback to %%any"); } else { plog("# default route not known: %s=%s", name, value); goto err; } } else if (streq(value, "%any") || streq(value, "%any4")) { anyaddr(conn->addr_family, &end->addr); } else if (streq(value, "%any6")) { conn->addr_family = AF_INET6; anyaddr(conn->addr_family, &end->addr); } else if (streq(value, "%group")) { ip_address any; conn->policy |= POLICY_GROUP | POLICY_TUNNEL; anyaddr(conn->addr_family, &end->addr); anyaddr(conn->tunnel_addr_family, &any); end->has_client = TRUE; } else { /* check for allow_any prefix */ if (value[0] == '%') { end->allow_any = TRUE; value++; } conn->addr_family = ip_version(value); ugh = ttoaddr(value, 0, conn->addr_family, &end->addr); if (ugh != NULL) { plog("# bad addr: %s=%s [%s]", name, value, ugh); if (streq(ugh, "does not look numeric and name lookup failed")) { end->dns_failed = TRUE; anyaddr(conn->addr_family, &end->addr); } else { goto err; } } } break; case KW_NEXTHOP: if (streq(value, "%defaultroute")) { if (cfg->defaultroute.defined) { end->nexthop = cfg->defaultroute.nexthop; } else { plog("# default route not known: %s=%s", name, value); goto err; } } else if (streq(value, "%direct")) { ugh = anyaddr(conn->addr_family, &end->nexthop); } else { conn->addr_family = ip_version(value); ugh = ttoaddr(value, 0, conn->addr_family, &end->nexthop); } if (ugh != NULL) { plog("# bad addr: %s=%s [%s]", name, value, ugh); goto err; } break; case KW_SUBNETWITHIN: { ip_subnet net; end->has_client = TRUE; end->has_client_wildcard = TRUE; conn->tunnel_addr_family = ip_version(value); ugh = ttosubnet(value, 0, ip_version(value), &net); if (ugh != NULL) { plog("# bad subnet: %s=%s [%s]", name, value, ugh); goto err; } end->subnet = clone_str(value); break; } case KW_PROTOPORT: ugh = ttoprotoport(value, 0, &end->protocol, &end->port, &has_port_wildcard); end->has_port_wildcard = has_port_wildcard; break; case KW_NATIP: if (end->sourceip) { plog("# natip and sourceip cannot be defined at the same time"); goto err; } if (streq(value, "%defaultroute")) { char buf[64]; if (cfg->defaultroute.defined) { addrtot(&cfg->defaultroute.addr, 0, buf, sizeof(buf)); end->sourceip = clone_str(buf); } else { plog("# default route not known: %s=%s", name, value); goto err; } } else { ip_address addr; conn->tunnel_addr_family = ip_version(value); ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr); if (ugh != NULL) { plog("# bad addr: %s=%s [%s]", name, value, ugh); goto err; } end->sourceip = clone_str(value); } end->has_natip = TRUE; conn->policy |= POLICY_TUNNEL; break; default: break; } return; err: plog(" bad argument value in conn '%s'", conn_name); cfg->err++; }
/* * 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); }