charon-nm: Add option to configure local traffic selectors

Closes strongswan/strongswan#2084
This commit is contained in:
Tobias Brunner 2024-11-12 13:56:16 +01:00
parent 941b7194a5
commit 9aa2be8411

View 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);
}
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);
/**