starter passes unresolved DNS names to charon
authorMartin Willi <martin@revosec.ch>
Mon, 29 Aug 2011 07:58:18 +0000 (09:58 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 29 Aug 2011 07:58:18 +0000 (09:58 +0200)
Based on an initial patch by Mirko Parthey.

src/starter/args.c
src/starter/confread.c
src/starter/confread.h
src/starter/starterstroke.c

index 863d1b9..ad5916f 100644 (file)
@@ -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                               },
index a470542..fc7dd39 100644 (file)
@@ -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=<FQDN> 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);
 }
index fe3219f..5e60ba0 100644 (file)
@@ -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;
index 6ead95c..e399b1c 100644 (file)
@@ -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);