]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
charon-nm: Add option to configure local traffic selectors
authorTobias Brunner <tobias@strongswan.org>
Tue, 12 Nov 2024 12:56:16 +0000 (13:56 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 6 Feb 2025 16:20:25 +0000 (17:20 +0100)
Closes strongswan/strongswan#2084

src/charon-nm/nm/nm_service.c

index 5d907ddbfa38a511317ee0b53ade5d868c9c2128..b920d5857f729064f2633bd722cedb4cc413e294 100644 (file)
@@ -674,6 +674,51 @@ static bool add_auth_cfg_pw(NMStrongswanPluginPrivate *priv,
        return TRUE;
 }
 
+/**
+ * Add traffic selectors to the given config, optionally parse them from a
+ * semicolon-separated list.
+ */
+static bool add_traffic_selectors(child_cfg_t *child_cfg, bool local,
+                                                                 const char *list, GError **err)
+{
+       enumerator_t *enumerator;
+       traffic_selector_t *ts;
+       char *token;
+
+       if (list && strlen(list))
+       {
+               enumerator = enumerator_create_token(list, ";", "");
+               while (enumerator->enumerate(enumerator, &token))
+               {
+                       ts = traffic_selector_create_from_cidr(token, 0, 0, 65535);
+                       if (!ts)
+                       {
+                               g_set_error(err, NM_VPN_PLUGIN_ERROR,
+                                                       NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+                                                       "Invalid %s traffic selector '%s'.",
+                                                       local ? "local" : "remote", token);
+                               enumerator->destroy(enumerator);
+                               return FALSE;
+                       }
+                       child_cfg->add_traffic_selector(child_cfg, local, ts);
+               }
+               enumerator->destroy(enumerator);
+       }
+       else if (local)
+       {
+               ts = traffic_selector_create_dynamic(0, 0, 65535);
+               child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
+       }
+       else
+       {
+               ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
+               child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+               ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
+               child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+       }
+       return TRUE;
+}
+
 /**
  * Connect function called from NM via DBUS
  */
@@ -692,7 +737,6 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection,
        ike_cfg_t *ike_cfg;
        peer_cfg_t *peer_cfg;
        child_cfg_t *child_cfg;
-       traffic_selector_t *ts;
        ike_sa_t *ike_sa;
        auth_cfg_t *auth;
        certificate_t *cert = NULL;
@@ -945,36 +989,22 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection,
                child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP));
                child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
        }
-       ts = traffic_selector_create_dynamic(0, 0, 65535);
-       child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
-       str = nm_setting_vpn_get_data_item(vpn, "remote-ts");
-       if (str && strlen(str))
+
+       str = nm_setting_vpn_get_data_item(vpn, "local-ts");
+       if (!add_traffic_selectors(child_cfg, TRUE, str, err))
        {
-               enumerator = enumerator_create_token(str, ";", "");
-               while (enumerator->enumerate(enumerator, &str))
-               {
-                       ts = traffic_selector_create_from_cidr((char*)str, 0, 0, 65535);
-                       if (!ts)
-                       {
-                               g_set_error(err, NM_VPN_PLUGIN_ERROR,
-                                                       NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
-                                                       "Invalid remote traffic selector.");
-                               enumerator->destroy(enumerator);
-                               child_cfg->destroy(child_cfg);
-                               peer_cfg->destroy(peer_cfg);
-                               return FALSE;
-                       }
-                       child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
-               }
-               enumerator->destroy(enumerator);
+               child_cfg->destroy(child_cfg);
+               peer_cfg->destroy(peer_cfg);
+               return FALSE;
        }
-       else
+       str = nm_setting_vpn_get_data_item(vpn, "remote-ts");
+       if (!add_traffic_selectors(child_cfg, FALSE, str, err))
        {
-               ts = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
-               child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
-               ts = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
-               child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+               child_cfg->destroy(child_cfg);
+               peer_cfg->destroy(peer_cfg);
+               return FALSE;
        }
+
        peer_cfg->add_child_cfg(peer_cfg, child_cfg);
 
        /**