]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
vici: Order auth rounds by optional `round` parameter instead of by position in the...
authorTobias Brunner <tobias@strongswan.org>
Thu, 19 Nov 2015 11:58:23 +0000 (12:58 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 8 Mar 2016 09:04:55 +0000 (10:04 +0100)
src/libcharon/plugins/vici/vici_config.c
src/swanctl/swanctl.opt

index 181b14b406970fd2597951885a7fc4b2baf0c561..6cf127b74d5df6ae0b2b40899bec7ae8ae3f3104 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2014 Martin Willi
  * Copyright (C) 2014 revosec AG
  *
+ * Copyright (C) 2015-2016 Tobias Brunner
  * Copyright (C) 2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
@@ -224,6 +225,24 @@ typedef struct {
        vici_message_t *reply;
 } request_data_t;
 
+/**
+ * Auth config data
+ */
+typedef struct {
+       request_data_t *request;
+       auth_cfg_t *cfg;
+       u_int32_t round;
+} auth_data_t;
+
+/**
+ * Clean up auth config data
+ */
+static void free_auth_data(auth_data_t *data)
+{
+       DESTROY_IF(data->cfg);
+       free(data);
+}
+
 /**
  * Data associated to a peer config
  */
@@ -318,7 +337,7 @@ static void log_auth(auth_cfg_t *auth)
 static void log_peer_data(peer_data_t *data)
 {
        enumerator_t *enumerator;
-       auth_cfg_t *auth;
+       auth_data_t *auth;
        host_t *host;
 
        DBG2(DBG_CFG, "  version = %u", data->version);
@@ -357,7 +376,7 @@ static void log_peer_data(peer_data_t *data)
        while (enumerator->enumerate(enumerator, &auth))
        {
                DBG2(DBG_CFG, "  local:");
-               log_auth(auth);
+               log_auth(auth->cfg);
        }
        enumerator->destroy(enumerator);
 
@@ -365,7 +384,7 @@ static void log_peer_data(peer_data_t *data)
        while (enumerator->enumerate(enumerator, &auth))
        {
                DBG2(DBG_CFG, "  remote:");
-               log_auth(auth);
+               log_auth(auth->cfg);
        }
        enumerator->destroy(enumerator);
 }
@@ -375,10 +394,8 @@ static void log_peer_data(peer_data_t *data)
  */
 static void free_peer_data(peer_data_t *data)
 {
-       data->local->destroy_offset(data->local,
-                                                                       offsetof(auth_cfg_t, destroy));
-       data->remote->destroy_offset(data->remote,
-                                                                       offsetof(auth_cfg_t, destroy));
+       data->local->destroy_function(data->local, (void*)free_auth_data);
+       data->remote->destroy_function(data->remote, (void*)free_auth_data);
        data->children->destroy_offset(data->children,
                                                                        offsetof(child_cfg_t, destroy));
        data->proposals->destroy_offset(data->proposals,
@@ -467,14 +484,6 @@ static void free_child_data(child_data_t *data)
        free(data->updown);
 }
 
-/**
- * Auth config data
- */
-typedef struct {
-       request_data_t *request;
-       auth_cfg_t *cfg;
-} auth_data_t;
-
 /**
  * Common proposal parsing
  */
@@ -1344,6 +1353,7 @@ CALLBACK(auth_kv, bool,
                { "eap_id",                     parse_eap_id,           auth->cfg                                       },
                { "xauth_id",           parse_xauth_id,         auth->cfg                                       },
                { "revocation",         parse_revocation,       auth->cfg                                       },
+               { "round",                      parse_uint32,           &auth->round                            },
        };
 
        return parse_rules(rules, countof(rules), name, value,
@@ -1547,25 +1557,28 @@ CALLBACK(peer_sn, bool,
        if (strcasepfx(name, "local") ||
                strcasepfx(name, "remote"))
        {
-               auth_data_t auth = {
-                       .request = peer->request,
-                       .cfg = auth_cfg_create(),
-               };
+               enumerator_t *enumerator;
+               linked_list_t *auths;
+               auth_data_t *auth, *current;
                auth_rule_t rule;
                certificate_t *cert;
                pubkey_cert_t *pubkey_cert;
                identification_t *id;
-               enumerator_t *enumerator;
                bool default_id = FALSE;
 
-               if (!message->parse(message, ctx, NULL, auth_kv, auth_li, &auth))
+               INIT(auth,
+                       .request = peer->request,
+                       .cfg = auth_cfg_create(),
+               );
+
+               if (!message->parse(message, ctx, NULL, auth_kv, auth_li, auth))
                {
-                       auth.cfg->destroy(auth.cfg);
+                       free_auth_data(auth);
                        return FALSE;
                }
-               id   = auth.cfg->get(auth.cfg, AUTH_RULE_IDENTITY);
+               id = auth->cfg->get(auth->cfg, AUTH_RULE_IDENTITY);
 
-               enumerator = auth.cfg->create_enumerator(auth.cfg);
+               enumerator = auth->cfg->create_enumerator(auth->cfg);
                while (enumerator->enumerate(enumerator, &rule, &cert))
                {
                        if (rule == AUTH_RULE_SUBJECT_CERT && !default_id)
@@ -1575,7 +1588,7 @@ CALLBACK(peer_sn, bool,
                                        id = cert->get_subject(cert);
                                        DBG1(DBG_CFG, "  id not specified, defaulting to"
                                                                  " cert subject '%Y'", id);
-                                       auth.cfg->add(auth.cfg, AUTH_RULE_IDENTITY, id->clone(id));
+                                       auth->cfg->add(auth->cfg, AUTH_RULE_IDENTITY, id->clone(id));
                                        default_id = TRUE;
                                }
                                else if (cert->get_type(cert) == CERT_TRUSTED_PUBKEY &&
@@ -1589,14 +1602,17 @@ CALLBACK(peer_sn, bool,
                }
                enumerator->destroy(enumerator);
 
-               if (strcasepfx(name, "local"))
+               auths = strcasepfx(name, "local") ? peer->local : peer->remote;
+               enumerator = auths->create_enumerator(auths);
+               while (enumerator->enumerate(enumerator, &current))
                {
-                       peer->local->insert_last(peer->local, auth.cfg);
-               }
-               else
-               {
-                       peer->remote->insert_last(peer->remote, auth.cfg);
+                       if (auth->round < current->round)
+                       {
+                               break;
+                       }
                }
+               auths->insert_before(auths, enumerator, auth);
+               enumerator->destroy(enumerator);
                return TRUE;
        }
        peer->request->reply = create_reply("invalid section: %s", name);
@@ -1932,7 +1948,7 @@ CALLBACK(config_sn, bool,
        peer_cfg_t *peer_cfg;
        ike_cfg_t *ike_cfg;
        child_cfg_t *child_cfg;
-       auth_cfg_t *auth_cfg;
+       auth_data_t *auth;
        proposal_t *proposal;
        host_t *host;
        char *str;
@@ -1947,13 +1963,17 @@ CALLBACK(config_sn, bool,
 
        if (peer.local->get_count(peer.local) == 0)
        {
-               auth_cfg = auth_cfg_create();
-               peer.local->insert_last(peer.local, auth_cfg);
+               INIT(auth,
+                       .cfg = auth_cfg_create(),
+               );
+               peer.local->insert_last(peer.local, auth);
        }
        if (peer.remote->get_count(peer.remote) == 0)
        {
-               auth_cfg = auth_cfg_create();
-               peer.remote->insert_last(peer.remote, auth_cfg);
+               INIT(auth,
+                       .cfg = auth_cfg_create(),
+               );
+               peer.remote->insert_last(peer.remote, auth);
        }
        if (peer.proposals->get_count(peer.proposals) == 0)
        {
@@ -2029,14 +2049,18 @@ CALLBACK(config_sn, bool,
                                                FALSE, NULL, NULL);
 
        while (peer.local->remove_first(peer.local,
-                                                                       (void**)&auth_cfg) == SUCCESS)
+                                                                       (void**)&auth) == SUCCESS)
        {
-               peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
+               peer_cfg->add_auth_cfg(peer_cfg, auth->cfg, TRUE);
+               auth->cfg = NULL;
+               free_auth_data(auth);
        }
        while (peer.remote->remove_first(peer.remote,
-                                                                        (void**)&auth_cfg) == SUCCESS)
+                                                                        (void**)&auth) == SUCCESS)
        {
-               peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
+               peer_cfg->add_auth_cfg(peer_cfg, auth->cfg, FALSE);
+               auth->cfg = NULL;
+               free_auth_data(auth);
        }
        while (peer.children->remove_first(peer.children,
                                                                           (void**)&child_cfg) == SUCCESS)
index b053fe32ae1f6afaff1926dd5a15ce6273487a01..145fab28d2b82824d039a343c5c0404680ea7fb2 100644 (file)
@@ -268,6 +268,11 @@ connections.<conn>.local<suffix> {}
        unique suffix. To define a single authentication round, the suffix may be
        omitted.
 
+connections.<conn>.local<suffix>.round = 0
+       Optional numeric identifier by which authentication rounds are sorted.  If
+       not specified rounds are ordered by their position in the config file/VICI
+       message.
+
 connections.<conn>.local<suffix>.certs =
        Comma separated list of certificate candidates to use for authentication.
 
@@ -374,6 +379,11 @@ connections.<conn>.remote<suffix> {}
        optional unique suffix. To define a single authentication round, the suffix
        may be omitted.
 
+connections.<conn>.remote<suffix>.round = 0
+       Optional numeric identifier by which authentication rounds are sorted.  If
+       not specified rounds are ordered by their position in the config file/VICI
+       message.
+
 connections.<conn>.remote<suffix>.id = %any
        IKE identity to expect for authentication round.