diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-12-05 16:44:41 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-12-05 16:44:41 +0000 |
commit | 2db1ef4ac8928944958712923b9c89c263a337d2 (patch) | |
tree | 700043d9d97b7e7ba344b448918728af0a8be8d1 /src/charon/plugins/nm | |
parent | 5dc75410286b0e3a16845b44dd696ba0f40df573 (diff) | |
download | vyos-strongswan-2db1ef4ac8928944958712923b9c89c263a337d2.tar.gz vyos-strongswan-2db1ef4ac8928944958712923b9c89c263a337d2.zip |
- Updated to new upstream.
Diffstat (limited to 'src/charon/plugins/nm')
-rw-r--r-- | src/charon/plugins/nm/Makefile.am | 2 | ||||
-rw-r--r-- | src/charon/plugins/nm/Makefile.in | 2 | ||||
-rw-r--r-- | src/charon/plugins/nm/nm_creds.c | 38 | ||||
-rw-r--r-- | src/charon/plugins/nm/nm_service.c | 154 |
4 files changed, 89 insertions, 107 deletions
diff --git a/src/charon/plugins/nm/Makefile.am b/src/charon/plugins/nm/Makefile.am index 107ca1a31..bb5436443 100644 --- a/src/charon/plugins/nm/Makefile.am +++ b/src/charon/plugins/nm/Makefile.am @@ -25,4 +25,4 @@ EXTRA_DIST = gnome/configure gnome/po/LINGUAS gnome/po/POTFILES.in gnome/po/Make gnome/config.sub gnome/missing gnome/configure : gnome/configure.in - cd gnome && ./autogen.sh; cd .. + (cd `dirname $<` && ./autogen.sh) diff --git a/src/charon/plugins/nm/Makefile.in b/src/charon/plugins/nm/Makefile.in index 46e4ab851..4f75da14f 100644 --- a/src/charon/plugins/nm/Makefile.in +++ b/src/charon/plugins/nm/Makefile.in @@ -513,7 +513,7 @@ uninstall-am: uninstall-pluginLTLIBRARIES gnome/configure : gnome/configure.in - cd gnome && ./autogen.sh; cd .. + (cd `dirname $<` && ./autogen.sh) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/charon/plugins/nm/nm_creds.c b/src/charon/plugins/nm/nm_creds.c index f165653ae..e7cd640a7 100644 --- a/src/charon/plugins/nm/nm_creds.c +++ b/src/charon/plugins/nm/nm_creds.c @@ -15,12 +15,10 @@ * $Id$ */ -#define _GNU_SOURCE -#include <pthread.h> - #include "nm_creds.h" #include <daemon.h> +#include <utils/mutex.h> typedef struct private_nm_creds_t private_nm_creds_t; @@ -62,7 +60,7 @@ struct private_nm_creds_t { /** * read/write lock */ - pthread_rwlock_t lock; + rwlock_t *lock; }; /** @@ -91,10 +89,10 @@ static enumerator_t *create_usercert_enumerator(private_nm_creds_t *this, } public->destroy(public); } - pthread_rwlock_rdlock(&this->lock); + this->lock->read_lock(this->lock); return enumerator_create_cleaner( enumerator_create_single(this->usercert, NULL), - (void*)pthread_rwlock_unlock, &this->lock); + (void*)this->lock->unlock, this->lock); } /** @@ -138,9 +136,9 @@ static enumerator_t* create_cert_enumerator(private_nm_creds_t *this, } public->destroy(public); } - pthread_rwlock_rdlock(&this->lock); + this->lock->read_lock(this->lock); return enumerator_create_cleaner(enumerator_create_single(this->cert, NULL), - (void*)pthread_rwlock_unlock, &this->lock); + (void*)this->lock->unlock, this->lock); } /** @@ -167,9 +165,9 @@ static enumerator_t* create_private_enumerator(private_nm_creds_t *this, return NULL; } } - pthread_rwlock_rdlock(&this->lock); + this->lock->read_lock(this->lock); return enumerator_create_cleaner(enumerator_create_single(this->key, NULL), - (void*)pthread_rwlock_unlock, &this->lock); + (void*)this->lock->unlock, this->lock); } /** @@ -205,7 +203,7 @@ static bool shared_enumerate(shared_enumerator_t *this, shared_key_t **key, static void shared_destroy(shared_enumerator_t *this) { this->key->destroy(this->key); - pthread_rwlock_unlock(&this->this->lock); + this->this->lock->unlock(this->this->lock); free(this); } /** @@ -235,7 +233,7 @@ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this, enumerator->public.destroy = (void*)shared_destroy; enumerator->this = this; enumerator->done = FALSE; - pthread_rwlock_rdlock(&this->lock); + this->lock->read_lock(this->lock); enumerator->key = shared_key_create(type, chunk_clone(chunk_create(this->pass, strlen(this->pass)))); @@ -247,10 +245,10 @@ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this, */ static void set_certificate(private_nm_creds_t *this, certificate_t *cert) { - pthread_rwlock_wrlock(&this->lock); + this->lock->write_lock(this->lock); DESTROY_IF(this->cert); this->cert = cert; - pthread_rwlock_unlock(&this->lock); + this->lock->unlock(this->lock); } /** @@ -259,14 +257,14 @@ static void set_certificate(private_nm_creds_t *this, certificate_t *cert) static void set_username_password(private_nm_creds_t *this, identification_t *id, char *password) { - pthread_rwlock_wrlock(&this->lock); + this->lock->write_lock(this->lock); DESTROY_IF(this->user); /* for EAP authentication, we use always use ID_EAP type */ this->user = identification_create_from_encoding(ID_EAP, id->get_encoding(id)); free(this->pass); this->pass = password ? strdup(password) : NULL; - pthread_rwlock_unlock(&this->lock); + this->lock->unlock(this->lock); } /** @@ -275,12 +273,12 @@ static void set_username_password(private_nm_creds_t *this, identification_t *id static void set_cert_and_key(private_nm_creds_t *this, certificate_t *cert, private_key_t *key) { - pthread_rwlock_wrlock(&this->lock); + this->lock->write_lock(this->lock); DESTROY_IF(this->key); DESTROY_IF(this->usercert); this->key = key; this->usercert = cert; - pthread_rwlock_unlock(&this->lock); + this->lock->unlock(this->lock); } /** @@ -306,7 +304,7 @@ static void clear(private_nm_creds_t *this) static void destroy(private_nm_creds_t *this) { clear(this); - pthread_rwlock_destroy(&this->lock); + this->lock->destroy(this->lock); free(this); } @@ -328,7 +326,7 @@ nm_creds_t *nm_creds_create() this->public.clear = (void(*)(nm_creds_t*))clear; this->public.destroy = (void(*)(nm_creds_t*))destroy; - pthread_rwlock_init(&this->lock, NULL); + this->lock = rwlock_create(RWLOCK_DEFAULT); this->cert = NULL; this->user = NULL; diff --git a/src/charon/plugins/nm/nm_service.c b/src/charon/plugins/nm/nm_service.c index fbc094a3b..f90bfa448 100644 --- a/src/charon/plugins/nm/nm_service.c +++ b/src/charon/plugins/nm/nm_service.c @@ -34,7 +34,7 @@ G_DEFINE_TYPE(NMStrongswanPlugin, nm_strongswan_plugin, NM_TYPE_VPN_PLUGIN) * Private data of NMStrongswanPlugin */ typedef struct { - bus_listener_t listener; + listener_t listener; ike_sa_t *ike_sa; NMVPNPlugin *plugin; nm_creds_t *creds; @@ -45,109 +45,88 @@ typedef struct { NM_TYPE_STRONGSWAN_PLUGIN, NMStrongswanPluginPrivate)) /** - * convert a traffic selector address range to subnet and its mask. + * signal IPv4 config to NM, set connection as established */ -static u_int ts2subnet(traffic_selector_t* ts, u_int8_t *mask) +static void signal_ipv4_config(NMVPNPlugin *plugin, + ike_sa_t *ike_sa, child_sa_t *child_sa) { - /* there is no way to do this cleanly, as the address range may - * be anything else but a subnet. We use from_addr as subnet - * and try to calculate a usable subnet mask. - */ - int byte, bit, net; - bool found = FALSE; - chunk_t from, to; - size_t size = (ts->get_type(ts) == TS_IPV4_ADDR_RANGE) ? 4 : 16; + GValue *val; + GHashTable *config; + host_t *me, *other; - from = ts->get_from_address(ts); - to = ts->get_to_address(ts); + config = g_hash_table_new(g_str_hash, g_str_equal); + me = ike_sa->get_my_host(ike_sa); + other = ike_sa->get_other_host(ike_sa); - *mask = (size * 8); - /* go trough all bits of the addresses, beginning in the front. - * as long as they are equal, the subnet gets larger - */ - for (byte = 0; byte < size; byte++) - { - for (bit = 7; bit >= 0; bit--) - { - if ((1<<bit & from.ptr[byte]) != (1<<bit & to.ptr[byte])) - { - *mask = ((7 - bit) + (byte * 8)); - found = TRUE; - break; - } - } - if (found) - { - break; - } - } - net = *(u_int32_t*)from.ptr; - chunk_free(&from); - chunk_free(&to); - return net; + /* NM requires a tundev, but netkey does not use one. Passing an invalid + * iface makes NM complain, but it accepts it without fiddling on eth0. */ + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, "none"); + g_hash_table_insert (config, NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, val); + + 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); + g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, val); + + val = g_slice_new0(GValue); + g_value_init(val, G_TYPE_UINT); + g_value_set_uint(val, me->get_address(me).len * 8); + g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val); + + nm_vpn_plugin_set_ip4_config(plugin, config); } /** - * signal IPv4 config to NM, set connection as established + * signal failure to NM, connecting failed */ -static void signal_ipv4_config(NMVPNPlugin *plugin, child_sa_t *child_sa) +static void signal_failure(NMVPNPlugin *plugin) { - linked_list_t *list; - traffic_selector_t *ts = NULL; - enumerator_t *enumerator; + /* TODO: NM does not handle this failure!? + nm_vpn_plugin_failure(plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); */ + nm_vpn_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED); +} + +/** + * Implementation of listener_t.ike_state_change + */ +static bool ike_state_change(listener_t *listener, ike_sa_t *ike_sa, + ike_sa_state_t state) +{ + NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; - list = child_sa->get_traffic_selectors(child_sa, FALSE); - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, &ts)) + if (private->ike_sa == ike_sa) { - GValue *val; - GHashTable *config; - u_int8_t mask; - - config = g_hash_table_new(g_str_hash, g_str_equal); - - val = g_slice_new0(GValue); - g_value_init(val, G_TYPE_UINT); - g_value_set_uint(val, ts2subnet(ts, &mask)); - g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, val); - - val = g_slice_new0(GValue); - g_value_init(val, G_TYPE_UINT); - g_value_set_uint(val, mask); - g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val); - - nm_vpn_plugin_set_ip4_config(plugin, config); + switch (state) + { + case IKE_DESTROYING: + signal_failure(private->plugin); + return FALSE; + default: + break; + } } - enumerator->destroy(enumerator); + return TRUE; } /** - * Bus listen function to wait for SA establishing + * Implementation of listener_t.child_state_change */ -bool listen_bus(bus_listener_t *listener, signal_t signal, level_t level, - int thread, ike_sa_t *ike_sa, void *data, - char* format, va_list args) +static bool child_state_change(listener_t *listener, ike_sa_t *ike_sa, + child_sa_t *child_sa, child_sa_state_t state) { NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; - + if (private->ike_sa == ike_sa) { - switch (signal) + switch (state) { - case CHD_UP_SUCCESS: - if (data) - { - signal_ipv4_config(private->plugin, (child_sa_t*)data); - return FALSE; - } - /* FALL */ - case IKE_UP_FAILED: - case CHD_UP_FAILED: - /* TODO: NM does not handle this failure!? - nm_vpn_plugin_failure(private->plugin, - NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); */ - nm_vpn_plugin_set_state(private->plugin, - NM_VPN_SERVICE_STATE_STOPPED); + case CHILD_INSTALLED: + signal_ipv4_config(private->plugin, ike_sa, child_sa); + return FALSE; + case CHILD_DESTROYING: + signal_failure(private->plugin); return FALSE; default: break; @@ -462,8 +441,13 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err) */ static void nm_strongswan_plugin_init(NMStrongswanPlugin *plugin) { - NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->plugin = NM_VPN_PLUGIN(plugin); - NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->listener.signal = listen_bus; + NMStrongswanPluginPrivate *private; + + private = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); + private->plugin = NM_VPN_PLUGIN(plugin); + memset(&private->listener.log, 0, sizeof(listener_t)); + private->listener.ike_state_change = ike_state_change; + private->listener.child_state_change = child_state_change; } /** |