diff options
Diffstat (limited to 'src/charon-nm/nm')
-rw-r--r-- | src/charon-nm/nm/nm_backend.c | 4 | ||||
-rw-r--r-- | src/charon-nm/nm/nm_service.c | 64 | ||||
-rw-r--r-- | src/charon-nm/nm/nm_service.h | 6 |
3 files changed, 63 insertions, 11 deletions
diff --git a/src/charon-nm/nm/nm_backend.c b/src/charon-nm/nm/nm_backend.c index 5bb2ed930..c18bf992a 100644 --- a/src/charon-nm/nm/nm_backend.c +++ b/src/charon-nm/nm/nm_backend.c @@ -173,6 +173,10 @@ void nm_backend_register() PLUGIN_CALLBACK((plugin_feature_callback_t)nm_backend_cb, NULL), PLUGIN_PROVIDE(CUSTOM, "NetworkManager backend"), PLUGIN_DEPENDS(CUSTOM, "libcharon"), + PLUGIN_SDEPEND(PRIVKEY, KEY_RSA), + PLUGIN_SDEPEND(PRIVKEY, KEY_ECDSA), + PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY), + PLUGIN_SDEPEND(CERT_DECODE, CERT_X509), }; lib->plugins->add_static_features(lib->plugins, "nm-backend", features, countof(features), TRUE); diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index eb187496d..901abd348 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2013 Tobias Brunner * Copyright (C) 2008-2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -22,6 +23,7 @@ #include <utils/identification.h> #include <config/peer_cfg.h> #include <credentials/certificates/x509.h> +#include <networking/tun_device.h> #include <stdio.h> @@ -41,6 +43,8 @@ typedef struct { nm_creds_t *creds; /* attribute handler for DNS/NBNS server information */ nm_handler_t *handler; + /* dummy TUN device */ + tun_device_t *tun; /* name of the connection */ char *name; } NMStrongswanPluginPrivate; @@ -80,23 +84,33 @@ static GValue* handler_to_val(nm_handler_t *handler, static void signal_ipv4_config(NMVPNPlugin *plugin, ike_sa_t *ike_sa, child_sa_t *child_sa) { + NMStrongswanPluginPrivate *priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); GValue *val; GHashTable *config; + enumerator_t *enumerator; host_t *me; nm_handler_t *handler; config = g_hash_table_new(g_str_hash, g_str_equal); - me = ike_sa->get_my_host(ike_sa); - handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler; + handler = priv->handler; /* NM requires a tundev, but netkey does not use one. Passing the physical - * interface does not work, as NM fiddles around with it. Passing the - * loopback seems to work, though... */ + * interface does not work, as NM fiddles around with it. So we pass a dummy + * TUN device along for NM to play with... */ val = g_slice_new0 (GValue); g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, "lo"); + g_value_set_string (val, priv->tun->get_name(priv->tun)); g_hash_table_insert (config, NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, val); + /* NM installs this IP address on the interface above, so we use the VIP if + * we got one. + */ + enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE); + if (!enumerator->enumerate(enumerator, &me)) + { + me = ike_sa->get_my_host(ike_sa); + } + enumerator->destroy(enumerator); val = g_slice_new0(GValue); g_value_init(val, G_TYPE_UINT); g_value_set_uint(val, *(u_int32_t*)me->get_address(me).ptr); @@ -107,6 +121,14 @@ static void signal_ipv4_config(NMVPNPlugin *plugin, g_value_set_uint(val, me->get_address(me).len * 8); g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val); + /* prevent NM from changing the default route. we set our own route in our + * own routing table + */ + val = g_slice_new0(GValue); + g_value_init(val, G_TYPE_BOOLEAN); + g_value_set_boolean(val, TRUE); + g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT, val); + val = handler_to_val(handler, INTERNAL_IP4_DNS); g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_DNS, val); @@ -303,6 +325,13 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, priv->name); DBG4(DBG_CFG, "%s", nm_setting_to_string(NM_SETTING(vpn))); + if (!priv->tun) + { + g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, + "Failed to create dummy TUN device."); + gateway->destroy(gateway); + return FALSE; + } address = nm_setting_vpn_get_data_item(vpn, "address"); if (!address || !*address) { @@ -501,7 +530,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, ike_cfg = ike_cfg_create(IKEV2, TRUE, encap, "0.0.0.0", FALSE, charon->socket->get_port(charon->socket, FALSE), (char*)address, FALSE, IKEV2_UDP_PORT, - FRAGMENTATION_NO); + FRAGMENTATION_NO, 0); ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); peer_cfg = peer_cfg_create(priv->name, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */ @@ -680,6 +709,25 @@ static void nm_strongswan_plugin_init(NMStrongswanPlugin *plugin) memset(&priv->listener, 0, sizeof(listener_t)); priv->listener.child_updown = child_updown; priv->listener.ike_rekey = ike_rekey; + priv->tun = tun_device_create(NULL); + priv->name = NULL; +} + +/** + * Destructor + */ +static void nm_strongswan_plugin_dispose(GObject *obj) +{ + NMStrongswanPlugin *plugin; + NMStrongswanPluginPrivate *priv; + + plugin = NM_STRONGSWAN_PLUGIN(obj); + priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); + if (priv->tun) + { + priv->tun->destroy(priv->tun); + priv->tun = NULL; + } } /** @@ -695,6 +743,7 @@ static void nm_strongswan_plugin_class_init( parent_class->connect = connect_; parent_class->need_secrets = need_secrets; parent_class->disconnect = disconnect; + G_OBJECT_CLASS(strongswan_class)->dispose = nm_strongswan_plugin_dispose; } /** @@ -711,11 +760,10 @@ NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds, { NMStrongswanPluginPrivate *priv; + /* the rest of the initialization happened in _init above */ priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); priv->creds = creds; priv->handler = handler; - priv->name = NULL; } return plugin; } - diff --git a/src/charon-nm/nm/nm_service.h b/src/charon-nm/nm/nm_service.h index 828d1a452..0cb23e120 100644 --- a/src/charon-nm/nm/nm_service.h +++ b/src/charon-nm/nm/nm_service.h @@ -29,11 +29,11 @@ #include "nm_handler.h" #define NM_TYPE_STRONGSWAN_PLUGIN (nm_strongswan_plugin_get_type ()) -#define NM_STRONGSWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPlugin)) -#define NM_STRONGSWAN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPluginClass)) +#define NM_STRONGSWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMStrongswanPlugin)) +#define NM_STRONGSWAN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_STRONGSWAN_PLUGIN, NMStrongswanPluginClass)) #define NM_IS_STRONGSWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_STRONGSWAN_PLUGIN)) #define NM_IS_STRONGSWAN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_STRONGSWAN_PLUGIN)) -#define NM_STRONGSWAN_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPluginClass)) +#define NM_STRONGSWAN_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMStrongswanPluginClass)) #define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan" #define NM_DBUS_INTERFACE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan" |