]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
peer-cfg: Store mediated_by as name and not peer-cfg reference
authorTobias Brunner <tobias@strongswan.org>
Tue, 7 Feb 2017 10:30:49 +0000 (11:30 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 16 Feb 2017 18:24:09 +0000 (19:24 +0100)
This way updates to the mediation config are respected and the order in
which configs are configured/loaded does not matter.

The SQL plugin currently maintains the strong relationship between
mediated and mediation connection (we could theoretically change that to a
string too).

src/libcharon/config/peer_cfg.c
src/libcharon/config/peer_cfg.h
src/libcharon/plugins/medcli/medcli_config.c
src/libcharon/plugins/sql/sql_config.c
src/libcharon/plugins/stroke/stroke_config.c
src/libcharon/processing/jobs/initiate_mediation_job.c

index 5665b66c46fb782ca3bab618ebbdb6efe50e7398..5d7ab076e7ea3780d97f8627c83e9bb3706a0ffc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2016 Tobias Brunner
+ * Copyright (C) 2007-2017 Tobias Brunner
  * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * HSR Hochschule fuer Technik Rapperswil
@@ -164,7 +164,7 @@ struct private_peer_cfg_t {
        /**
         * Name of the mediation connection to mediate through
         */
-       peer_cfg_t *mediated_by;
+       char *mediated_by;
 
        /**
         * ID of our peer at the mediation server (= leftid of the peer's conn with
@@ -580,7 +580,7 @@ METHOD(peer_cfg_t, is_mediation, bool,
        return this->mediation;
 }
 
-METHOD(peer_cfg_t, get_mediated_by, peer_cfg_t*,
+METHOD(peer_cfg_t, get_mediated_by, char*,
        private_peer_cfg_t *this)
 {
        return this->mediated_by;
@@ -683,7 +683,7 @@ METHOD(peer_cfg_t, equals, bool,
                auth_cfg_equal(this, other)
 #ifdef ME
                && this->mediation == other->mediation &&
-               this->mediated_by == other->mediated_by &&
+               streq(this->mediated_by, other->mediated_by) &&
                (this->peer_id == other->peer_id ||
                 (this->peer_id && other->peer_id &&
                  this->peer_id->equals(this->peer_id, other->peer_id)))
@@ -713,8 +713,8 @@ METHOD(peer_cfg_t, destroy, void,
                this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
                this->pools->destroy_function(this->pools, free);
 #ifdef ME
-               DESTROY_IF(this->mediated_by);
                DESTROY_IF(this->peer_id);
+               free(this->mediated_by);
 #endif /* ME */
                this->mutex->destroy(this->mutex);
                free(this->name);
@@ -802,7 +802,7 @@ peer_cfg_t *peer_cfg_create(char *name, ike_cfg_t *ike_cfg,
                .refcount = 1,
 #ifdef ME
                .mediation = data->mediation,
-               .mediated_by = data->mediated_by,
+               .mediated_by = strdupnull(data->mediated_by),
                .peer_id = data->peer_id,
 #endif /* ME */
        );
index 8e4d5331c88f53c9e539c1b3bd3158681ef68b1a..b294ae72f7fb6fbb9fc15e32a0efa3df9fd23adf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2016 Tobias Brunner
+ * Copyright (C) 2007-2017 Tobias Brunner
  * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * HSR Hochschule fuer Technik Rapperswil
@@ -319,14 +319,14 @@ struct peer_cfg_t {
         *
         * @return                              TRUE, if this is a mediation connection
         */
-       bool (*is_mediation) (peer_cfg_t *this);
+       bool (*is_mediation)(peer_cfg_t *this);
 
        /**
-        * Get peer_cfg of the connection this one is mediated through.
+        * Get name of the connection this one is mediated through.
         *
-        * @return                              the peer_cfg of the mediation connection
+        * @return                              the name of the mediation connection
         */
-       peer_cfg_t* (*get_mediated_by) (peer_cfg_t *this);
+       char* (*get_mediated_by)(peer_cfg_t *this);
 
        /**
         * Get the id of the other peer at the mediation server.
@@ -338,7 +338,7 @@ struct peer_cfg_t {
         *
         * @return                              the id of the other peer
         */
-       identification_t* (*get_peer_id) (peer_cfg_t *this);
+       identification_t* (*get_peer_id)(peer_cfg_t *this);
 #endif /* ME */
 
        /**
@@ -398,8 +398,8 @@ struct peer_cfg_create_t {
 #ifdef ME
        /** TRUE if this is a mediation connection */
        bool mediation;
-       /** peer_cfg_t of the mediation connection to mediate through (adopted) */
-       peer_cfg_t *mediated_by;
+       /** peer_cfg_t of the mediation connection to mediate through (cloned) */
+       char *mediated_by;
        /** ID that identifies our peer at the mediation server (adopted) */
        identification_t *peer_id;
 #endif /* ME */
index 4452739c1121f23d30732a25c013b891a69df851..78159c845a1e7a0ef4301e7d451e65811ec7fec4 100644 (file)
 
 typedef struct private_medcli_config_t private_medcli_config_t;
 
+/**
+ * Name of the mediation connection
+ */
+#define MEDIATION_CONN_NAME "medcli-mediation"
+
 /**
  * Private data of an medcli_config_t object
  */
@@ -72,36 +77,19 @@ static traffic_selector_t *ts_from_string(char *str)
        return traffic_selector_create_dynamic(0, 0, 65535);
 }
 
-METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
-       private_medcli_config_t *this, char *name)
+/**
+ * Build a mediation config
+ */
+static peer_cfg_t *build_mediation_config(private_medcli_config_t *this,
+                                                                                 peer_cfg_create_t *defaults)
 {
        enumerator_t *e;
-       peer_cfg_t *peer_cfg, *med_cfg;
        auth_cfg_t *auth;
        ike_cfg_t *ike_cfg;
-       child_cfg_t *child_cfg;
+       peer_cfg_t *med_cfg;
+       peer_cfg_create_t peer = *defaults;
        chunk_t me, other;
-       char *address, *local_net, *remote_net;
-       peer_cfg_create_t peer = {
-               .cert_policy = CERT_NEVER_SEND,
-               .unique = UNIQUE_REPLACE,
-               .keyingtries = 1,
-               .rekey_time = this->rekey * 60,
-               .jitter_time = this->rekey * 5,
-               .over_time = this->rekey * 3,
-               .dpd = this->dpd,
-               .mediation = TRUE,
-       };
-       child_cfg_create_t child = {
-               .lifetime = {
-                       .time = {
-                               .life = this->rekey * 60 + this->rekey,
-                               .rekey = this->rekey,
-                               .jitter = this->rekey
-                       },
-               },
-               .mode = MODE_TUNNEL,
-       };
+       char *address;
 
        /* query mediation server config:
         * - build ike_cfg/peer_cfg for mediation connection on-the-fly
@@ -120,7 +108,9 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
                                                         address, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
        ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
-       med_cfg = peer_cfg_create("mediation", ike_cfg, &peer);
+
+       peer.mediation = TRUE;
+       med_cfg = peer_cfg_create(MEDIATION_CONN_NAME, ike_cfg, &peer);
        e->destroy(e);
 
        auth = auth_cfg_create();
@@ -133,6 +123,42 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
        auth->add(auth, AUTH_RULE_IDENTITY,
                          identification_create_from_encoding(ID_KEY_ID, other));
        med_cfg->add_auth_cfg(med_cfg, auth, FALSE);
+       return med_cfg;
+}
+
+METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
+       private_medcli_config_t *this, char *name)
+{
+       enumerator_t *e;
+       auth_cfg_t *auth;
+       peer_cfg_t *peer_cfg;
+       child_cfg_t *child_cfg;
+       chunk_t me, other;
+       char *local_net, *remote_net;
+       peer_cfg_create_t peer = {
+               .cert_policy = CERT_NEVER_SEND,
+               .unique = UNIQUE_REPLACE,
+               .keyingtries = 1,
+               .rekey_time = this->rekey * 60,
+               .jitter_time = this->rekey * 5,
+               .over_time = this->rekey * 3,
+               .dpd = this->dpd,
+       };
+       child_cfg_create_t child = {
+               .lifetime = {
+                       .time = {
+                               .life = this->rekey * 60 + this->rekey,
+                               .rekey = this->rekey,
+                               .jitter = this->rekey
+                       },
+               },
+               .mode = MODE_TUNNEL,
+       };
+
+       if (streq(name, "medcli-mediation"))
+       {
+               return build_mediation_config(this, &peer);
+       }
 
        /* query mediated config:
         * - use any-any ike_cfg
@@ -150,8 +176,7 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
                DESTROY_IF(e);
                return NULL;
        }
-       peer.mediation = FALSE;
-       peer.mediated_by = med_cfg;
+       peer.mediated_by = MEDIATION_CONN_NAME;
        peer.peer_id = identification_create_from_encoding(ID_KEY_ID, other);
        peer_cfg = peer_cfg_create(name, this->ike->get_ref(this->ike), &peer);
 
index bbc20dca7222ae0bb1cfdd61708e29611040d78e..88cac7f2650a198280e1e37726f53d0de4d5c21b 100644 (file)
@@ -381,12 +381,14 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
                ike = get_ike_cfg_by_id(this, ike_cfg);
 
 #ifdef ME
-               mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by) : NULL;
+               mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by)
+                                                                  : NULL;
                if (p_type)
                {
                        peer_id = identification_create_from_encoding(p_type, p_data);
                }
-#endif
+#endif /* ME */
+
                if (virtual)
                {
                        vip = host_create_from_string(virtual, 0);
@@ -405,7 +407,8 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
                                .dpd = dpd_delay,
 #ifdef ME
                                .mediation = mediation,
-                               .mediated_by = mediated_cfg,
+                               .mediated_by = mediated_cfg ?
+                                                                       mediated_cfg->get_name(mediated_cfg) : NULL,
                                .peer_id = peer_id,
 #endif /* ME */
                        };
@@ -443,6 +446,7 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
                        }
                        peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
                        add_child_cfgs(this, peer_cfg, id);
+                       DESTROY_IF(mediated_cfg);
                        return peer_cfg;
                }
                DESTROY_IF(ike);
index 49bf3ab60b21c2c477ab0292871714779bf99a38..bbdc2116d8b4da55b88fb8e52222e26f26348ecd 100644 (file)
@@ -642,28 +642,9 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
                /* force unique connections for mediation connections */
                msg->add_conn.unique = 1;
        }
-
-       if (msg->add_conn.ikeme.mediated_by)
+       else if (msg->add_conn.ikeme.mediated_by)
        {
-               peer_cfg_t *mediated_by;
-
-               mediated_by = charon->backends->get_peer_cfg_by_name(
-                                                       charon->backends, msg->add_conn.ikeme.mediated_by);
-               if (!mediated_by)
-               {
-                       DBG1(DBG_CFG, "mediation connection '%s' not found, aborting",
-                                msg->add_conn.ikeme.mediated_by);
-                       return NULL;
-               }
-               if (!mediated_by->is_mediation(mediated_by))
-               {
-                       DBG1(DBG_CFG, "connection '%s' as referred to by '%s' is "
-                                "no mediation connection, aborting",
-                                msg->add_conn.ikeme.mediated_by, msg->add_conn.name);
-                       mediated_by->destroy(mediated_by);
-                       return NULL;
-               }
-               peer.mediated_by = mediated_by;
+               peer.mediated_by = msg->add_conn.ikeme.mediated_by;
                if (msg->add_conn.ikeme.peerid)
                {
                        peer.peer_id = identification_create_from_string(
index 6c01ffe95ea08990ea5f294ef31bd4c13e466b24..1082eae0b63d55ab7efad66b0f517be842daaed8 100644 (file)
@@ -82,8 +82,25 @@ METHOD(job_t, initiate, job_requeue_t,
 
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
 
-               mediation_cfg = mediated_cfg->get_mediated_by(mediated_cfg);
-               mediation_cfg->get_ref(mediation_cfg);
+               mediation_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
+                                                               mediated_cfg->get_mediated_by(mediated_cfg));
+               if (!mediation_cfg)
+               {
+                       DBG1(DBG_IKE, "mediation connection '%s' not found, aborting",
+                                mediated_cfg->get_mediated_by(mediated_cfg));
+                       mediated_cfg->destroy(mediated_cfg);
+                       return JOB_REQUEUE_NONE;
+               }
+               if (!mediation_cfg->is_mediation(mediation_cfg))
+               {
+                       DBG1(DBG_CFG, "connection '%s' as referred to by '%s' is no "
+                                "mediation connection, aborting",
+                                mediated_cfg->get_mediated_by(mediated_cfg),
+                                mediated_cfg->get_name(mediated_cfg));
+                       mediated_cfg->destroy(mediated_cfg);
+                       mediation_cfg->destroy(mediation_cfg);
+                       return JOB_REQUEUE_NONE;
+               }
 
                enumerator = mediation_cfg->create_auth_cfg_enumerator(mediation_cfg,
                                                                                                                           TRUE);