From e59a50009cfb44330a3b6c1cab8ac57badf58434 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Mon, 29 Aug 2011 09:58:18 +0200 Subject: [PATCH] starter passes unresolved DNS names to charon Based on an initial patch by Mirko Parthey. --- src/starter/args.c | 2 +- src/starter/confread.c | 136 +++++++++++++++++++----------------- src/starter/confread.h | 1 + src/starter/starterstroke.c | 11 ++- 4 files changed, 82 insertions(+), 68 deletions(-) diff --git a/src/starter/args.c b/src/starter/args.c index 863d1b99f..ad5916f2e 100644 --- a/src/starter/args.c +++ b/src/starter/args.c @@ -256,7 +256,7 @@ static const token_info_t token_info[] = { ARG_STR, offsetof(starter_ca_t, certuribase), NULL }, /* end keywords */ - { ARG_MISC, 0, NULL /* KW_HOST */ }, + { ARG_STR, offsetof(starter_end_t, host), NULL }, { ARG_UINT, offsetof(starter_end_t, ikeport), NULL }, { ARG_MISC, 0, NULL /* KW_NEXTHOP */ }, { ARG_STR, offsetof(starter_end_t, subnet), NULL }, diff --git a/src/starter/confread.c b/src/starter/confread.c index a4705425c..fc7dd390f 100644 --- a/src/starter/confread.c +++ b/src/starter/confread.c @@ -185,6 +185,73 @@ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token, /* post processing of some keywords that were assigned automatically */ switch (token) { + case KW_HOST: + free(end->host); + end->host = NULL; + 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; + } + } + if (!end->allow_any) + { + end->host = clone_str(value); + } + } + break; case KW_SUBNET: if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0) || (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0)) @@ -294,67 +361,6 @@ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token, /* 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")) { @@ -455,7 +461,7 @@ err: * handles left|right= DNS resolution failure */ static void handle_dns_failure(const char *label, starter_end_t *end, - starter_config_t *cfg) + starter_config_t *cfg, starter_conn_t *conn) { if (end->dns_failed) { @@ -464,7 +470,7 @@ static void handle_dns_failure(const char *label, starter_end_t *end, plog("# fallback to %s=%%any due to '%%' prefix or %sallowany=yes", label, label); } - else + else if (!end->host || conn->keyexchange != KEY_EXCHANGE_IKEV2) { /* declare an error */ cfg->err++; @@ -792,8 +798,8 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg } } - handle_dns_failure("left", &conn->left, cfg); - handle_dns_failure("right", &conn->right, cfg); + handle_dns_failure("left", &conn->left, cfg, conn); + handle_dns_failure("right", &conn->right, cfg, conn); handle_firewall("left", &conn->left, cfg); handle_firewall("right", &conn->right, cfg); } diff --git a/src/starter/confread.h b/src/starter/confread.h index fe3219f32..5e60ba0db 100644 --- a/src/starter/confread.h +++ b/src/starter/confread.h @@ -66,6 +66,7 @@ struct starter_end { char *groups; char *cert_policy; char *iface; + char *host; ip_address addr; u_int ikeport; ip_address nexthop; diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index 6ead95c8b..e399b1c04 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -169,8 +169,15 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta msg_end->ca2 = push_string(msg, conn_end->ca2); msg_end->groups = push_string(msg, conn_end->groups); msg_end->updown = push_string(msg, conn_end->updown); - ip_address2string(&conn_end->addr, buffer, sizeof(buffer)); - msg_end->address = push_string(msg, buffer); + if (conn_end->host) + { + msg_end->address = push_string(msg, conn_end->host); + } + else + { + ip_address2string(&conn_end->addr, buffer, sizeof(buffer)); + msg_end->address = push_string(msg, buffer); + } msg_end->ikeport = conn_end->ikeport; msg_end->subnets = push_string(msg, conn_end->subnet); msg_end->sourceip = push_string(msg, conn_end->sourceip);