stroke: Add an option to disable side-swapping of configuration options
authorTobias Brunner <tobias@strongswan.org>
Mon, 3 Aug 2015 17:26:54 +0000 (19:26 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 21 Aug 2015 16:19:26 +0000 (18:19 +0200)
In some scenarios it might be preferred to ensure left is always local
and no unintended swaps occur.

conf/plugins/stroke.opt
src/libcharon/plugins/stroke/stroke_config.c

index 4b49b1f..ad5e62d 100644 (file)
@@ -1,3 +1,8 @@
+charon.plugins.stroke.allow_swap = yes
+       Analyze addresses/hostnames in _left|right_ to detect which side is local
+       and swap configuration options if necessary. If disabled _left_ is always
+       _local_.
+
 charon.plugins.stroke.ignore_missing_ca_basic_constraint = no
        Treat certificates in ipsec.d/cacerts and ipsec.conf ca sections as CA
        certificates even if they don't contain a CA basic constraint.
index 55ec7cd..afd88cb 100644 (file)
@@ -184,19 +184,16 @@ static void add_proposals(private_stroke_config_t *this, char *string,
 }
 
 /**
- * Build an IKE config from a stroke message
+ * Check if any addresses in the given string are local
  */
-static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg)
+static bool is_local(char *address)
 {
        enumerator_t *enumerator;
-       stroke_end_t tmp_end;
-       ike_cfg_t *ike_cfg;
        host_t *host;
-       u_int16_t ikeport;
-       char me[256], other[256], *token;
-       bool swapped = FALSE;;
+       char *token;
+       bool found = FALSE;
 
-       enumerator = enumerator_create_token(msg->add_conn.other.address, ",", " ");
+       enumerator = enumerator_create_token(address, ",", " ");
        while (enumerator->enumerate(enumerator, &token))
        {
                if (!strchr(token, '/'))
@@ -207,40 +204,56 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
                                if (hydra->kernel_interface->get_interface(
                                                                                hydra->kernel_interface, host, NULL))
                                {
-                                       DBG2(DBG_CFG, "left is other host, swapping ends");
-                                       tmp_end = msg->add_conn.me;
-                                       msg->add_conn.me = msg->add_conn.other;
-                                       msg->add_conn.other = tmp_end;
-                                       swapped = TRUE;
+                                       found = TRUE;
                                }
                                host->destroy(host);
+                               if (found)
+                               {
+                                       break;
+                               }
                        }
                }
        }
        enumerator->destroy(enumerator);
+       return found;
+}
 
-       if (!swapped)
+/**
+ * Swap ends if indicated by left|right
+ */
+static void swap_ends(stroke_msg_t *msg)
+{
+       if (!lib->settings->get_bool(lib->settings, "%s.plugins.stroke.allow_swap",
+                                                                TRUE, lib->ns))
        {
-               enumerator = enumerator_create_token(msg->add_conn.me.address, ",", " ");
-               while (enumerator->enumerate(enumerator, &token))
-               {
-                       if (!strchr(token, '/'))
-                       {
-                               host = host_create_from_dns(token, 0, 0);
-                               if (host)
-                               {
-                                       if (!hydra->kernel_interface->get_interface(
-                                                                               hydra->kernel_interface, host, NULL))
-                                       {
-                                               DBG1(DBG_CFG, "left nor right host is our side, "
-                                                        "assuming left=local");
-                                       }
-                                       host->destroy(host);
-                               }
-                       }
-               }
-               enumerator->destroy(enumerator);
+               return;
+       }
+
+       if (is_local(msg->add_conn.other.address))
+       {
+               stroke_end_t tmp_end;
+
+               DBG2(DBG_CFG, "left is other host, swapping ends");
+               tmp_end = msg->add_conn.me;
+               msg->add_conn.me = msg->add_conn.other;
+               msg->add_conn.other = tmp_end;
+       }
+       else if (!is_local(msg->add_conn.me.address))
+       {
+               DBG1(DBG_CFG, "left nor right host is our side, assuming left=local");
        }
+}
+
+/**
+ * Build an IKE config from a stroke message
+ */
+static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg)
+{
+       ike_cfg_t *ike_cfg;
+       u_int16_t ikeport;
+       char me[256], other[256];
+
+       swap_ends(msg);
 
        if (msg->add_conn.me.allow_any)
        {