summaryrefslogtreecommitdiff
path: root/src/starter/confread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/starter/confread.c')
-rw-r--r--src/starter/confread.c257
1 files changed, 164 insertions, 93 deletions
diff --git a/src/starter/confread.c b/src/starter/confread.c
index e7a4789a9..2fe5b8ca7 100644
--- a/src/starter/confread.c
+++ b/src/starter/confread.c
@@ -181,14 +181,42 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
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);
+ initsubnet(&any, 0, '0', &end->subnet);
+ end->has_client = TRUE;
+ }
else
{
+ bool fallback_to_any = FALSE;
+
+ if (value[0] == '%')
+ {
+ fallback_to_any = TRUE;
+ 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);
- goto err;
+ if (fallback_to_any)
+ {
+ plog("# fallback to %s=%%any due to '%%' prefix");
+ anyaddr(conn->addr_family, &end->addr);
+ end->allow_any = FALSE;
+ cfg->non_fatal_err++;
+ }
+ else
+ {
+ goto err;
+ }
}
}
break;
@@ -465,11 +493,12 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
case KW_EAP:
/* TODO: a gperf function for all EAP types */
if (streq(kw->value, "aka"))
+ {
conn->eap = 23;
+ }
else if (streq(kw->value, "sim"))
{
conn->eap = 18;
-
}
else
{
@@ -481,6 +510,23 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
}
}
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;
@@ -695,7 +741,79 @@ find_also_ca(const char* name, starter_ca_t *ca, starter_config_t *cfg)
return NULL;
}
+/*
+ * free the memory used by also_t objects
+ */
+static void
+free_also(also_t *head)
+{
+ while (head != NULL)
+ {
+ also_t *also = head;
+
+ head = also->next;
+ pfree(also->name);
+ pfree(also);
+ }
+}
+
+/*
+ * free the memory used by a starter_conn_t object
+ */
+static void
+confread_free_conn(starter_conn_t *conn)
+{
+ free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left);
+ free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right);
+ free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
+ free_also(conn->also);
+}
+
+/*
+ * free the memory used by a starter_ca_t object
+ */
+static void
+confread_free_ca(starter_ca_t *ca)
+{
+ free_args(KW_CA_NAME, KW_CA_LAST, (char *)ca);
+ free_also(ca->also);
+}
+
+/*
+ * free the memory used by a starter_config_t object
+ */
+void
+confread_free(starter_config_t *cfg)
+{
+ starter_conn_t *conn = cfg->conn_first;
+ starter_ca_t *ca = cfg->ca_first;
+
+ free_args(KW_SETUP_FIRST, KW_SETUP_LAST, (char *)cfg);
+
+ confread_free_conn(&cfg->conn_default);
+
+ while (conn != NULL)
+ {
+ starter_conn_t *conn_aux = conn;
+
+ conn = conn->next;
+ confread_free_conn(conn_aux);
+ pfree(conn_aux);
+ }
+
+ confread_free_ca(&cfg->ca_default);
+
+ while (ca != NULL)
+ {
+ starter_ca_t *ca_aux = ca;
+
+ ca = ca->next;
+ confread_free_ca(ca_aux);
+ pfree(ca_aux);
+ }
+ pfree(cfg);
+}
/*
* load and parse an IPsec configuration file
@@ -709,6 +827,7 @@ confread_load(const char *file)
starter_conn_t *conn;
starter_ca_t *ca;
+ u_int total_err;
u_int visit = 0;
/* load IPSec configuration file */
@@ -748,6 +867,8 @@ confread_load(const char *file)
/* load other ca sections */
for (sca = cfgp->ca_first; sca; sca = sca->next)
{
+ u_int previous_err;
+
/* skip %default ca section */
if (streq(sca->name, "%default"))
continue;
@@ -761,13 +882,24 @@ confread_load(const char *file)
ca->kw = sca->kw;
ca->next = NULL;
- if (cfg->ca_last)
- cfg->ca_last->next = ca;
- cfg->ca_last = ca;
- if (!cfg->ca_first)
- cfg->ca_first = ca;
-
+ previous_err = cfg->err;
load_ca(ca, ca->kw, cfg);
+ if (cfg->err > previous_err)
+ {
+ /* errors occurred - free the ca */
+ confread_free_ca(ca);
+ cfg->non_fatal_err += cfg->err - previous_err;
+ cfg->err = previous_err;
+ }
+ else
+ {
+ /* success - insert the ca into the chained list */
+ if (cfg->ca_last)
+ cfg->ca_last->next = ca;
+ cfg->ca_last = ca;
+ if (!cfg->ca_first)
+ cfg->ca_first = ca;
+ }
}
for (ca = cfg->ca_first; ca; ca = ca->next)
@@ -806,6 +938,8 @@ confread_load(const char *file)
/* load other conn sections */
for (sconn = cfgp->conn_first; sconn; sconn = sconn->next)
{
+ u_int previous_err;
+
/* skip %default conn section */
if (streq(sconn->name, "%default"))
continue;
@@ -818,14 +952,25 @@ confread_load(const char *file)
conn_default(sconn->name, conn, &cfg->conn_default);
conn->kw = sconn->kw;
conn->next = NULL;
-
- if (cfg->conn_last)
- cfg->conn_last->next = conn;
- cfg->conn_last = conn;
- if (!cfg->conn_first)
- cfg->conn_first = conn;
-
+
+ previous_err = cfg->err;
load_conn(conn, conn->kw, cfg);
+ if (cfg->err > previous_err)
+ {
+ /* error occurred - free the conn */
+ confread_free_conn(conn);
+ cfg->non_fatal_err += cfg->err - previous_err;
+ cfg->err = previous_err;
+ }
+ else
+ {
+ /* success - insert the conn into the chained list */
+ if (cfg->conn_last)
+ cfg->conn_last->next = conn;
+ cfg->conn_last = conn;
+ if (!cfg->conn_first)
+ cfg->conn_first = conn;
+ }
}
/* in the second round do not parse also statements */
@@ -851,86 +996,12 @@ confread_load(const char *file)
parser_free_conf(cfgp);
- if (cfg->err)
+ total_err = cfg->err + cfg->non_fatal_err;
+ if (total_err > 0)
{
- plog("### %d parsing error%s ###", cfg->err, (cfg->err > 1)?"s":"");
- confread_free(cfg);
- cfg = NULL;
+ plog("### %d parsing error%s (%d fatal) ###"
+ , total_err, (total_err > 1)?"s":"", cfg->err);
}
return cfg;
}
-
-/*
- * free the memory used by also_t objects
- */
-static void
-free_also(also_t *head)
-{
- while (head != NULL)
- {
- also_t *also = head;
-
- head = also->next;
- pfree(also->name);
- pfree(also);
- }
-}
-
-/*
- * free the memory used by a starter_conn_t object
- */
-static void
-confread_free_conn(starter_conn_t *conn)
-{
- free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left);
- free_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->right);
- free_args(KW_CONN_NAME, KW_CONN_LAST, (char *)conn);
- free_also(conn->also);
-}
-
-/*
- * free the memory used by a starter_ca_t object
- */
-static void
-confread_free_ca(starter_ca_t *ca)
-{
- free_args(KW_CA_NAME, KW_CA_LAST, (char *)ca);
- free_also(ca->also);
-}
-
-/*
- * free the memory used by a starter_config_t object
- */
-void
-confread_free(starter_config_t *cfg)
-{
- starter_conn_t *conn = cfg->conn_first;
- starter_ca_t *ca = cfg->ca_first;
-
- free_args(KW_SETUP_FIRST, KW_SETUP_LAST, (char *)cfg);
-
- confread_free_conn(&cfg->conn_default);
-
- while (conn != NULL)
- {
- starter_conn_t *conn_aux = conn;
-
- conn = conn->next;
- confread_free_conn(conn_aux);
- pfree(conn_aux);
- }
-
- confread_free_ca(&cfg->ca_default);
-
- while (ca != NULL)
- {
- starter_ca_t *ca_aux = ca;
-
- ca = ca->next;
- confread_free_ca(ca_aux);
- pfree(ca_aux);
- }
-
- pfree(cfg);
-}