use the configured NM connection id as configuration/IKE_SA name
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nm-setting-vpn.h>
|
#include <nm-setting-vpn.h>
|
||||||
|
#include <nm-setting-connection.h>
|
||||||
#include "nm_service.h"
|
#include "nm_service.h"
|
||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
@@ -25,8 +26,6 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define CONFIG_NAME "NetworkManager"
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(NMStrongswanPlugin, nm_strongswan_plugin, NM_TYPE_VPN_PLUGIN)
|
G_DEFINE_TYPE(NMStrongswanPlugin, nm_strongswan_plugin, NM_TYPE_VPN_PLUGIN)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,6 +42,8 @@ typedef struct {
|
|||||||
nm_creds_t *creds;
|
nm_creds_t *creds;
|
||||||
/* attribute handler for DNS/NBNS server information */
|
/* attribute handler for DNS/NBNS server information */
|
||||||
nm_handler_t *handler;
|
nm_handler_t *handler;
|
||||||
|
/* name of the connection */
|
||||||
|
char *name;
|
||||||
} NMStrongswanPluginPrivate;
|
} NMStrongswanPluginPrivate;
|
||||||
|
|
||||||
#define NM_STRONGSWAN_PLUGIN_GET_PRIVATE(o) \
|
#define NM_STRONGSWAN_PLUGIN_GET_PRIVATE(o) \
|
||||||
@@ -209,9 +210,9 @@ static bool ike_rekey(listener_t *listener, ike_sa_t *old, ike_sa_t *new)
|
|||||||
static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
nm_creds_t *creds;
|
NMStrongswanPluginPrivate *priv;
|
||||||
NMSettingVPN *settings;
|
NMSettingConnection *conn;
|
||||||
listener_t *listener;
|
NMSettingVPN *vpn;
|
||||||
identification_t *user = NULL, *gateway;
|
identification_t *user = NULL, *gateway;
|
||||||
const char *address, *str;
|
const char *address, *str;
|
||||||
bool virtual, encap, ipcomp;
|
bool virtual, encap, ipcomp;
|
||||||
@@ -229,25 +230,34 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
/**
|
/**
|
||||||
* Read parameters
|
* Read parameters
|
||||||
*/
|
*/
|
||||||
settings = NM_SETTING_VPN(nm_connection_get_setting(connection,
|
priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin);
|
||||||
NM_TYPE_SETTING_VPN));
|
conn = NM_SETTING_CONNECTION(nm_connection_get_setting(connection,
|
||||||
|
NM_TYPE_SETTING_CONNECTION));
|
||||||
DBG4(DBG_CFG, "received NetworkManager connection: %s",
|
vpn = NM_SETTING_VPN(nm_connection_get_setting(connection,
|
||||||
nm_setting_to_string(NM_SETTING(settings)));
|
NM_TYPE_SETTING_VPN));
|
||||||
address = nm_setting_vpn_get_data_item(settings, "address");
|
if (priv->name)
|
||||||
|
{
|
||||||
|
free(priv->name);
|
||||||
|
}
|
||||||
|
priv->name = strdup(nm_setting_connection_get_id(conn));
|
||||||
|
DBG1(DBG_CFG, "received initiate for NetworkManager connection %s",
|
||||||
|
priv->name);
|
||||||
|
DBG4(DBG_CFG, "%s",
|
||||||
|
nm_setting_to_string(NM_SETTING(vpn)));
|
||||||
|
address = nm_setting_vpn_get_data_item(vpn, "address");
|
||||||
if (!address || !*address)
|
if (!address || !*address)
|
||||||
{
|
{
|
||||||
g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
|
g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
|
||||||
"Gateway address missing.");
|
"Gateway address missing.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
str = nm_setting_vpn_get_data_item(settings, "virtual");
|
str = nm_setting_vpn_get_data_item(vpn, "virtual");
|
||||||
virtual = str && streq(str, "yes");
|
virtual = str && streq(str, "yes");
|
||||||
str = nm_setting_vpn_get_data_item(settings, "encap");
|
str = nm_setting_vpn_get_data_item(vpn, "encap");
|
||||||
encap = str && streq(str, "yes");
|
encap = str && streq(str, "yes");
|
||||||
str = nm_setting_vpn_get_data_item(settings, "ipcomp");
|
str = nm_setting_vpn_get_data_item(vpn, "ipcomp");
|
||||||
ipcomp = str && streq(str, "yes");
|
ipcomp = str && streq(str, "yes");
|
||||||
str = nm_setting_vpn_get_data_item(settings, "method");
|
str = nm_setting_vpn_get_data_item(vpn, "method");
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
if (streq(str, "psk"))
|
if (streq(str, "psk"))
|
||||||
@@ -268,16 +278,15 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
/**
|
/**
|
||||||
* Register credentials
|
* Register credentials
|
||||||
*/
|
*/
|
||||||
creds = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds;
|
priv->creds->clear(priv->creds);
|
||||||
creds->clear(creds);
|
|
||||||
|
|
||||||
/* gateway/CA cert */
|
/* gateway/CA cert */
|
||||||
str = nm_setting_vpn_get_data_item(settings, "certificate");
|
str = nm_setting_vpn_get_data_item(vpn, "certificate");
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||||
BUILD_FROM_FILE, str, BUILD_END);
|
BUILD_FROM_FILE, str, BUILD_END);
|
||||||
creds->set_certificate(creds, cert);
|
priv->creds->set_certificate(priv->creds, cert);
|
||||||
}
|
}
|
||||||
if (!cert)
|
if (!cert)
|
||||||
{
|
{
|
||||||
@@ -304,19 +313,19 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
if (auth_class == AUTH_CLASS_EAP)
|
if (auth_class == AUTH_CLASS_EAP)
|
||||||
{
|
{
|
||||||
/* username/password authentication ... */
|
/* username/password authentication ... */
|
||||||
str = nm_setting_vpn_get_data_item(settings, "user");
|
str = nm_setting_vpn_get_data_item(vpn, "user");
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
user = identification_create_from_string((char*)str);
|
user = identification_create_from_string((char*)str);
|
||||||
str = nm_setting_vpn_get_secret(settings, "password");
|
str = nm_setting_vpn_get_secret(vpn, "password");
|
||||||
creds->set_username_password(creds, user, (char*)str);
|
priv->creds->set_username_password(priv->creds, user, (char*)str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth_class == AUTH_CLASS_PUBKEY)
|
if (auth_class == AUTH_CLASS_PUBKEY)
|
||||||
{
|
{
|
||||||
/* ... or certificate/private key authenitcation */
|
/* ... or certificate/private key authenitcation */
|
||||||
str = nm_setting_vpn_get_data_item(settings, "usercert");
|
str = nm_setting_vpn_get_data_item(vpn, "usercert");
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
public_key_t *public;
|
public_key_t *public;
|
||||||
@@ -333,7 +342,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/* try agent */
|
/* try agent */
|
||||||
str = nm_setting_vpn_get_secret(settings, "agent");
|
str = nm_setting_vpn_get_secret(vpn, "agent");
|
||||||
if (agent && str)
|
if (agent && str)
|
||||||
{
|
{
|
||||||
public = cert->get_public_key(cert);
|
public = cert->get_public_key(cert);
|
||||||
@@ -354,14 +363,13 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* ... or key file */
|
/* ... or key file */
|
||||||
str = nm_setting_vpn_get_data_item(settings, "userkey");
|
str = nm_setting_vpn_get_data_item(vpn, "userkey");
|
||||||
if (!agent && str)
|
if (!agent && str)
|
||||||
{
|
{
|
||||||
chunk_t secret, chunk;
|
chunk_t secret, chunk;
|
||||||
bool pgp = FALSE;
|
bool pgp = FALSE;
|
||||||
|
|
||||||
secret.ptr = (char*)nm_setting_vpn_get_secret(settings,
|
secret.ptr = (char*)nm_setting_vpn_get_secret(vpn, "password");
|
||||||
"password");
|
|
||||||
if (secret.ptr)
|
if (secret.ptr)
|
||||||
{
|
{
|
||||||
secret.len = strlen(secret.ptr);
|
secret.len = strlen(secret.ptr);
|
||||||
@@ -383,7 +391,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
{
|
{
|
||||||
user = cert->get_subject(cert);
|
user = cert->get_subject(cert);
|
||||||
user = user->clone(user);
|
user = user->clone(user);
|
||||||
creds->set_cert_and_key(creds, cert, private);
|
priv->creds->set_cert_and_key(priv->creds, cert, private);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -407,7 +415,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
*/
|
*/
|
||||||
ike_cfg = ike_cfg_create(TRUE, encap, "0.0.0.0", (char*)address);
|
ike_cfg = ike_cfg_create(TRUE, encap, "0.0.0.0", (char*)address);
|
||||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||||
peer_cfg = peer_cfg_create(CONFIG_NAME, 2, ike_cfg,
|
peer_cfg = peer_cfg_create(priv->name, 2, ike_cfg,
|
||||||
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
|
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
|
||||||
36000, 0, /* rekey 10h, reauth none */
|
36000, 0, /* rekey 10h, reauth none */
|
||||||
600, 600, /* jitter, over 10min */
|
600, 600, /* jitter, over 10min */
|
||||||
@@ -423,7 +431,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
auth->add(auth, AUTH_RULE_IDENTITY, gateway);
|
auth->add(auth, AUTH_RULE_IDENTITY, gateway);
|
||||||
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
|
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
|
||||||
|
|
||||||
child_cfg = child_cfg_create(CONFIG_NAME,
|
child_cfg = child_cfg_create(priv->name,
|
||||||
10800, 10200, /* lifetime 3h, rekey 2h50min */
|
10800, 10200, /* lifetime 3h, rekey 2h50min */
|
||||||
300, /* jitter 5min */
|
300, /* jitter 5min */
|
||||||
NULL, TRUE, MODE_TUNNEL, /* updown, hostaccess */
|
NULL, TRUE, MODE_TUNNEL, /* updown, hostaccess */
|
||||||
@@ -454,18 +462,17 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
/**
|
/**
|
||||||
* Register listener, enable initiate-failure-detection hooks
|
* Register listener, enable initiate-failure-detection hooks
|
||||||
*/
|
*/
|
||||||
NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->ike_sa = ike_sa;
|
priv->ike_sa = ike_sa;
|
||||||
listener = &NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->listener;
|
priv->listener.ike_state_change = ike_state_change;
|
||||||
listener->ike_state_change = ike_state_change;
|
priv->listener.child_state_change = child_state_change;
|
||||||
listener->child_state_change = child_state_change;
|
charon->bus->add_listener(charon->bus, &priv->listener);
|
||||||
charon->bus->add_listener(charon->bus, listener);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate
|
* Initiate
|
||||||
*/
|
*/
|
||||||
if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
|
if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
|
||||||
{
|
{
|
||||||
charon->bus->remove_listener(charon->bus, listener);
|
charon->bus->remove_listener(charon->bus, &priv->listener);
|
||||||
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
|
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
|
||||||
|
|
||||||
g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
|
g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
|
||||||
@@ -533,14 +540,16 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
|
|||||||
*/
|
*/
|
||||||
static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
|
static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
|
||||||
{
|
{
|
||||||
|
NMStrongswanPluginPrivate *priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin);
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
u_int id;
|
u_int id;
|
||||||
|
|
||||||
|
/* our ike_sa pointer might be invalid, lookup sa */
|
||||||
enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
|
enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
|
||||||
while (enumerator->enumerate(enumerator, &ike_sa))
|
while (enumerator->enumerate(enumerator, &ike_sa))
|
||||||
{
|
{
|
||||||
if (streq(CONFIG_NAME, ike_sa->get_name(ike_sa)))
|
if (priv->ike_sa == ike_sa)
|
||||||
{
|
{
|
||||||
id = ike_sa->get_unique_id(ike_sa);
|
id = ike_sa->get_unique_id(ike_sa);
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
@@ -561,13 +570,13 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
|
|||||||
*/
|
*/
|
||||||
static void nm_strongswan_plugin_init(NMStrongswanPlugin *plugin)
|
static void nm_strongswan_plugin_init(NMStrongswanPlugin *plugin)
|
||||||
{
|
{
|
||||||
NMStrongswanPluginPrivate *private;
|
NMStrongswanPluginPrivate *priv;
|
||||||
|
|
||||||
private = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin);
|
priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin);
|
||||||
private->plugin = NM_VPN_PLUGIN(plugin);
|
priv->plugin = NM_VPN_PLUGIN(plugin);
|
||||||
memset(&private->listener.log, 0, sizeof(listener_t));
|
memset(&priv->listener.log, 0, sizeof(listener_t));
|
||||||
private->listener.child_updown = child_updown;
|
priv->listener.child_updown = child_updown;
|
||||||
private->listener.ike_rekey = ike_rekey;
|
priv->listener.ike_rekey = ike_rekey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -597,8 +606,12 @@ NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds,
|
|||||||
NULL);
|
NULL);
|
||||||
if (plugin)
|
if (plugin)
|
||||||
{
|
{
|
||||||
NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds = creds;
|
NMStrongswanPluginPrivate *priv;
|
||||||
NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler = handler;
|
|
||||||
|
priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin);
|
||||||
|
priv->creds = creds;
|
||||||
|
priv->handler = handler;
|
||||||
|
priv->name = NULL;
|
||||||
}
|
}
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user