Pass IKE version to peer config enumerator, filter configs
authorMartin Willi <martin@revosec.ch>
Sat, 17 Dec 2011 12:31:27 +0000 (13:31 +0100)
committerMartin Willi <martin@revosec.ch>
Tue, 20 Mar 2012 16:31:25 +0000 (17:31 +0100)
src/libcharon/config/backend_manager.c
src/libcharon/config/backend_manager.h
src/libcharon/config/peer_cfg.c
src/libcharon/plugins/smp/smp.c
src/libcharon/plugins/stroke/stroke_control.c
src/libcharon/plugins/stroke/stroke_list.c
src/libcharon/plugins/uci/uci_control.c
src/libcharon/processing/jobs/start_action_job.c
src/libcharon/sa/tasks/ike_auth.c
src/libcharon/sa/tasks/main_mode.c

index e7e7a90..507f26d 100644 (file)
@@ -146,10 +146,11 @@ METHOD(backend_manager_t, get_ike_cfg, ike_cfg_t*,
        ike_cfg_match_t match, best = MATCH_ANY;
        ike_data_t *data;
 
-       data = malloc_thing(ike_data_t);
-       data->this = this;
-       data->me = me;
-       data->other = other;
+       INIT(data,
+               .this = this,
+               .me = me,
+               .other = other,
+       );
 
        DBG2(DBG_CFG, "looking for an ike config for %H...%H", me, other);
 
@@ -233,6 +234,22 @@ static id_match_t get_peer_match(identification_t *id,
 }
 
 /**
+ * Get match quality of IKE version
+ */
+static int get_version_match(ike_version_t cfg, ike_version_t req)
+{
+       if (req == IKE_ANY || cfg == IKE_ANY)
+       {
+               return 1;
+       }
+       if (req == cfg)
+       {
+               return 2;
+       }
+       return 0;
+}
+
+/**
  * data to pass nested peer enumerator
  */
 typedef struct {
@@ -325,17 +342,18 @@ static void insert_sorted(match_entry_t *entry, linked_list_t *list,
 
 METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
        private_backend_manager_t *this, host_t *me, host_t *other,
-       identification_t *my_id, identification_t *other_id)
+       identification_t *my_id, identification_t *other_id, ike_version_t version)
 {
        enumerator_t *enumerator;
        peer_data_t *data;
        peer_cfg_t *cfg;
        linked_list_t *configs, *helper;
 
-       data = malloc_thing(peer_data_t);
-       data->lock = this->lock;
-       data->me = my_id;
-       data->other = other_id;
+       INIT(data,
+               .lock = this->lock,
+               .me = my_id,
+               .other = other_id,
+       );
 
        /* create a sorted list with all matches */
        this->lock->read_lock(this->lock);
@@ -355,22 +373,26 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
        {
                id_match_t match_peer_me, match_peer_other;
                ike_cfg_match_t match_ike;
+               int match_version;
                match_entry_t *entry;
 
                match_peer_me = get_peer_match(my_id, cfg, TRUE);
                match_peer_other = get_peer_match(other_id, cfg, FALSE);
                match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other);
+               match_version = get_version_match(cfg->get_ike_version(cfg), version);
                DBG3(DBG_CFG, "ike config match: %d (%H %H)", match_ike, me, other);
 
-               if (match_peer_me && match_peer_other && match_ike)
+               if (match_peer_me && match_peer_other && match_ike && match_version)
                {
-                       DBG2(DBG_CFG, "  candidate \"%s\", match: %d/%d/%d (me/other/ike)",
-                                cfg->get_name(cfg), match_peer_me, match_peer_other, match_ike);
-
-                       entry = malloc_thing(match_entry_t);
-                       entry->match_peer = match_peer_me + match_peer_other;
-                       entry->match_ike = match_ike;
-                       entry->cfg = cfg->get_ref(cfg);
+                       DBG2(DBG_CFG, "  candidate \"%s\", match: %d/%d/%d/%d "
+                                "(me/other/ike/version)", cfg->get_name(cfg),
+                                match_peer_me, match_peer_other, match_ike, match_version);
+
+                       INIT(entry,
+                               .match_peer = match_peer_me + match_peer_other,
+                               .match_ike = match_ike,
+                               .cfg = cfg->get_ref(cfg),
+                       );
                        insert_sorted(entry, configs, helper);
                }
        }
index 5b394f7..de26336 100644 (file)
@@ -56,6 +56,7 @@ struct backend_manager_t {
         *
         * @param my_host                       address of own host
         * @param other_host            address of remote host
+        * @param version                       IKE version to get a config for
         * @return                                      matching ike_config, or NULL if none found
         */
        ike_cfg_t* (*get_ike_cfg)(backend_manager_t *this,
@@ -79,11 +80,12 @@ struct backend_manager_t {
         * @param other                         remote address
         * @param my_id                         IDr in first authentication round
         * @param other_id                      IDi in first authentication round
+        * @param version                       IKE version to get a config for
         * @return                                      enumerator over peer_cfg_t
         */
        enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this,
                                                        host_t *me, host_t *other, identification_t *my_id,
-                                                       identification_t *other_id);
+                                                       identification_t *other_id, ike_version_t version);
        /**
         * Register a backend on the manager.
         *
index fbdfa25..b58bdce 100644 (file)
@@ -25,7 +25,8 @@
 #include <utils/linked_list.h>
 #include <utils/identification.h>
 
-ENUM(ike_version_names, IKEV1, IKEV2,
+ENUM(ike_version_names, IKE_ANY, IKEV2,
+       "IKEv1/2"
        "IKEv1",
        "IKEv2",
 );
index 0db2874..c2fe11f 100644 (file)
@@ -294,7 +294,7 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
        xmlTextWriterStartElement(writer, "configlist");
 
        enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
-                                                                                                               NULL, NULL, NULL, NULL);
+                                                                                       NULL, NULL, NULL, NULL, IKE_ANY);
        while (enumerator->enumerate(enumerator, &peer_cfg))
        {
                enumerator_t *children;
index 98f57b5..3264cb8 100644 (file)
@@ -149,8 +149,8 @@ METHOD(stroke_control_t, initiate, void,
        }
        else
        {
-               enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
-                                                                                                       NULL, NULL, NULL, NULL);
+               enumerator = charon->backends->create_peer_cfg_enumerator(
+                                                       charon->backends, NULL, NULL, NULL, NULL, IKE_ANY);
                while (enumerator->enumerate(enumerator, &peer_cfg))
                {
                        child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
@@ -579,8 +579,8 @@ METHOD(stroke_control_t, route, void,
        }
        else
        {
-               enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
-                                                                                                       NULL, NULL, NULL, NULL);
+               enumerator = charon->backends->create_peer_cfg_enumerator(
+                                                       charon->backends, NULL, NULL, NULL, NULL, IKE_ANY);
                while (enumerator->enumerate(enumerator, &peer_cfg))
                {
                        child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
index eb16047..19fc464 100644 (file)
@@ -497,7 +497,7 @@ METHOD(stroke_list_t, status, void,
 
                fprintf(out, "Connections:\n");
                enumerator = charon->backends->create_peer_cfg_enumerator(
-                                                                       charon->backends, NULL, NULL, NULL, NULL);
+                                                       charon->backends, NULL, NULL, NULL, NULL, IKE_ANY);
                while (enumerator->enumerate(enumerator, &peer_cfg))
                {
                        if (name && !streq(name, peer_cfg->get_name(peer_cfg)))
@@ -506,8 +506,9 @@ METHOD(stroke_list_t, status, void,
                        }
 
                        ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
-                       fprintf(out, "%12s:  %s...%s", peer_cfg->get_name(peer_cfg),
-                               ike_cfg->get_my_addr(ike_cfg), ike_cfg->get_other_addr(ike_cfg));
+                       fprintf(out, "%12s:  %s...%s (%N)", peer_cfg->get_name(peer_cfg),
+                               ike_cfg->get_my_addr(ike_cfg), ike_cfg->get_other_addr(ike_cfg),
+                               ike_version_names, peer_cfg->get_ike_version(peer_cfg));
 
                        dpd = peer_cfg->get_dpd(peer_cfg);
                        if (dpd)
index af4a6a7..87d0f86 100644 (file)
@@ -84,7 +84,7 @@ static void status(private_uci_control_t *this, char *name)
        FILE *out = NULL;
 
        configs = charon->backends->create_peer_cfg_enumerator(charon->backends,
-                                                                                                               NULL, NULL, NULL, NULL);
+                                                                                       NULL, NULL, NULL, NULL, IKE_ANY);
        while (configs->enumerate(configs, &peer_cfg))
        {
                if (name && !streq(name, peer_cfg->get_name(peer_cfg)))
index efb53ac..294ac15 100644 (file)
@@ -46,7 +46,7 @@ METHOD(job_t, execute, void,
        char *name;
 
        enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
-                                                                                                       NULL, NULL, NULL, NULL);
+                                                                                       NULL, NULL, NULL, NULL, IKE_ANY);
        while (enumerator->enumerate(enumerator, &peer_cfg))
        {
                children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
index 39d865c..f9cf5c6 100644 (file)
@@ -272,7 +272,7 @@ static bool load_cfg_candidates(private_ike_auth_t *this)
        DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]",
                 me, my_id, other, other_id);
        enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
-                                                                                                       me, other, my_id, other_id);
+                                                                                       me, other, my_id, other_id, IKEV2);
        while (enumerator->enumerate(enumerator, &peer_cfg))
        {
                peer_cfg->get_ref(peer_cfg);
index 5b2cdf7..08bb291 100644 (file)
@@ -406,7 +406,7 @@ static peer_cfg_t *select_config(private_main_mode_t *this, identification_t *id
        DBG1(DBG_CFG, "looking for %N peer configs matching %H...%H[%Y]",
                 auth_method_names, this->auth_method, me, other, id);
        enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
-                                                                                                               me, other, NULL, id);
+                                                                                                       me, other, NULL, id, IKEV1);
        while (enumerator->enumerate(enumerator, &current))
        {
                if (get_auth_method(this, current) == this->auth_method)
@@ -811,7 +811,7 @@ static shared_key_t *lookup_shared_key(private_main_mode_t *this)
                peer_cfg_t *peer_cfg = NULL;
 
                enumerator = charon->backends->create_peer_cfg_enumerator(
-                                                                       charon->backends, me, other, NULL, NULL);
+                                                               charon->backends, me, other, NULL, NULL, IKEV1);
                while (enumerator->enumerate(enumerator, &peer_cfg))
                {
                        my_auth = get_auth_cfg(peer_cfg, TRUE);