use the configured NM connection id as configuration/IKE_SA name

This commit is contained in:
Martin Willi
2009-07-10 11:01:44 +02:00
parent ce741aa649
commit 69b8058925
+58 -45
View File
@@ -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;
} }