diff options
Diffstat (limited to 'src/charon')
118 files changed, 2012 insertions, 606 deletions
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index 3b5b9c068..dd51555c0 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -2,6 +2,7 @@ ipsec_PROGRAMS = charon charon_SOURCES = \ bus/bus.c bus/bus.h \ +bus/listeners/listener.h \ bus/listeners/file_logger.c bus/listeners/file_logger.h \ bus/listeners/sys_logger.c bus/listeners/sys_logger.h \ config/backend_manager.c config/backend_manager.h config/backend.h \ @@ -107,7 +108,7 @@ AM_CFLAGS = -rdynamic \ -DIPSEC_PIDDIR=\"${piddir}\" \ -DIPSEC_PLUGINDIR=\"${plugindir}\" \ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" -charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm $(DLLIB) +charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm $(DLLIB) $(SOCKLIB) # compile options ################# @@ -128,10 +129,6 @@ if USE_ME sa/tasks/ike_me.c sa/tasks/ike_me.h endif -if USE_INTEGRITY_TEST - AM_CFLAGS += -DINTEGRITY_TEST -endif - if USE_CAPABILITIES charon_LDADD += -lcap endif diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in index 77884d50e..59c0228f8 100644 --- a/src/charon/Makefile.in +++ b/src/charon/Makefile.in @@ -47,56 +47,55 @@ ipsec_PROGRAMS = charon$(EXEEXT) @USE_ME_TRUE@ sa/mediation_manager.c sa/mediation_manager.h \ @USE_ME_TRUE@ sa/tasks/ike_me.c sa/tasks/ike_me.h -@USE_INTEGRITY_TEST_TRUE@am__append_4 = -DINTEGRITY_TEST -@USE_CAPABILITIES_TRUE@am__append_5 = -lcap -@USE_LOAD_TESTS_TRUE@am__append_6 = plugins/load_tester -@USE_LOAD_TESTS_TRUE@am__append_7 = load-tester -@USE_KERNEL_PFKEY_TRUE@am__append_8 = plugins/kernel_pfkey -@USE_KERNEL_PFKEY_TRUE@am__append_9 = kernel-pfkey -@USE_KERNEL_PFROUTE_TRUE@am__append_10 = plugins/kernel_pfroute -@USE_KERNEL_PFROUTE_TRUE@am__append_11 = kernel-pfroute -@USE_KERNEL_KLIPS_TRUE@am__append_12 = plugins/kernel_klips -@USE_KERNEL_KLIPS_TRUE@am__append_13 = kernel-klips -@USE_KERNEL_NETLINK_TRUE@am__append_14 = plugins/kernel_netlink -@USE_KERNEL_NETLINK_TRUE@am__append_15 = kernel-netlink -@USE_STROKE_TRUE@am__append_16 = plugins/stroke -@USE_STROKE_TRUE@am__append_17 = stroke -@USE_SMP_TRUE@am__append_18 = plugins/smp -@USE_SMP_TRUE@am__append_19 = smp -@USE_SQL_TRUE@am__append_20 = plugins/sql -@USE_SQL_TRUE@am__append_21 = sql -@USE_UPDOWN_TRUE@am__append_22 = plugins/updown -@USE_UPDOWN_TRUE@am__append_23 = updown -@USE_ATTR_TRUE@am__append_24 = plugins/attr -@USE_ATTR_TRUE@am__append_25 = attr -@USE_EAP_IDENTITY_TRUE@am__append_26 = plugins/eap_identity -@USE_EAP_IDENTITY_TRUE@am__append_27 = eapidentity -@USE_EAP_SIM_TRUE@am__append_28 = plugins/eap_sim -@USE_EAP_SIM_TRUE@am__append_29 = eapsim -@USE_EAP_SIM_FILE_TRUE@am__append_30 = plugins/eap_sim_file -@USE_EAP_SIM_FILE_TRUE@am__append_31 = eapsim-file -@USE_EAP_MD5_TRUE@am__append_32 = plugins/eap_md5 -@USE_EAP_MD5_TRUE@am__append_33 = eapmd5 -@USE_EAP_GTC_TRUE@am__append_34 = plugins/eap_gtc -@USE_EAP_GTC_TRUE@am__append_35 = eapgtc -@USE_EAP_AKA_TRUE@am__append_36 = plugins/eap_aka -@USE_EAP_AKA_TRUE@am__append_37 = eapaka -@USE_EAP_MSCHAPV2_TRUE@am__append_38 = plugins/eap_mschapv2 -@USE_EAP_MSCHAPV2_TRUE@am__append_39 = eapmschapv2 -@USE_EAP_RADIUS_TRUE@am__append_40 = plugins/eap_radius -@USE_EAP_RADIUS_TRUE@am__append_41 = eapradius -@USE_MEDSRV_TRUE@am__append_42 = plugins/medsrv -@USE_MEDSRV_TRUE@am__append_43 = medsrv -@USE_MEDCLI_TRUE@am__append_44 = plugins/medcli -@USE_MEDCLI_TRUE@am__append_45 = medcli -@USE_NM_TRUE@am__append_46 = plugins/nm -@USE_NM_TRUE@am__append_47 = nm -@USE_RESOLV_CONF_TRUE@am__append_48 = plugins/resolv_conf -@USE_RESOLV_CONF_TRUE@am__append_49 = resolv-conf -@USE_UCI_TRUE@am__append_50 = plugins/uci -@USE_UCI_TRUE@am__append_51 = uci -@USE_UNIT_TESTS_TRUE@am__append_52 = plugins/unit_tester -@USE_UNIT_TESTS_TRUE@am__append_53 = unit-tester +@USE_CAPABILITIES_TRUE@am__append_4 = -lcap +@USE_LOAD_TESTS_TRUE@am__append_5 = plugins/load_tester +@USE_LOAD_TESTS_TRUE@am__append_6 = load-tester +@USE_KERNEL_PFKEY_TRUE@am__append_7 = plugins/kernel_pfkey +@USE_KERNEL_PFKEY_TRUE@am__append_8 = kernel-pfkey +@USE_KERNEL_PFROUTE_TRUE@am__append_9 = plugins/kernel_pfroute +@USE_KERNEL_PFROUTE_TRUE@am__append_10 = kernel-pfroute +@USE_KERNEL_KLIPS_TRUE@am__append_11 = plugins/kernel_klips +@USE_KERNEL_KLIPS_TRUE@am__append_12 = kernel-klips +@USE_KERNEL_NETLINK_TRUE@am__append_13 = plugins/kernel_netlink +@USE_KERNEL_NETLINK_TRUE@am__append_14 = kernel-netlink +@USE_STROKE_TRUE@am__append_15 = plugins/stroke +@USE_STROKE_TRUE@am__append_16 = stroke +@USE_SMP_TRUE@am__append_17 = plugins/smp +@USE_SMP_TRUE@am__append_18 = smp +@USE_SQL_TRUE@am__append_19 = plugins/sql +@USE_SQL_TRUE@am__append_20 = sql +@USE_UPDOWN_TRUE@am__append_21 = plugins/updown +@USE_UPDOWN_TRUE@am__append_22 = updown +@USE_ATTR_TRUE@am__append_23 = plugins/attr +@USE_ATTR_TRUE@am__append_24 = attr +@USE_EAP_IDENTITY_TRUE@am__append_25 = plugins/eap_identity +@USE_EAP_IDENTITY_TRUE@am__append_26 = eapidentity +@USE_EAP_SIM_TRUE@am__append_27 = plugins/eap_sim +@USE_EAP_SIM_TRUE@am__append_28 = eapsim +@USE_EAP_SIM_FILE_TRUE@am__append_29 = plugins/eap_sim_file +@USE_EAP_SIM_FILE_TRUE@am__append_30 = eapsim-file +@USE_EAP_MD5_TRUE@am__append_31 = plugins/eap_md5 +@USE_EAP_MD5_TRUE@am__append_32 = eapmd5 +@USE_EAP_GTC_TRUE@am__append_33 = plugins/eap_gtc +@USE_EAP_GTC_TRUE@am__append_34 = eapgtc +@USE_EAP_AKA_TRUE@am__append_35 = plugins/eap_aka +@USE_EAP_AKA_TRUE@am__append_36 = eapaka +@USE_EAP_MSCHAPV2_TRUE@am__append_37 = plugins/eap_mschapv2 +@USE_EAP_MSCHAPV2_TRUE@am__append_38 = eapmschapv2 +@USE_EAP_RADIUS_TRUE@am__append_39 = plugins/eap_radius +@USE_EAP_RADIUS_TRUE@am__append_40 = eapradius +@USE_MEDSRV_TRUE@am__append_41 = plugins/medsrv +@USE_MEDSRV_TRUE@am__append_42 = medsrv +@USE_MEDCLI_TRUE@am__append_43 = plugins/medcli +@USE_MEDCLI_TRUE@am__append_44 = medcli +@USE_NM_TRUE@am__append_45 = plugins/nm +@USE_NM_TRUE@am__append_46 = nm +@USE_RESOLV_CONF_TRUE@am__append_47 = plugins/resolv_conf +@USE_RESOLV_CONF_TRUE@am__append_48 = resolv-conf +@USE_UCI_TRUE@am__append_49 = plugins/uci +@USE_UCI_TRUE@am__append_50 = uci +@USE_UNIT_TESTS_TRUE@am__append_51 = plugins/unit_tester +@USE_UNIT_TESTS_TRUE@am__append_52 = unit-tester subdir = src/charon DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -108,7 +107,7 @@ CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(ipsecdir)" ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(ipsec_PROGRAMS) -am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \ +am__charon_SOURCES_DIST = bus/bus.c bus/bus.h bus/listeners/listener.h \ bus/listeners/file_logger.c bus/listeners/file_logger.h \ bus/listeners/sys_logger.c bus/listeners/sys_logger.h \ config/backend_manager.c config/backend_manager.h \ @@ -289,7 +288,8 @@ charon_OBJECTS = $(am_charon_OBJECTS) am__DEPENDENCIES_1 = charon_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -325,12 +325,14 @@ DIST_SUBDIRS = . plugins/load_tester plugins/kernel_pfkey \ plugins/resolv_conf plugins/uci plugins/unit_tester DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -395,6 +397,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -435,7 +438,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -469,14 +474,15 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/file_logger.c \ - bus/listeners/file_logger.h bus/listeners/sys_logger.c \ - bus/listeners/sys_logger.h config/backend_manager.c \ - config/backend_manager.h config/backend.h config/child_cfg.c \ - config/child_cfg.h config/ike_cfg.c config/ike_cfg.h \ - config/peer_cfg.c config/peer_cfg.h config/proposal.c \ - config/proposal.h config/auth_cfg.c config/auth_cfg.h \ - config/traffic_selector.c config/traffic_selector.h \ +charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ + bus/listeners/file_logger.c bus/listeners/file_logger.h \ + bus/listeners/sys_logger.c bus/listeners/sys_logger.h \ + config/backend_manager.c config/backend_manager.h \ + config/backend.h config/child_cfg.c config/child_cfg.h \ + config/ike_cfg.c config/ike_cfg.h config/peer_cfg.c \ + config/peer_cfg.h config/proposal.c config/proposal.h \ + config/auth_cfg.c config/auth_cfg.h config/traffic_selector.c \ + config/traffic_selector.h \ config/attributes/attribute_provider.h \ config/attributes/attribute_handler.h \ config/attributes/attribute_manager.c \ @@ -593,30 +599,30 @@ INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/c AM_CFLAGS = -rdynamic -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" \ -DIPSEC_PLUGINDIR=\"${plugindir}\" \ - -DSTRONGSWAN_CONF=\"${strongswan_conf}\" $(am__append_4) \ + -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \ -DPLUGINS=\""${PLUGINS}\"" charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \ - -lpthread -lm $(DLLIB) $(am__append_5) + -lpthread -lm $(DLLIB) $(SOCKLIB) $(am__append_4) # build optional plugins ######################## -SUBDIRS = . $(am__append_6) $(am__append_8) $(am__append_10) \ - $(am__append_12) $(am__append_14) $(am__append_16) \ - $(am__append_18) $(am__append_20) $(am__append_22) \ - $(am__append_24) $(am__append_26) $(am__append_28) \ - $(am__append_30) $(am__append_32) $(am__append_34) \ - $(am__append_36) $(am__append_38) $(am__append_40) \ - $(am__append_42) $(am__append_44) $(am__append_46) \ - $(am__append_48) $(am__append_50) $(am__append_52) -PLUGINS = ${libstrongswan_plugins} $(am__append_7) $(am__append_9) \ +SUBDIRS = . $(am__append_5) $(am__append_7) $(am__append_9) \ $(am__append_11) $(am__append_13) $(am__append_15) \ $(am__append_17) $(am__append_19) $(am__append_21) \ $(am__append_23) $(am__append_25) $(am__append_27) \ $(am__append_29) $(am__append_31) $(am__append_33) \ $(am__append_35) $(am__append_37) $(am__append_39) \ $(am__append_41) $(am__append_43) $(am__append_45) \ - $(am__append_47) $(am__append_49) $(am__append_51) \ - $(am__append_53) + $(am__append_47) $(am__append_49) $(am__append_51) +PLUGINS = ${libstrongswan_plugins} $(am__append_6) $(am__append_8) \ + $(am__append_10) $(am__append_12) $(am__append_14) \ + $(am__append_16) $(am__append_18) $(am__append_20) \ + $(am__append_22) $(am__append_24) $(am__append_26) \ + $(am__append_28) $(am__append_30) $(am__append_32) \ + $(am__append_34) $(am__append_36) $(am__append_38) \ + $(am__append_40) $(am__append_42) $(am__append_44) \ + $(am__append_46) $(am__append_48) $(am__append_50) \ + $(am__append_52) all: all-recursive .SUFFIXES: diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c index bb7014b0b..2671f848e 100644 --- a/src/charon/bus/bus.c +++ b/src/charon/bus/bus.c @@ -117,7 +117,7 @@ static entry_t *entry_create(listener_t *listener, bool blocker) this->listener = listener; this->blocker = blocker; this->calling = 0; - this->condvar = condvar_create(CONDVAR_DEFAULT); + this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT); return this; } @@ -351,6 +351,41 @@ static void unregister_listener(private_bus_t *this, entry_t *entry, } /** + * Implementation of bus_t.alert + */ +static void alert(private_bus_t *this, alert_t alert, ...) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + entry_t *entry; + va_list args; + bool keep; + + ike_sa = pthread_getspecific(this->thread_sa); + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->alert) + { + continue; + } + entry->calling++; + va_start(args, alert); + keep = entry->listener->alert(entry->listener, ike_sa, alert, args); + va_end(args); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** * Implementation of bus_t.ike_state_change */ static void ike_state_change(private_bus_t *this, ike_sa_t *ike_sa, @@ -374,7 +409,6 @@ static void ike_state_change(private_bus_t *this, ike_sa_t *ike_sa, if (!keep) { unregister_listener(this, entry, enumerator); - break; } } enumerator->destroy(enumerator); @@ -409,7 +443,6 @@ static void child_state_change(private_bus_t *this, child_sa_t *child_sa, if (!keep) { unregister_listener(this, entry, enumerator); - break; } } enumerator->destroy(enumerator); @@ -443,7 +476,6 @@ static void message(private_bus_t *this, message_t *message, bool incoming) if (!keep) { unregister_listener(this, entry, enumerator); - break; } } enumerator->destroy(enumerator); @@ -476,7 +508,6 @@ static void ike_keys(private_bus_t *this, ike_sa_t *ike_sa, if (!keep) { unregister_listener(this, entry, enumerator); - break; } } enumerator->destroy(enumerator); @@ -511,7 +542,143 @@ static void child_keys(private_bus_t *this, child_sa_t *child_sa, if (!keep) { unregister_listener(this, entry, enumerator); - break; + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of bus_t.child_updown + */ +static void child_updown(private_bus_t *this, child_sa_t *child_sa, bool up) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + entry_t *entry; + bool keep; + + ike_sa = pthread_getspecific(this->thread_sa); + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->child_updown) + { + continue; + } + entry->calling++; + keep = entry->listener->child_updown(entry->listener, + ike_sa, child_sa, up); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of bus_t.child_rekey + */ +static void child_rekey(private_bus_t *this, child_sa_t *old, child_sa_t *new) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + entry_t *entry; + bool keep; + + ike_sa = pthread_getspecific(this->thread_sa); + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->child_rekey) + { + continue; + } + entry->calling++; + keep = entry->listener->child_rekey(entry->listener, ike_sa, old, new); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of bus_t.ike_updown + */ +static void ike_updown(private_bus_t *this, ike_sa_t *ike_sa, bool up) +{ + enumerator_t *enumerator; + entry_t *entry; + bool keep; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->ike_updown) + { + continue; + } + entry->calling++; + keep = entry->listener->ike_updown(entry->listener, ike_sa, up); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + + /* a down event for IKE_SA implicitly downs all CHILD_SAs */ + if (!up) + { + iterator_t *iterator; + child_sa_t *child_sa; + + iterator = ike_sa->create_child_sa_iterator(ike_sa); + while (iterator->iterate(iterator, (void**)&child_sa)) + { + child_updown(this, child_sa, FALSE); + } + iterator->destroy(iterator); + } +} + +/** + * Implementation of bus_t.ike_rekey + */ +static void ike_rekey(private_bus_t *this, ike_sa_t *old, ike_sa_t *new) +{ + enumerator_t *enumerator; + entry_t *entry; + bool keep; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->ike_rekey) + { + continue; + } + entry->calling++; + keep = entry->listener->ike_rekey(entry->listener, old, new); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); } } enumerator->destroy(enumerator); @@ -545,7 +712,6 @@ static bool authorize(private_bus_t *this, linked_list_t *auth, bool final) if (!keep) { unregister_listener(this, entry, enumerator); - break; } if (!success) { @@ -580,16 +746,21 @@ bus_t *bus_create() this->public.set_sa = (void(*)(bus_t*,ike_sa_t*))set_sa; this->public.log = (void(*)(bus_t*,debug_t,level_t,char*,...))log_; this->public.vlog = (void(*)(bus_t*,debug_t,level_t,char*,va_list))vlog; + this->public.alert = (void(*)(bus_t*, alert_t alert, ...))alert; this->public.ike_state_change = (void(*)(bus_t*,ike_sa_t*,ike_sa_state_t))ike_state_change; this->public.child_state_change = (void(*)(bus_t*,child_sa_t*,child_sa_state_t))child_state_change; this->public.message = (void(*)(bus_t*, message_t *message, bool incoming))message; this->public.ike_keys = (void(*)(bus_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys; this->public.child_keys = (void(*)(bus_t*, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r))child_keys; + this->public.ike_updown = (void(*)(bus_t*, ike_sa_t *ike_sa, bool up))ike_updown; + this->public.ike_rekey = (void(*)(bus_t*, ike_sa_t *old, ike_sa_t *new))ike_rekey; + this->public.child_updown = (void(*)(bus_t*, child_sa_t *child_sa, bool up))child_updown; + this->public.child_rekey = (void(*)(bus_t*, child_sa_t *old, child_sa_t *new))child_rekey; this->public.authorize = (bool(*)(bus_t*, linked_list_t *auth, bool final))authorize; this->public.destroy = (void(*)(bus_t*)) destroy; this->listeners = linked_list_create(); - this->mutex = mutex_create(MUTEX_RECURSIVE); + this->mutex = mutex_create(MUTEX_TYPE_RECURSIVE); pthread_key_create(&this->thread_id, NULL); pthread_key_create(&this->thread_sa, NULL); diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h index 5faea088f..9c90db6f9 100644 --- a/src/charon/bus/bus.h +++ b/src/charon/bus/bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2009 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ typedef enum debug_t debug_t; typedef enum level_t level_t; -typedef struct listener_t listener_t; +typedef enum alert_t alert_t; typedef struct bus_t bus_t; #include <stdarg.h> @@ -31,6 +31,7 @@ typedef struct bus_t bus_t; #include <sa/ike_sa.h> #include <sa/child_sa.h> #include <processing/jobs/job.h> +#include <bus/listeners/listener.h> /** * Debug message group. @@ -126,105 +127,12 @@ enum level_t { # define DBG4(...) {} #endif /* DBG4 */ - /** - * Listener interface, listens to events if registered to the bus. + * Kind of alerts to raise. */ -struct listener_t { - - /** - * Log a debugging message. - * - * The implementing signal function returns TRUE to stay registered - * to the bus, or FALSE to unregister itself. - * Calling bus_t.log() inside of a registered listener is possible, - * but the bus does not invoke listeners recursively. - * - * @param singal kind of the signal (up, down, rekeyed, ...) - * @param level verbosity level of the signal - * @param thread ID of the thread raised this signal - * @param ike_sa IKE_SA associated to the event - * @param format printf() style format string - * @param args vprintf() style va_list argument list - " @return TRUE to stay registered, FALSE to unregister - */ - bool (*log) (listener_t *this, debug_t group, level_t level, int thread, - ike_sa_t *ike_sa, char* format, va_list args); - - /** - * Handle state changes in an IKE_SA. - * - * @param ike_sa IKE_SA which changes its state - * @param state new IKE_SA state this IKE_SA changes to - * @return TRUE to stay registered, FALSE to unregister - */ - bool (*ike_state_change)(listener_t *this, ike_sa_t *ike_sa, - ike_sa_state_t state); - - /** - * Handle state changes in a CHILD_SA. - * - * @param ike_sa IKE_SA containing the affected CHILD_SA - * @param child_sa CHILD_SA which changes its state - * @param state new CHILD_SA state this CHILD_SA changes to - * @return TRUE to stay registered, FALSE to unregister - */ - bool (*child_state_change)(listener_t *this, ike_sa_t *ike_sa, - child_sa_t *child_sa, child_sa_state_t state); - - /** - * Hook called for received/sent messages of an IKE_SA. - * - * @param ike_sa IKE_SA sending/receving a message - * @param message message object - * @param incoming TRUE for incoming messages, FALSE for outgoing - * @return TRUE to stay registered, FALSE to unregister - */ - bool (*message)(listener_t *this, ike_sa_t *ike_sa, message_t *message, - bool incoming); - - /** - * Hook called with IKE_SA key material. - * - * @param ike_sa IKE_SA this keymat belongs to - * @param dh diffie hellman shared secret - * @param nonce_i initiators nonce - * @param nonce_r responders nonce - * @param rekey IKE_SA we are rekeying, if any - * @return TRUE to stay registered, FALSE to unregister - */ - bool (*ike_keys)(listener_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh, - chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey); - - /** - * Hook called with CHILD_SA key material. - * - * @param ike_sa IKE_SA the child sa belongs to - * @param child_sa CHILD_SA this keymat is used for - * @param dh diffie hellman shared secret - * @param nonce_i initiators nonce - * @param nonce_r responders nonce - * @return TRUE to stay registered, FALSE to unregister - */ - bool (*child_keys)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, - diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r); - - /** - * Hook called to invoke additional authorization rules. - * - * An authorization hook gets invoked several times: After each - * authentication round, the hook gets invoked with with final = FALSE. - * After authentication is complete and the peer configuration is selected, - * it is invoked again, but with final = TRUE. - * - * @param ike_sa IKE_SA to authorize - * @param auth list of auth_cfg_t, done in peers authentication rounds - * @param final TRUE if this is the final hook invocation - * @param success set to TRUE to complete IKE_SA, FALSE abort - * @return TRUE to stay registered, FALSE to unregister - */ - bool (*authorize)(listener_t *this, ike_sa_t *ike_sa, linked_list_t *auth, - bool final, bool *success); +enum alert_t { + /* a RADIUS server did not respond, no additional arguments */ + ALERT_RADIUS_NOT_RESPONDING, }; /** @@ -307,6 +215,15 @@ struct bus_t { */ void (*vlog)(bus_t *this, debug_t group, level_t level, char* format, va_list args); + + /** + * Raise an alert over the bus. + * + * @param alert kind of alert + * @param ... alert specific attributes + */ + void (*alert)(bus_t *this, alert_t alert, ...); + /** * Send a IKE_SA state change event to the bus. * @@ -361,6 +278,39 @@ struct bus_t { */ void (*child_keys)(bus_t *this, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r); + + /** + * IKE_SA up/down hook. + * + * @param ike_sa IKE_SA coming up/going down + * @param up TRUE for an up event, FALSE for a down event + */ + void (*ike_updown)(bus_t *this, ike_sa_t *ike_sa, bool up); + + /** + * IKE_SA rekeying hook. + * + * @param old rekeyed and obsolete IKE_SA + * @param new new IKE_SA replacing old + */ + void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new); + + /** + * CHILD_SA up/down hook. + * + * @param child_sa CHILD_SA coming up/going down + * @param up TRUE for an up event, FALSE for a down event + */ + void (*child_updown)(bus_t *this, child_sa_t *child_sa, bool up); + + /** + * CHILD_SA rekeying hook. + * + * @param old rekeyed and obsolete CHILD_SA + * @param new new CHILD_SA replacing old + */ + void (*child_rekey)(bus_t *this, child_sa_t *old, child_sa_t *new); + /** * Destroy the event bus. */ diff --git a/src/charon/bus/listeners/file_logger.h b/src/charon/bus/listeners/file_logger.h index 7282224a5..a69374f23 100644 --- a/src/charon/bus/listeners/file_logger.h +++ b/src/charon/bus/listeners/file_logger.h @@ -21,9 +21,9 @@ #ifndef FILE_LOGGER_H_ #define FILE_LOGGER_H_ -typedef struct file_logger_t file_logger_t; +#include <bus/listeners/listener.h> -#include <bus/bus.h> +typedef struct file_logger_t file_logger_t; /** * Logger to files which implements listener_t. diff --git a/src/charon/bus/listeners/listener.h b/src/charon/bus/listeners/listener.h new file mode 100644 index 000000000..578f08ebe --- /dev/null +++ b/src/charon/bus/listeners/listener.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup listener listener + * @{ @ingroup listeners + */ + +#ifndef LISTENER_H_ +#define LISTENER_H_ + +typedef struct listener_t listener_t; + +#include <bus/bus.h> + +/** + * Listener interface, listens to events if registered to the bus. + */ +struct listener_t { + + /** + * Log a debugging message. + * + * The implementing signal function returns TRUE to stay registered + * to the bus, or FALSE to unregister itself. + * Calling bus_t.log() inside of a registered listener is possible, + * but the bus does not invoke listeners recursively. + * + * @param group kind of the signal (up, down, rekeyed, ...) + * @param level verbosity level of the signal + * @param thread ID of the thread raised this signal + * @param ike_sa IKE_SA associated to the event + * @param format printf() style format string + * @param args vprintf() style va_list argument list + " @return TRUE to stay registered, FALSE to unregister + */ + bool (*log)(listener_t *this, debug_t group, level_t level, int thread, + ike_sa_t *ike_sa, char* format, va_list args); + + /** + * Hook called if a critical alert is risen. + * + * @param ike_sa IKE_SA associated to the alert, if any + * @param alert kind of alert + * @param ... alert specific argument list + " @return TRUE to stay registered, FALSE to unregister + */ + bool (*alert)(listener_t *this, ike_sa_t *ike_sa, + alert_t alert, va_list args); + + /** + * Handle state changes in an IKE_SA. + * + * @param ike_sa IKE_SA which changes its state + * @param state new IKE_SA state this IKE_SA changes to + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*ike_state_change)(listener_t *this, ike_sa_t *ike_sa, + ike_sa_state_t state); + + /** + * Handle state changes in a CHILD_SA. + * + * @param ike_sa IKE_SA containing the affected CHILD_SA + * @param child_sa CHILD_SA which changes its state + * @param state new CHILD_SA state this CHILD_SA changes to + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*child_state_change)(listener_t *this, ike_sa_t *ike_sa, + child_sa_t *child_sa, child_sa_state_t state); + + /** + * Hook called for received/sent messages of an IKE_SA. + * + * @param ike_sa IKE_SA sending/receving a message + * @param message message object + * @param incoming TRUE for incoming messages, FALSE for outgoing + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*message)(listener_t *this, ike_sa_t *ike_sa, message_t *message, + bool incoming); + + /** + * Hook called with IKE_SA key material. + * + * @param ike_sa IKE_SA this keymat belongs to + * @param dh diffie hellman shared secret + * @param nonce_i initiators nonce + * @param nonce_r responders nonce + * @param rekey IKE_SA we are rekeying, if any + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*ike_keys)(listener_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh, + chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey); + + /** + * Hook called with CHILD_SA key material. + * + * @param ike_sa IKE_SA the child sa belongs to + * @param child_sa CHILD_SA this keymat is used for + * @param dh diffie hellman shared secret + * @param nonce_i initiators nonce + * @param nonce_r responders nonce + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*child_keys)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r); + + /** + * Hook called if an IKE_SA gets up or down. + * + * @param ike_sa IKE_SA coming up/going down + * @param up TRUE for an up event, FALSE for a down event + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*ike_updown)(listener_t *this, ike_sa_t *ike_sa, bool up); + + /** + * Hook called when an IKE_SA gets rekeyed. + * + * @param old rekeyed IKE_SA getting obsolete + * @param new new IKE_SA replacing old + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*ike_rekey)(listener_t *this, ike_sa_t *old, ike_sa_t *new); + + /** + * Hook called when a CHILD_SA gets up or down. + * + * @param ike_sa IKE_SA containing the handled CHILD_SA + * @param child_sa CHILD_SA coming up/going down + * @param up TRUE for an up event, FALSE for a down event + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*child_updown)(listener_t *this, ike_sa_t *ike_sa, + child_sa_t *child_sa, bool up); + + /** + * Hook called when an CHILD_SA gets rekeyed. + * + * @param ike_sa IKE_SA containing the rekeyed CHILD_SA + * @param old rekeyed CHILD_SA getting obsolete + * @param new new CHILD_SA replacing old + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*child_rekey)(listener_t *this, ike_sa_t *ike_sa, + child_sa_t *old, child_sa_t *new); + + /** + * Hook called to invoke additional authorization rules. + * + * An authorization hook gets invoked several times: After each + * authentication round, the hook gets invoked with with final = FALSE. + * After authentication is complete and the peer configuration is selected, + * it is invoked again, but with final = TRUE. + * + * @param ike_sa IKE_SA to authorize + * @param auth list of auth_cfg_t, done in peers authentication rounds + * @param final TRUE if this is the final hook invocation + * @param success set to TRUE to complete IKE_SA, FALSE abort + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*authorize)(listener_t *this, ike_sa_t *ike_sa, linked_list_t *auth, + bool final, bool *success); +}; + +#endif /* LISTENER_ @}*/ diff --git a/src/charon/bus/listeners/sys_logger.c b/src/charon/bus/listeners/sys_logger.c index 5bcf28f24..0b579ce92 100644 --- a/src/charon/bus/listeners/sys_logger.c +++ b/src/charon/bus/listeners/sys_logger.c @@ -15,7 +15,6 @@ #include <stdio.h> #include <string.h> -#include <pthread.h> #include "sys_logger.h" diff --git a/src/charon/bus/listeners/sys_logger.h b/src/charon/bus/listeners/sys_logger.h index 6eda096a9..3ed0f02fa 100644 --- a/src/charon/bus/listeners/sys_logger.h +++ b/src/charon/bus/listeners/sys_logger.h @@ -21,11 +21,11 @@ #ifndef SYS_LOGGER_H_ #define SYS_LOGGER_H_ -typedef struct sys_logger_t sys_logger_t; - #include <syslog.h> -#include <bus/bus.h> +#include <bus/listeners/listener.h> + +typedef struct sys_logger_t sys_logger_t; /** * Logger for syslog which implements listener_t. diff --git a/src/charon/config/attributes/attribute_manager.c b/src/charon/config/attributes/attribute_manager.c index 83e431c43..bf45fdb42 100644 --- a/src/charon/config/attributes/attribute_manager.c +++ b/src/charon/config/attributes/attribute_manager.c @@ -260,7 +260,7 @@ attribute_manager_t *attribute_manager_create() this->providers = linked_list_create(); this->handlers = linked_list_create(); - this->lock = rwlock_create(RWLOCK_DEFAULT); + this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); return &this->public; } diff --git a/src/charon/config/backend_manager.c b/src/charon/config/backend_manager.c index 3a3a78466..cfd611858 100644 --- a/src/charon/config/backend_manager.c +++ b/src/charon/config/backend_manager.c @@ -438,7 +438,7 @@ backend_manager_t *backend_manager_create() this->public.destroy = (void (*)(backend_manager_t*))destroy; this->backends = linked_list_create(); - this->lock = rwlock_create(RWLOCK_DEFAULT); + this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); return &this->public; } diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c index 43e41671a..990ee3fd6 100644 --- a/src/charon/config/child_cfg.c +++ b/src/charon/config/child_cfg.c @@ -345,35 +345,6 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca } /** - * Implementation of child_cfg_t.equal_traffic_selectors. - */ -bool equal_traffic_selectors(private_child_cfg_t *this, bool local, - linked_list_t *ts_list, host_t *host) -{ - linked_list_t *this_list; - traffic_selector_t *this_ts, *ts; - bool result; - - this_list = (local) ? this->my_ts : this->other_ts; - - /* currently equality is established for single traffic selectors only */ - if (this_list->get_count(this_list) != 1 || ts_list->get_count(ts_list) != 1) - { - return FALSE; - } - - this_list->get_first(this_list, (void**)&this_ts); - this_ts = this_ts->clone(this_ts); - this_ts->set_address(this_ts, host); - ts_list->get_first(ts_list, (void**)&ts); - - result = ts->equals(ts, this_ts); - - this_ts->destroy(this_ts); - return result; -} - -/** * Implementation of child_cfg_t.get_updown. */ static char* get_updown(private_child_cfg_t *this) @@ -525,7 +496,6 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime, this->public.get_name = (char* (*) (child_cfg_t*))get_name; this->public.add_traffic_selector = (void (*)(child_cfg_t*,bool,traffic_selector_t*))add_traffic_selector; this->public.get_traffic_selectors = (linked_list_t*(*)(child_cfg_t*,bool,linked_list_t*,host_t*))get_traffic_selectors; - this->public.equal_traffic_selectors = (bool (*)(child_cfg_t*,bool,linked_list_t*,host_t*))equal_traffic_selectors; this->public.add_proposal = (void (*) (child_cfg_t*,proposal_t*))add_proposal; this->public.get_proposals = (linked_list_t* (*) (child_cfg_t*,bool))get_proposals; this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*,bool))select_proposal; diff --git a/src/charon/config/child_cfg.h b/src/charon/config/child_cfg.h index 185fee3da..33c75701c 100644 --- a/src/charon/config/child_cfg.h +++ b/src/charon/config/child_cfg.h @@ -150,18 +150,6 @@ struct child_cfg_t { linked_list_t *(*get_traffic_selectors)(child_cfg_t *this, bool local, linked_list_t *supplied, host_t *host); - - /** - * Checks [single] traffic selectors for equality - * - * @param local TRUE for TS on local side, FALSE for remote - * @param ts list with single traffic selector to compare with - * @param host address to use for narrowing "dynamic" TS', or NULL - * @return TRUE if TS are equal, FALSE otherwise - */ - bool (*equal_traffic_selectors)(child_cfg_t *this, bool local, - linked_list_t *ts_list, host_t *host); - /** * Get the updown script to run for the CHILD_SA. * diff --git a/src/charon/config/peer_cfg.c b/src/charon/config/peer_cfg.c index da796d6a2..f096f269e 100644 --- a/src/charon/config/peer_cfg.c +++ b/src/charon/config/peer_cfg.c @@ -250,22 +250,46 @@ static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this) } /** - * Check if child_cfg contains traffic selectors + * Check how good a list of TS matches a given child config */ -static int contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts, - host_t *host) +static int get_ts_match(child_cfg_t *cfg, bool local, + linked_list_t *sup_list, host_t *host) { - linked_list_t *selected; - int prio; + linked_list_t *cfg_list; + enumerator_t *sup_enum, *cfg_enum; + traffic_selector_t *sup_ts, *cfg_ts; + int match = 0, round; - if (child->equal_traffic_selectors(child, mine, ts, host)) + /* fetch configured TS list, narrowing dynamic TS */ + cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, host); + + /* use a round counter to rate leading TS with higher priority */ + round = sup_list->get_count(sup_list); + + sup_enum = sup_list->create_enumerator(sup_list); + while (sup_enum->enumerate(sup_enum, &sup_ts)) { - return 2; + cfg_enum = cfg_list->create_enumerator(cfg_list); + while (cfg_enum->enumerate(cfg_enum, &cfg_ts)) + { + if (cfg_ts->equals(cfg_ts, sup_ts)) + { /* equality is honored better than matches */ + match += round * 5; + } + else if (cfg_ts->is_contained_in(cfg_ts, sup_ts) || + sup_ts->is_contained_in(sup_ts, cfg_ts)) + { + match += round * 1; + } + } + cfg_enum->destroy(cfg_enum); + round--; } - selected = child->get_traffic_selectors(child, mine, ts, host); - prio = selected->get_count(selected) ? 1 : 0; - selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy)); - return prio; + sup_enum->destroy(sup_enum); + + cfg_list->destroy_offset(cfg_list, offsetof(traffic_selector_t, destroy)); + + return match; } /** @@ -279,21 +303,23 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this, child_cfg_t *current, *found = NULL; enumerator_t *enumerator; int best = 0; - - DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts); + + DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts); enumerator = create_child_cfg_enumerator(this); while (enumerator->enumerate(enumerator, ¤t)) { - int prio = contains_ts(current, TRUE, my_ts, my_host) + - contains_ts(current, FALSE, other_ts, other_host); - - if (prio) + int my_prio, other_prio; + + my_prio = get_ts_match(current, TRUE, my_ts, my_host); + other_prio = get_ts_match(current, FALSE, other_ts, other_host); + + if (my_prio && other_prio) { - DBG2(DBG_CFG, " candidate \"%s\" with prio %d", - current->get_name(current), prio); - if (prio > best) + DBG2(DBG_CFG, " candidate \"%s\" with prio %d+%d", + current->get_name(current), my_prio, other_prio); + if (my_prio + other_prio > best) { - best = prio; + best = my_prio + other_prio; DESTROY_IF(found); found = current->get_ref(current); } @@ -637,7 +663,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg, this->ike_version = ike_version; this->ike_cfg = ike_cfg; this->child_cfgs = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); this->cert_policy = cert_policy; this->unique = unique; this->keyingtries = keyingtries; diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c index e2dfcca4f..cf7e19605 100644 --- a/src/charon/config/proposal.c +++ b/src/charon/config/proposal.c @@ -266,6 +266,9 @@ static bool is_authenticated_encryption(u_int16_t alg) case ENCR_AES_GCM_ICV8: case ENCR_AES_GCM_ICV12: case ENCR_AES_GCM_ICV16: + case ENCR_CAMELLIA_CCM_ICV8: + case ENCR_CAMELLIA_CCM_ICV12: + case ENCR_CAMELLIA_CCM_ICV16: return TRUE; } return FALSE; diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c index 776dbe599..0967cbc81 100644 --- a/src/charon/credentials/credential_manager.c +++ b/src/charon/credentials/credential_manager.c @@ -1591,7 +1591,7 @@ credential_manager_t *credential_manager_create() this->cache = cert_cache_create(); this->cache_queue = linked_list_create(); this->sets->insert_first(this->sets, this->cache); - this->lock = rwlock_create(RWLOCK_DEFAULT); + this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); return &this->public; } diff --git a/src/charon/credentials/sets/cert_cache.c b/src/charon/credentials/sets/cert_cache.c index 907f5072f..dee0463e6 100644 --- a/src/charon/credentials/sets/cert_cache.c +++ b/src/charon/credentials/sets/cert_cache.c @@ -383,7 +383,7 @@ cert_cache_t *cert_cache_create() this->relations[i].subject = NULL; this->relations[i].issuer = NULL; this->relations[i].hits = 0; - this->relations[i].lock = rwlock_create(RWLOCK_DEFAULT); + this->relations[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT); } return &this->public; } diff --git a/src/charon/daemon.c b/src/charon/daemon.c index c646ef9b4..0689c448e 100644 --- a/src/charon/daemon.c +++ b/src/charon/daemon.c @@ -20,7 +20,9 @@ #ifdef HAVE_PRCTL #include <sys/prctl.h> #endif +#define _POSIX_PTHREAD_SEMANTICS /* for two param sigwait on OpenSolaris */ #include <signal.h> +#undef _POSIX_PTHREAD_SEMANTICS #include <pthread.h> #include <sys/stat.h> #include <sys/types.h> @@ -42,10 +44,9 @@ #include <config/traffic_selector.h> #include <config/proposal.h> -#ifdef INTEGRITY_TEST -#include <fips/fips.h> -#include <fips/fips_signature.h> -#endif /* INTEGRITY_TEST */ +#ifndef LOG_AUTHPRIV /* not defined on OpenSolaris */ +#define LOG_AUTHPRIV LOG_AUTH +#endif typedef struct private_daemon_t private_daemon_t; @@ -469,6 +470,13 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[]) DBG1(DBG_DMN, "Starting IKEv2 charon daemon (strongSwan "VERSION")"); + if (lib->integrity) + { + DBG1(DBG_DMN, "integrity tests enabled:"); + DBG1(DBG_DMN, "lib 'libstrongswan': passed file and segment integrity tests"); + DBG1(DBG_DMN, "daemon 'charon': passed file integrity test"); + } + /* load secrets, ca certificates and crls */ this->public.processor = processor_create(); this->public.scheduler = scheduler_create(); @@ -487,19 +495,6 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[]) lib->settings->get_str(lib->settings, "charon.load", PLUGINS)); print_plugins(); - -#ifdef INTEGRITY_TEST - DBG1(DBG_DMN, "integrity test of libstrongswan code"); - if (fips_verify_hmac_signature(hmac_key, hmac_signature)) - { - DBG1(DBG_DMN, " integrity test passed"); - } - else - { - DBG1(DBG_DMN, " integrity test failed"); - return FALSE; - } -#endif /* INTEGRITY_TEST */ this->public.ike_sa_manager = ike_sa_manager_create(); if (this->public.ike_sa_manager == NULL) @@ -686,7 +681,20 @@ int main(int argc, char *argv[]) dbg = dbg_stderr; /* initialize library */ - library_init(STRONGSWAN_CONF); + if (!library_init(STRONGSWAN_CONF)) + { + library_deinit(); + exit(SS_RC_LIBSTRONGSWAN_INTEGRITY); + } + + if (lib->integrity && + !lib->integrity->check_file(lib->integrity, "charon", argv[0])) + { + dbg_stderr(1, "integrity check of charon failed"); + library_deinit(); + exit(SS_RC_DAEMON_INTEGRITY); + } + lib->printf_hook->add_handler(lib->printf_hook, 'R', traffic_selector_printf_hook, PRINTF_HOOK_ARGTYPE_POINTER, @@ -757,7 +765,7 @@ int main(int argc, char *argv[]) { DBG1(DBG_DMN, "initialization failed - aborting charon"); destroy(private_charon); - exit(-1); + exit(SS_RC_INITIALIZATION_FAILED); } if (check_pidfile()) diff --git a/src/charon/kernel/kernel_interface.c b/src/charon/kernel/kernel_interface.c index 5188b79fe..53ae1d200 100644 --- a/src/charon/kernel/kernel_interface.c +++ b/src/charon/kernel/kernel_interface.c @@ -104,6 +104,19 @@ static status_t update_sa(private_kernel_interface_t *this, u_int32_t spi, } /** + * Implementation of kernel_interface_t.query_sa + */ +static status_t query_sa(private_kernel_interface_t *this, host_t *src, host_t *dst, + u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, bytes); +} + +/** * Implementation of kernel_interface_t.del_sa */ static status_t del_sa(private_kernel_interface_t *this, host_t *src, host_t *dst, @@ -387,6 +400,7 @@ kernel_interface_t *kernel_interface_create() this->public.get_cpi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi; this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa; this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa; + this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa; this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa; this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy; this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy; diff --git a/src/charon/kernel/kernel_interface.h b/src/charon/kernel/kernel_interface.h index 8c58c959a..c4a273a34 100644 --- a/src/charon/kernel/kernel_interface.h +++ b/src/charon/kernel/kernel_interface.h @@ -141,6 +141,19 @@ struct kernel_interface_t { bool encap, bool new_encap); /** + * Query the number of bytes processed by an SA from the SAD. + * + * @param src source address for this SA + * @param dst destination address for this SA + * @param spi SPI allocated by us or remote peer + * @param protocol protocol for this SA (ESP/AH) + * @param[out] bytes the number of bytes processed by SA + * @return SUCCESS if operation completed + */ + status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst, + u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes); + + /** * Delete a previously installed SA from the SAD. * * @param src source address for this SA diff --git a/src/charon/kernel/kernel_ipsec.h b/src/charon/kernel/kernel_ipsec.h index 6e8c5bc63..d6438c197 100644 --- a/src/charon/kernel/kernel_ipsec.h +++ b/src/charon/kernel/kernel_ipsec.h @@ -171,6 +171,19 @@ struct kernel_ipsec_t { bool encap, bool new_encap); /** + * Query the number of bytes processed by an SA from the SAD. + * + * @param src source address for this SA + * @param dst destination address for this SA + * @param spi SPI allocated by us or remote peer + * @param protocol protocol for this SA (ESP/AH) + * @param[out] bytes the number of bytes processed by SA + * @return SUCCESS if operation completed + */ + status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes); + + /** * Delete a previusly installed SA from the SAD. * * @param src source address for this SA diff --git a/src/charon/network/sender.c b/src/charon/network/sender.c index 4910fe2e8..19f589115 100644 --- a/src/charon/network/sender.c +++ b/src/charon/network/sender.c @@ -139,9 +139,9 @@ sender_t * sender_create() this->public.destroy = (void(*)(sender_t*)) destroy; this->list = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); - this->got = condvar_create(CONDVAR_DEFAULT); - this->sent = condvar_create(CONDVAR_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->got = condvar_create(CONDVAR_TYPE_DEFAULT); + this->sent = condvar_create(CONDVAR_TYPE_DEFAULT); this->job = callback_job_create((callback_job_cb_t)send_packets, this, NULL, NULL); diff --git a/src/charon/network/socket.c b/src/charon/network/socket.c index 8627ca76d..97c88be79 100644 --- a/src/charon/network/socket.c +++ b/src/charon/network/socket.c @@ -18,6 +18,10 @@ /* for struct in6_pktinfo */ #define _GNU_SOURCE +#ifdef __sun +#define _XPG4_2 +#define __EXTENSIONS__ +#endif #include <pthread.h> #include <sys/types.h> @@ -34,6 +38,9 @@ #include <netinet/ip6.h> #include <netinet/udp.h> #include <net/if.h> +#ifdef __APPLE__ +#include <sys/sysctl.h> +#endif #include "socket.h" @@ -431,7 +438,6 @@ status_t sender(private_socket_t *this, packet_t *packet) static int open_socket(private_socket_t *this, int family, u_int16_t port) { int on = TRUE; - int type = UDP_ENCAP_ESPINUDP; struct sockaddr_storage addr; socklen_t addrlen; u_int sol, pktinfo = 0; @@ -502,13 +508,18 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port) return 0; } } - - /* enable UDP decapsulation globally, only for one socket needed */ - if (family == AF_INET && port == IKEV2_NATT_PORT && - setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) + +#ifndef __APPLE__ { - DBG1(DBG_NET, "unable to set UDP_ENCAP: %s", strerror(errno)); + /* enable UDP decapsulation globally, only for one socket needed */ + int type = UDP_ENCAP_ESPINUDP; + if (family == AF_INET && port == IKEV2_NATT_PORT && + setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) + { + DBG1(DBG_NET, "unable to set UDP_ENCAP: %s", strerror(errno)); + } } +#endif return skt; } @@ -611,6 +622,18 @@ socket_t *socket_create() this->ipv6 = 0; this->ipv4_natt = 0; this->ipv6_natt = 0; + +#ifdef __APPLE__ + { + int natt_port = IKEV2_NATT_PORT; + if (sysctlbyname("net.inet.ipsec.esp_port", NULL, NULL, &natt_port, + sizeof(natt_port)) != 0) + { + DBG1(DBG_NET, "could not set net.inet.ipsec.esp_port to %d: %s", + natt_port, strerror(errno)); + } + } +#endif this->ipv4 = open_socket(this, AF_INET, IKEV2_UDP_PORT); if (this->ipv4 == 0) diff --git a/src/charon/plugins/attr/Makefile.am b/src/charon/plugins/attr/Makefile.am index d5eb99d9f..b4b3b7da6 100644 --- a/src/charon/plugins/attr/Makefile.am +++ b/src/charon/plugins/attr/Makefile.am @@ -6,4 +6,4 @@ AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-attr.la libstrongswan_attr_la_SOURCES = attr_plugin.h attr_plugin.c \ attr_provider.h attr_provider.c -libstrongswan_attr_la_LDFLAGS = -module +libstrongswan_attr_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/attr/Makefile.in b/src/charon/plugins/attr/Makefile.in index c0467054e..5c94771e1 100644 --- a/src/charon/plugins/attr/Makefile.in +++ b/src/charon/plugins/attr/Makefile.in @@ -73,12 +73,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -143,6 +145,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -183,7 +186,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -223,7 +228,7 @@ plugin_LTLIBRARIES = libstrongswan-attr.la libstrongswan_attr_la_SOURCES = attr_plugin.h attr_plugin.c \ attr_provider.h attr_provider.c -libstrongswan_attr_la_LDFLAGS = -module +libstrongswan_attr_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/eap_aka/Makefile.am b/src/charon/plugins/eap_aka/Makefile.am index e1ad1eaf9..1a3ea1857 100644 --- a/src/charon/plugins/eap_aka/Makefile.am +++ b/src/charon/plugins/eap_aka/Makefile.am @@ -6,6 +6,6 @@ AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-eapaka.la libstrongswan_eapaka_la_SOURCES = eap_aka_plugin.h eap_aka_plugin.c eap_aka.h eap_aka.c -libstrongswan_eapaka_la_LDFLAGS = -module +libstrongswan_eapaka_la_LDFLAGS = -module -avoid-version libstrongswan_eapaka_la_LIBADD = -lgmp diff --git a/src/charon/plugins/eap_aka/Makefile.in b/src/charon/plugins/eap_aka/Makefile.in index 74d49ac73..2d2405379 100644 --- a/src/charon/plugins/eap_aka/Makefile.in +++ b/src/charon/plugins/eap_aka/Makefile.in @@ -74,12 +74,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -144,6 +146,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -184,7 +187,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -222,7 +227,7 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-eapaka.la libstrongswan_eapaka_la_SOURCES = eap_aka_plugin.h eap_aka_plugin.c eap_aka.h eap_aka.c -libstrongswan_eapaka_la_LDFLAGS = -module +libstrongswan_eapaka_la_LDFLAGS = -module -avoid-version libstrongswan_eapaka_la_LIBADD = -lgmp all: all-am diff --git a/src/charon/plugins/eap_gtc/Makefile.am b/src/charon/plugins/eap_gtc/Makefile.am index 1057bd506..547a8dfc5 100644 --- a/src/charon/plugins/eap_gtc/Makefile.am +++ b/src/charon/plugins/eap_gtc/Makefile.am @@ -6,5 +6,5 @@ AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-eapgtc.la libstrongswan_eapgtc_la_SOURCES = eap_gtc_plugin.h eap_gtc_plugin.c eap_gtc.h eap_gtc.c -libstrongswan_eapgtc_la_LDFLAGS = -module -lpam +libstrongswan_eapgtc_la_LDFLAGS = -module -avoid-version -lpam diff --git a/src/charon/plugins/eap_gtc/Makefile.in b/src/charon/plugins/eap_gtc/Makefile.in index 19d648bbd..46d438a97 100644 --- a/src/charon/plugins/eap_gtc/Makefile.in +++ b/src/charon/plugins/eap_gtc/Makefile.in @@ -74,12 +74,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -144,6 +146,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -184,7 +187,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -222,7 +227,7 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-eapgtc.la libstrongswan_eapgtc_la_SOURCES = eap_gtc_plugin.h eap_gtc_plugin.c eap_gtc.h eap_gtc.c -libstrongswan_eapgtc_la_LDFLAGS = -module -lpam +libstrongswan_eapgtc_la_LDFLAGS = -module -avoid-version -lpam all: all-am .SUFFIXES: diff --git a/src/charon/plugins/eap_identity/Makefile.am b/src/charon/plugins/eap_identity/Makefile.am index dbf66e74b..79ddee3e8 100644 --- a/src/charon/plugins/eap_identity/Makefile.am +++ b/src/charon/plugins/eap_identity/Makefile.am @@ -6,5 +6,5 @@ AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-eapidentity.la libstrongswan_eapidentity_la_SOURCES = \ eap_identity_plugin.h eap_identity_plugin.c eap_identity.h eap_identity.c -libstrongswan_eapidentity_la_LDFLAGS = -module +libstrongswan_eapidentity_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/eap_identity/Makefile.in b/src/charon/plugins/eap_identity/Makefile.in index f275cd770..0adb9ce10 100644 --- a/src/charon/plugins/eap_identity/Makefile.in +++ b/src/charon/plugins/eap_identity/Makefile.in @@ -76,12 +76,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -146,6 +148,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -186,7 +189,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -226,7 +231,7 @@ plugin_LTLIBRARIES = libstrongswan-eapidentity.la libstrongswan_eapidentity_la_SOURCES = \ eap_identity_plugin.h eap_identity_plugin.c eap_identity.h eap_identity.c -libstrongswan_eapidentity_la_LDFLAGS = -module +libstrongswan_eapidentity_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/eap_md5/Makefile.am b/src/charon/plugins/eap_md5/Makefile.am index d7964fee9..8bad64368 100644 --- a/src/charon/plugins/eap_md5/Makefile.am +++ b/src/charon/plugins/eap_md5/Makefile.am @@ -6,5 +6,5 @@ AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-eapmd5.la libstrongswan_eapmd5_la_SOURCES = eap_md5_plugin.h eap_md5_plugin.c eap_md5.h eap_md5.c -libstrongswan_eapmd5_la_LDFLAGS = -module +libstrongswan_eapmd5_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/eap_md5/Makefile.in b/src/charon/plugins/eap_md5/Makefile.in index 372b80b3e..c11837b91 100644 --- a/src/charon/plugins/eap_md5/Makefile.in +++ b/src/charon/plugins/eap_md5/Makefile.in @@ -74,12 +74,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -144,6 +146,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -184,7 +187,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -222,7 +227,7 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-eapmd5.la libstrongswan_eapmd5_la_SOURCES = eap_md5_plugin.h eap_md5_plugin.c eap_md5.h eap_md5.c -libstrongswan_eapmd5_la_LDFLAGS = -module +libstrongswan_eapmd5_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/eap_mschapv2/Makefile.am b/src/charon/plugins/eap_mschapv2/Makefile.am index 6ab931905..179da70fc 100644 --- a/src/charon/plugins/eap_mschapv2/Makefile.am +++ b/src/charon/plugins/eap_mschapv2/Makefile.am @@ -8,5 +8,5 @@ plugin_LTLIBRARIES = libstrongswan-eapmschapv2.la libstrongswan_eapmschapv2_la_SOURCES = \ eap_mschapv2_plugin.h eap_mschapv2_plugin.c \ eap_mschapv2.h eap_mschapv2.c -libstrongswan_eapmschapv2_la_LDFLAGS = -module +libstrongswan_eapmschapv2_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/eap_mschapv2/Makefile.in b/src/charon/plugins/eap_mschapv2/Makefile.in index 5ae41d896..d6dd74b88 100644 --- a/src/charon/plugins/eap_mschapv2/Makefile.in +++ b/src/charon/plugins/eap_mschapv2/Makefile.in @@ -76,12 +76,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -146,6 +148,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -186,7 +189,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -227,7 +232,7 @@ libstrongswan_eapmschapv2_la_SOURCES = \ eap_mschapv2_plugin.h eap_mschapv2_plugin.c \ eap_mschapv2.h eap_mschapv2.c -libstrongswan_eapmschapv2_la_LDFLAGS = -module +libstrongswan_eapmschapv2_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/eap_radius/Makefile.am b/src/charon/plugins/eap_radius/Makefile.am index f7de2f14f..df5c94656 100644 --- a/src/charon/plugins/eap_radius/Makefile.am +++ b/src/charon/plugins/eap_radius/Makefile.am @@ -10,5 +10,5 @@ libstrongswan_eapradius_la_SOURCES = \ eap_radius.h eap_radius.c \ radius_client.h radius_client.c \ radius_message.h radius_message.c -libstrongswan_eapradius_la_LDFLAGS = -module +libstrongswan_eapradius_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/eap_radius/Makefile.in b/src/charon/plugins/eap_radius/Makefile.in index e7a4cd0f8..c30111fad 100644 --- a/src/charon/plugins/eap_radius/Makefile.in +++ b/src/charon/plugins/eap_radius/Makefile.in @@ -76,12 +76,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -146,6 +148,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -186,7 +189,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -229,7 +234,7 @@ libstrongswan_eapradius_la_SOURCES = \ radius_client.h radius_client.c \ radius_message.h radius_message.c -libstrongswan_eapradius_la_LDFLAGS = -module +libstrongswan_eapradius_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/eap_radius/eap_radius.c b/src/charon/plugins/eap_radius/eap_radius.c index ee2477440..deb3b648b 100644 --- a/src/charon/plugins/eap_radius/eap_radius.c +++ b/src/charon/plugins/eap_radius/eap_radius.c @@ -66,6 +66,11 @@ struct private_eap_radius_t { * TRUE to use EAP-Start, FALSE to send EAP-Identity Response directly */ bool eap_start; + + /** + * Prefix to prepend to EAP identity + */ + char *id_prefix; }; /** @@ -86,18 +91,20 @@ static void add_eap_identity(private_eap_radius_t *this, /** identity data */ u_int8_t data[]; } __attribute__((__packed__)) *hdr; - chunk_t id; + chunk_t id, prefix; size_t len; id = this->peer->get_encoding(this->peer); - len = sizeof(*hdr) + id.len; + prefix = chunk_create(this->id_prefix, strlen(this->id_prefix)); + len = sizeof(*hdr) + prefix.len + id.len; hdr = alloca(len); hdr->code = EAP_RESPONSE; hdr->identifier = 0; hdr->length = htons(len); hdr->type = EAP_IDENTITY; - memcpy(hdr->data, id.ptr, id.len); + memcpy(hdr->data, prefix.ptr, prefix.len); + memcpy(hdr->data + prefix.len, id.ptr, id.len); request->add(request, RAT_EAP_MESSAGE, chunk_create((u_char*)hdr, len)); } @@ -136,9 +143,12 @@ static status_t initiate(private_eap_radius_t *this, eap_payload_t **out) { radius_message_t *request, *response; status_t status = FAILED; + chunk_t username; request = radius_message_create_request(); - request->add(request, RAT_USER_NAME, this->peer->get_encoding(this->peer)); + username = chunk_create(this->id_prefix, strlen(this->id_prefix)); + username = chunk_cata("cc", username, this->peer->get_encoding(this->peer)); + request->add(request, RAT_USER_NAME, username); if (this->eap_start) { @@ -283,7 +293,8 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer this->msk = chunk_empty; this->eap_start = lib->settings->get_bool(lib->settings, "charon.plugins.eap_radius.eap_start", FALSE); - + this->id_prefix = lib->settings->get_str(lib->settings, + "charon.plugins.eap_radius.id_prefix", ""); return &this->public; } diff --git a/src/charon/plugins/eap_radius/radius_client.c b/src/charon/plugins/eap_radius/radius_client.c index 57d3f8f21..de1bafc6d 100644 --- a/src/charon/plugins/eap_radius/radius_client.c +++ b/src/charon/plugins/eap_radius/radius_client.c @@ -161,8 +161,8 @@ bool radius_client_init() "charon.plugins.eap_radius.sockets", 1); sockets = linked_list_create(); - mutex = mutex_create(MUTEX_DEFAULT); - condvar = condvar_create(CONDVAR_DEFAULT); + mutex = mutex_create(MUTEX_TYPE_DEFAULT); + condvar = condvar_create(CONDVAR_TYPE_DEFAULT); for (i = 0; i < count; i++) { fd = socket(host->get_family(host), SOCK_DGRAM, IPPROTO_UDP); @@ -353,6 +353,7 @@ static radius_message_t* request(private_radius_client_t *this, } DBG1(DBG_CFG, "RADIUS server is not responding"); put_socket(socket); + charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING); return NULL; } diff --git a/src/charon/plugins/eap_sim/Makefile.am b/src/charon/plugins/eap_sim/Makefile.am index 6cb53ebb5..e503bddab 100644 --- a/src/charon/plugins/eap_sim/Makefile.am +++ b/src/charon/plugins/eap_sim/Makefile.am @@ -7,5 +7,5 @@ plugin_LTLIBRARIES = libstrongswan-eapsim.la libstrongswan_eapsim_la_SOURCES = eap_sim.h eap_sim.c \ eap_sim_plugin.h eap_sim_plugin.c -libstrongswan_eapsim_la_LDFLAGS = -module +libstrongswan_eapsim_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/eap_sim/Makefile.in b/src/charon/plugins/eap_sim/Makefile.in index 2374567bc..8f6daacad 100644 --- a/src/charon/plugins/eap_sim/Makefile.in +++ b/src/charon/plugins/eap_sim/Makefile.in @@ -74,12 +74,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -144,6 +146,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -184,7 +187,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -224,7 +229,7 @@ plugin_LTLIBRARIES = libstrongswan-eapsim.la libstrongswan_eapsim_la_SOURCES = eap_sim.h eap_sim.c \ eap_sim_plugin.h eap_sim_plugin.c -libstrongswan_eapsim_la_LDFLAGS = -module +libstrongswan_eapsim_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/eap_sim_file/Makefile.am b/src/charon/plugins/eap_sim_file/Makefile.am index fc3a0fa14..1cd1dd9e2 100644 --- a/src/charon/plugins/eap_sim_file/Makefile.am +++ b/src/charon/plugins/eap_sim_file/Makefile.am @@ -10,5 +10,5 @@ libstrongswan_eapsim_file_la_SOURCES = \ eap_sim_file_card.h eap_sim_file_card.c \ eap_sim_file_provider.h eap_sim_file_provider.c \ eap_sim_file_triplets.h eap_sim_file_triplets.c -libstrongswan_eapsim_file_la_LDFLAGS = -module +libstrongswan_eapsim_file_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/eap_sim_file/Makefile.in b/src/charon/plugins/eap_sim_file/Makefile.in index 554b3a7bc..b19cc839f 100644 --- a/src/charon/plugins/eap_sim_file/Makefile.in +++ b/src/charon/plugins/eap_sim_file/Makefile.in @@ -77,12 +77,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -147,6 +149,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -187,7 +190,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -230,7 +235,7 @@ libstrongswan_eapsim_file_la_SOURCES = \ eap_sim_file_provider.h eap_sim_file_provider.c \ eap_sim_file_triplets.h eap_sim_file_triplets.c -libstrongswan_eapsim_file_la_LDFLAGS = -module +libstrongswan_eapsim_file_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c b/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c index d093851c2..e27ed6860 100644 --- a/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c +++ b/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c @@ -251,7 +251,7 @@ eap_sim_file_triplets_t *eap_sim_file_triplets_create(char *file) this->public.destroy = (void(*)(eap_sim_file_triplets_t*))destroy; this->triplets = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); read_triplets(this, file); diff --git a/src/charon/plugins/kernel_klips/Makefile.am b/src/charon/plugins/kernel_klips/Makefile.am index dc0234775..0c0987cca 100644 --- a/src/charon/plugins/kernel_klips/Makefile.am +++ b/src/charon/plugins/kernel_klips/Makefile.am @@ -7,4 +7,4 @@ plugin_LTLIBRARIES = libstrongswan-kernel-klips.la libstrongswan_kernel_klips_la_SOURCES = kernel_klips_plugin.h kernel_klips_plugin.c \ kernel_klips_ipsec.h kernel_klips_ipsec.c pfkeyv2.h -libstrongswan_kernel_klips_la_LDFLAGS = -module +libstrongswan_kernel_klips_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/kernel_klips/Makefile.in b/src/charon/plugins/kernel_klips/Makefile.in index a1efe9d5a..4b1c27352 100644 --- a/src/charon/plugins/kernel_klips/Makefile.in +++ b/src/charon/plugins/kernel_klips/Makefile.in @@ -76,12 +76,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -146,6 +148,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -186,7 +189,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -226,7 +231,7 @@ plugin_LTLIBRARIES = libstrongswan-kernel-klips.la libstrongswan_kernel_klips_la_SOURCES = kernel_klips_plugin.h kernel_klips_plugin.c \ kernel_klips_ipsec.h kernel_klips_ipsec.c pfkeyv2.h -libstrongswan_kernel_klips_la_LDFLAGS = -module +libstrongswan_kernel_klips_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c b/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c index c69ce4c9a..9a903d027 100644 --- a/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c +++ b/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c @@ -1934,6 +1934,16 @@ static status_t update_sa(private_kernel_klips_ipsec_t *this, } /** + * Implementation of kernel_interface_t.query_sa. + */ +static status_t query_sa(private_kernel_klips_ipsec_t *this, host_t *src, + host_t *dst, u_int32_t spi, protocol_id_t protocol, + u_int64_t *bytes) +{ + return NOT_SUPPORTED; /* TODO */ +} + +/** * Implementation of kernel_interface_t.del_sa. */ static status_t del_sa(private_kernel_klips_ipsec_t *this, host_t *src, @@ -2609,6 +2619,7 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create() this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi; this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa; this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa; + this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa; this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa; this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy; this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy; @@ -2621,8 +2632,8 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create() this->allocated_spis = linked_list_create(); this->installed_sas = linked_list_create(); this->ipsec_devices = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); - this->mutex_pfkey = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT); this->install_routes = lib->settings->get_bool(lib->settings, "charon.install_routes", TRUE); this->seq = 0; diff --git a/src/charon/plugins/kernel_netlink/Makefile.am b/src/charon/plugins/kernel_netlink/Makefile.am index e0efe5779..6351280d6 100644 --- a/src/charon/plugins/kernel_netlink/Makefile.am +++ b/src/charon/plugins/kernel_netlink/Makefile.am @@ -8,4 +8,4 @@ plugin_LTLIBRARIES = libstrongswan-kernel-netlink.la libstrongswan_kernel_netlink_la_SOURCES = kernel_netlink_plugin.h kernel_netlink_plugin.c \ kernel_netlink_ipsec.h kernel_netlink_ipsec.c kernel_netlink_net.h kernel_netlink_net.c \ kernel_netlink_shared.h kernel_netlink_shared.c -libstrongswan_kernel_netlink_la_LDFLAGS = -module +libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/kernel_netlink/Makefile.in b/src/charon/plugins/kernel_netlink/Makefile.in index b97738bff..46d2a1c65 100644 --- a/src/charon/plugins/kernel_netlink/Makefile.in +++ b/src/charon/plugins/kernel_netlink/Makefile.in @@ -77,12 +77,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -147,6 +149,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -187,7 +190,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -228,7 +233,7 @@ libstrongswan_kernel_netlink_la_SOURCES = kernel_netlink_plugin.h kernel_netlink kernel_netlink_ipsec.h kernel_netlink_ipsec.c kernel_netlink_net.h kernel_netlink_net.c \ kernel_netlink_shared.h kernel_netlink_shared.c -libstrongswan_kernel_netlink_la_LDFLAGS = -module +libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c index 9322d8dfe..2051316f6 100644 --- a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -984,16 +984,20 @@ static status_t add_sa(private_kernel_netlink_ipsec_t *this, break; case ENCR_AES_CCM_ICV16: case ENCR_AES_GCM_ICV16: + case ENCR_CAMELLIA_CCM_ICV16: icv_size += 32; /* FALL */ case ENCR_AES_CCM_ICV12: case ENCR_AES_GCM_ICV12: + case ENCR_CAMELLIA_CCM_ICV12: icv_size += 32; /* FALL */ case ENCR_AES_CCM_ICV8: case ENCR_AES_GCM_ICV8: + case ENCR_CAMELLIA_CCM_ICV8: { - rthdr->rta_type = XFRMA_ALG_AEAD; + struct xfrm_algo_aead *algo; + alg_name = lookup_algorithm(encryption_algs, enc_alg); if (alg_name == NULL) { @@ -1004,6 +1008,7 @@ static status_t add_sa(private_kernel_netlink_ipsec_t *this, DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", encryption_algorithm_names, enc_alg, enc_key.len * 8); + rthdr->rta_type = XFRMA_ALG_AEAD; rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_aead) + enc_key.len); hdr->nlmsg_len += rthdr->rta_len; if (hdr->nlmsg_len > sizeof(request)) @@ -1011,7 +1016,7 @@ static status_t add_sa(private_kernel_netlink_ipsec_t *this, return FAILED; } - struct xfrm_algo_aead* algo = (struct xfrm_algo_aead*)RTA_DATA(rthdr); + algo = (struct xfrm_algo_aead*)RTA_DATA(rthdr); algo->alg_key_len = enc_key.len * 8; algo->alg_icv_len = icv_size; strcpy(algo->alg_name, alg_name); @@ -1022,7 +1027,8 @@ static status_t add_sa(private_kernel_netlink_ipsec_t *this, } default: { - rthdr->rta_type = XFRMA_ALG_CRYPT; + struct xfrm_algo *algo; + alg_name = lookup_algorithm(encryption_algs, enc_alg); if (alg_name == NULL) { @@ -1033,6 +1039,7 @@ static status_t add_sa(private_kernel_netlink_ipsec_t *this, DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", encryption_algorithm_names, enc_alg, enc_key.len * 8); + rthdr->rta_type = XFRMA_ALG_CRYPT; rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + enc_key.len); hdr->nlmsg_len += rthdr->rta_len; if (hdr->nlmsg_len > sizeof(request)) @@ -1040,13 +1047,12 @@ static status_t add_sa(private_kernel_netlink_ipsec_t *this, return FAILED; } - struct xfrm_algo* algo = (struct xfrm_algo*)RTA_DATA(rthdr); + algo = (struct xfrm_algo*)RTA_DATA(rthdr); algo->alg_key_len = enc_key.len * 8; strcpy(algo->alg_name, alg_name); memcpy(algo->alg_key, enc_key.ptr, enc_key.len); rthdr = XFRM_RTA_NEXT(rthdr); - break; } } @@ -1230,6 +1236,74 @@ static status_t get_replay_state(private_kernel_netlink_ipsec_t *this, } /** + * Implementation of kernel_interface_t.query_sa. + */ +static status_t query_sa(private_kernel_netlink_ipsec_t *this, host_t *src, + host_t *dst, u_int32_t spi, protocol_id_t protocol, + u_int64_t *bytes) +{ + netlink_buf_t request; + struct nlmsghdr *out = NULL, *hdr; + struct xfrm_usersa_id *sa_id; + struct xfrm_usersa_info *sa = NULL; + size_t len; + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); + + hdr = (struct nlmsghdr*)request; + hdr->nlmsg_flags = NLM_F_REQUEST; + hdr->nlmsg_type = XFRM_MSG_GETSA; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); + + sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr); + host2xfrm(dst, &sa_id->daddr); + sa_id->spi = spi; + sa_id->proto = proto_ike2kernel(protocol); + sa_id->family = dst->get_family(dst); + + if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) + { + hdr = out; + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case XFRM_MSG_NEWSA: + { + sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr); + break; + } + case NLMSG_ERROR: + { + struct nlmsgerr *err = NLMSG_DATA(hdr); + DBG1(DBG_KNL, "querying SAD entry with SPI %.8x failed: %s (%d)", + ntohl(spi), strerror(-err->error), -err->error); + break; + } + default: + hdr = NLMSG_NEXT(hdr, len); + continue; + case NLMSG_DONE: + break; + } + break; + } + } + + if (sa == NULL) + { + DBG2(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); + free(out); + return FAILED; + } + *bytes = sa->curlft.bytes; + + free(out); + return SUCCESS; +} +/** * Implementation of kernel_interface_t.del_sa. */ static status_t del_sa(private_kernel_netlink_ipsec_t *this, host_t *src, @@ -1888,6 +1962,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi; this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa; this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa; + this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa; this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa; this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy; this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy; @@ -1897,7 +1972,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() /* private members */ this->policies = hashtable_create((hashtable_hash_t)policy_hash, (hashtable_equals_t)policy_equals, 32); - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); this->install_routes = lib->settings->get_bool(lib->settings, "charon.install_routes", TRUE); diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_net.c b/src/charon/plugins/kernel_netlink/kernel_netlink_net.c index 32154a7ea..e5c0b5da7 100644 --- a/src/charon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/charon/plugins/kernel_netlink/kernel_netlink_net.c @@ -1370,8 +1370,8 @@ kernel_netlink_net_t *kernel_netlink_net_create() /* private members */ this->ifaces = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); - this->condvar = condvar_create(CONDVAR_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT); timerclear(&this->last_roam); this->routing_table = lib->settings->get_int(lib->settings, "charon.routing_table", IPSEC_ROUTING_TABLE); diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/charon/plugins/kernel_netlink/kernel_netlink_shared.c index 7ef7cc56e..ec1187083 100644 --- a/src/charon/plugins/kernel_netlink/kernel_netlink_shared.c +++ b/src/charon/plugins/kernel_netlink/kernel_netlink_shared.c @@ -255,7 +255,7 @@ netlink_socket_t *netlink_socket_create(int protocol) { /* private members */ this->seq = 200; - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); memset(&addr, 0, sizeof(addr)); addr.nl_family = AF_NETLINK; diff --git a/src/charon/plugins/kernel_pfkey/Makefile.am b/src/charon/plugins/kernel_pfkey/Makefile.am index c9d66b5de..e03a0ca02 100644 --- a/src/charon/plugins/kernel_pfkey/Makefile.am +++ b/src/charon/plugins/kernel_pfkey/Makefile.am @@ -7,4 +7,4 @@ plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la libstrongswan_kernel_pfkey_la_SOURCES = kernel_pfkey_plugin.h kernel_pfkey_plugin.c \ kernel_pfkey_ipsec.h kernel_pfkey_ipsec.c -libstrongswan_kernel_pfkey_la_LDFLAGS = -module +libstrongswan_kernel_pfkey_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/kernel_pfkey/Makefile.in b/src/charon/plugins/kernel_pfkey/Makefile.in index df2492ef7..e01510127 100644 --- a/src/charon/plugins/kernel_pfkey/Makefile.in +++ b/src/charon/plugins/kernel_pfkey/Makefile.in @@ -76,12 +76,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -146,6 +148,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -186,7 +189,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -226,7 +231,7 @@ plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la libstrongswan_kernel_pfkey_la_SOURCES = kernel_pfkey_plugin.h kernel_pfkey_plugin.c \ kernel_pfkey_ipsec.h kernel_pfkey_ipsec.c -libstrongswan_kernel_pfkey_la_LDFLAGS = -module +libstrongswan_kernel_pfkey_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index 56f0320dc..1f83e8f39 100644 --- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -17,6 +17,10 @@ #include <sys/types.h> #include <sys/socket.h> +#ifdef __FreeBSD__ +#include <limits.h> /* for LONG_MAX */ +#endif + #ifdef HAVE_NET_PFKEYV2_H #include <net/pfkeyv2.h> #else @@ -37,11 +41,11 @@ #endif #ifdef HAVE_NATT -#ifdef HAVE_NETINET_UDP_H -#include <netinet/udp.h> -#else +#ifdef HAVE_LINUX_UDP_H #include <linux/udp.h> -#endif /*HAVE_NETINET_UDP_H*/ +#else +#include <netinet/udp.h> +#endif /*HAVE_LINUX_UDP_H*/ #endif /*HAVE_NATT*/ #include <unistd.h> @@ -89,7 +93,7 @@ #define IP_IPSEC_POLICY 16 #endif -/* missing on uclibc */ +/** missing on uclibc */ #ifndef IPV6_IPSEC_POLICY #define IPV6_IPSEC_POLICY 34 #endif @@ -98,6 +102,17 @@ #define PRIO_LOW 3000 #define PRIO_HIGH 2000 +#ifdef __APPLE__ +/** from xnu/bsd/net/pfkeyv2.h */ +#define SADB_X_EXT_NATT 0x002 + struct sadb_sa_2 { + struct sadb_sa sa; + u_int16_t sadb_sa_natt_port; + u_int16_t sadb_reserved0; + u_int32_t sadb_reserved1; + }; +#endif + /** buffer size for PF_KEY messages */ #define PFKEY_BUFFER_SIZE 4096 @@ -467,7 +482,7 @@ static u_int8_t dir2kernel(policy_dir_t dir) return IPSEC_DIR_FWD; #endif default: - return dir; + return IPSEC_DIR_INVALID; } } @@ -693,7 +708,7 @@ static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out) while (len >= PFKEY_LEN(sizeof(struct sadb_ext))) { - DBG2(DBG_KNL, " %N", sadb_ext_type_names, ext->sadb_ext_type); + DBG3(DBG_KNL, " %N", sadb_ext_type_names, ext->sadb_ext_type); if (ext->sadb_ext_len < PFKEY_LEN(sizeof(struct sadb_ext)) || ext->sadb_ext_len > len) { @@ -740,6 +755,8 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket this->mutex_pfkey->lock(this->mutex_pfkey); + /* FIXME: our usage of sequence numbers is probably wrong. check RFC 2367, + * in particular the behavior in response to an SADB_ACQUIRE. */ in->sadb_msg_seq = ++this->seq; in->sadb_msg_pid = getpid(); @@ -801,14 +818,23 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket } if (msg->sadb_msg_seq != this->seq) { - DBG1(DBG_KNL, "received PF_KEY message with invalid sequence number, " - "was %d expected %d", msg->sadb_msg_seq, this->seq); - if (msg->sadb_msg_seq < this->seq) + DBG1(DBG_KNL, "received PF_KEY message with unexpected sequence " + "number, was %d expected %d", msg->sadb_msg_seq, this->seq); + if (msg->sadb_msg_seq == 0) + { + /* FreeBSD and Mac OS X do this for the response to + * SADB_X_SPDGET (but not for the response to SADB_GET). + * FreeBSD: 'key_spdget' in /usr/src/sys/netipsec/key.c. */ + } + else if (msg->sadb_msg_seq < this->seq) { continue; } - this->mutex_pfkey->unlock(this->mutex_pfkey); - return FAILED; + else + { + this->mutex_pfkey->unlock(this->mutex_pfkey); + return FAILED; + } } if (msg->sadb_msg_type != in->sadb_msg_type) { @@ -1223,10 +1249,25 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this, msg->sadb_msg_type = inbound ? SADB_UPDATE : SADB_ADD; msg->sadb_msg_satype = proto_ike2satype(protocol); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); + +#ifdef __APPLE__ + if (encap) + { + struct sadb_sa_2 *sa_2; + sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg); + sa_2->sadb_sa_natt_port = dst->get_port(dst); + sa = &sa_2->sa; + sa->sadb_sa_flags |= SADB_X_EXT_NATT; + len = sizeof(struct sadb_sa_2); + } + else +#endif + { + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); + len = sizeof(struct sadb_sa); + } sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); + sa->sadb_sa_len = PFKEY_LEN(len); sa->sadb_sa_spi = spi; sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32; sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg); @@ -1403,7 +1444,21 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this, msg->sadb_msg_satype = proto_ike2satype(protocol); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); +#ifdef __APPLE__ + { + struct sadb_sa_2 *sa_2; + sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg); + sa_2->sa.sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa_2)); + memcpy(&sa_2->sa, response.sa, sizeof(struct sadb_sa)); + if (encap) + { + sa_2->sadb_sa_natt_port = new_dst->get_port(new_dst); + sa_2->sa.sadb_sa_flags |= SADB_X_EXT_NATT; + } + } +#else PFKEY_EXT_COPY(msg, response.sa); +#endif PFKEY_EXT_COPY(msg, response.x_sa2); PFKEY_EXT_COPY(msg, response.src); @@ -1421,7 +1476,7 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this, { PFKEY_EXT_COPY(msg, response.key_auth); } - + #ifdef HAVE_NATT if (new_encap) { @@ -1449,6 +1504,65 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this, } /** + * Implementation of kernel_interface_t.query_sa. + */ +static status_t query_sa(private_kernel_pfkey_ipsec_t *this, host_t *src, + host_t *dst, u_int32_t spi, protocol_id_t protocol, + u_int64_t *bytes) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_sa *sa; + pfkey_msg_t response; + size_t len; + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_GET; + msg->sadb_msg_satype = proto_ike2satype(protocol); + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); + sa->sadb_sa_exttype = SADB_EXT_SA; + sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); + sa->sadb_sa_spi = spi; + PFKEY_EXT_ADD(msg, sa); + + /* the Linux Kernel doesn't care for the src address, but other systems do + * (e.g. FreeBSD) + */ + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)", + ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); + free(out); + return FAILED; + } + else if (parse_pfkey_message(out, &response) != SUCCESS) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); + free(out); + return FAILED; + } + *bytes = response.lft_current->sadb_lifetime_bytes; + + free(out); + return SUCCESS; +} + +/** * Implementation of kernel_interface_t.del_sa. */ static status_t del_sa(private_kernel_pfkey_ipsec_t *this, host_t *src, @@ -1476,7 +1590,9 @@ static status_t del_sa(private_kernel_pfkey_ipsec_t *this, host_t *src, sa->sadb_sa_spi = spi; PFKEY_EXT_ADD(msg, sa); - /* the Linux Kernel doesn't care for the src address, but other systems do (e.g. FreeBSD) */ + /* the Linux Kernel doesn't care for the src address, but other systems do + * (e.g. FreeBSD) + */ add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); @@ -1518,6 +1634,12 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, pfkey_msg_t response; size_t len; + if (dir2kernel(direction) == IPSEC_DIR_INVALID) + { + /* FWD policies are not supported on all platforms */ + return SUCCESS; + } + /* create a policy */ policy = create_policy_entry(src_ts, dst_ts, direction, reqid); @@ -1594,6 +1716,18 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, policy->dst.mask); +#ifdef __FreeBSD__ + { /* on FreeBSD a lifetime has to be defined to be able to later query + * the current use time. */ + struct sadb_lifetime *lft; + lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); + lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; + lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); + lft->sadb_lifetime_addtime = LONG_MAX; + PFKEY_EXT_ADD(msg, lft); + } +#endif + this->mutex->unlock(this->mutex); if (pfkey_send(this, msg, &out, &len) != SUCCESS) @@ -1700,6 +1834,12 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this, pfkey_msg_t response; size_t len; + if (dir2kernel(direction) == IPSEC_DIR_INVALID) + { + /* FWD policies are not supported on all platforms */ + return NOT_FOUND; + } + DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts, policy_dir_names, direction); @@ -1764,6 +1904,13 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this, free(out); return FAILED; } + else if (response.lft_current == NULL) + { + DBG1(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no " + "use time", src_ts, dst_ts, policy_dir_names, direction); + free(out); + return FAILED; + } *use_time = response.lft_current->sadb_lifetime_usetime; @@ -1787,6 +1934,12 @@ static status_t del_policy(private_kernel_pfkey_ipsec_t *this, route_entry_t *route; size_t len; + if (dir2kernel(direction) == IPSEC_DIR_INVALID) + { + /* FWD policies are not supported on all platforms */ + return SUCCESS; + } + DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts, policy_dir_names, direction); @@ -1995,6 +2148,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi; this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa; this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa; + this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa; this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa; this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy; this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy; @@ -2004,8 +2158,8 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() /* private members */ this->policies = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); - this->mutex_pfkey = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT); this->install_routes = lib->settings->get_bool(lib->settings, "charon.install_routes", TRUE); this->seq = 0; diff --git a/src/charon/plugins/kernel_pfroute/Makefile.am b/src/charon/plugins/kernel_pfroute/Makefile.am index 3ad445c09..b6e6587a7 100644 --- a/src/charon/plugins/kernel_pfroute/Makefile.am +++ b/src/charon/plugins/kernel_pfroute/Makefile.am @@ -7,4 +7,4 @@ plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la libstrongswan_kernel_pfroute_la_SOURCES = kernel_pfroute_plugin.h kernel_pfroute_plugin.c \ kernel_pfroute_net.h kernel_pfroute_net.c -libstrongswan_kernel_pfroute_la_LDFLAGS = -module +libstrongswan_kernel_pfroute_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/kernel_pfroute/Makefile.in b/src/charon/plugins/kernel_pfroute/Makefile.in index e585a7db2..05da8e271 100644 --- a/src/charon/plugins/kernel_pfroute/Makefile.in +++ b/src/charon/plugins/kernel_pfroute/Makefile.in @@ -76,12 +76,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -146,6 +148,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -186,7 +189,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -226,7 +231,7 @@ plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la libstrongswan_kernel_pfroute_la_SOURCES = kernel_pfroute_plugin.h kernel_pfroute_plugin.c \ kernel_pfroute_net.h kernel_pfroute_net.c -libstrongswan_kernel_pfroute_la_LDFLAGS = -module +libstrongswan_kernel_pfroute_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.c index c2b35a5ce..d5a864b1c 100644 --- a/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -681,8 +681,8 @@ kernel_pfroute_net_t *kernel_pfroute_net_create() /* private members */ this->ifaces = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); - this->mutex_pfroute = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->mutex_pfroute = mutex_create(MUTEX_TYPE_DEFAULT); this->seq = 0; diff --git a/src/charon/plugins/load_tester/Makefile.am b/src/charon/plugins/load_tester/Makefile.am index 121f0b080..e6e04229a 100644 --- a/src/charon/plugins/load_tester/Makefile.am +++ b/src/charon/plugins/load_tester/Makefile.am @@ -13,5 +13,5 @@ libstrongswan_load_tester_la_SOURCES = \ load_tester_listener.c load_tester_listener.h \ load_tester_diffie_hellman.c load_tester_diffie_hellman.h -libstrongswan_load_tester_la_LDFLAGS = -module +libstrongswan_load_tester_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/load_tester/Makefile.in b/src/charon/plugins/load_tester/Makefile.in index 056ac16d3..3b494cea2 100644 --- a/src/charon/plugins/load_tester/Makefile.in +++ b/src/charon/plugins/load_tester/Makefile.in @@ -78,12 +78,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -148,6 +150,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -188,7 +191,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -233,7 +238,7 @@ libstrongswan_load_tester_la_SOURCES = \ load_tester_listener.c load_tester_listener.h \ load_tester_diffie_hellman.c load_tester_diffie_hellman.h -libstrongswan_load_tester_la_LDFLAGS = -module +libstrongswan_load_tester_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/load_tester/load_tester_ipsec.c b/src/charon/plugins/load_tester/load_tester_ipsec.c index d37f7a7bd..e463d2adc 100644 --- a/src/charon/plugins/load_tester/load_tester_ipsec.c +++ b/src/charon/plugins/load_tester/load_tester_ipsec.c @@ -84,6 +84,16 @@ static status_t update_sa(private_load_tester_ipsec_t *this, } /** + * Implementation of kernel_interface_t.query_sa. + */ +static status_t query_sa(private_load_tester_ipsec_t *this, host_t *src, + host_t *dst, u_int32_t spi, protocol_id_t protocol, + u_int64_t *bytes) +{ + return NOT_SUPPORTED; +} + +/** * Implementation of kernel_interface_t.del_sa. */ static status_t del_sa(private_load_tester_ipsec_t *this, host_t *src, @@ -151,6 +161,7 @@ load_tester_ipsec_t *load_tester_ipsec_create() this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi; this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa; this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa; + this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa; this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa; this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t *this,host_t *, host_t *,traffic_selector_t *,traffic_selector_t *,policy_dir_t, u_int32_t,protocol_id_t, u_int32_t,ipsec_mode_t, u_int16_t, u_int16_t,bool))add_policy; this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy; diff --git a/src/charon/plugins/load_tester/load_tester_plugin.c b/src/charon/plugins/load_tester/load_tester_plugin.c index 12ac7b090..93ed2e3c5 100644 --- a/src/charon/plugins/load_tester/load_tester_plugin.c +++ b/src/charon/plugins/load_tester/load_tester_plugin.c @@ -202,8 +202,8 @@ plugin_t *plugin_create() shutdown_on = this->iterations * this->initiators; } - this->mutex = mutex_create(MUTEX_DEFAULT); - this->condvar = condvar_create(CONDVAR_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT); this->config = load_tester_config_create(); this->creds = load_tester_creds_create(); this->listener = load_tester_listener_create(shutdown_on); diff --git a/src/charon/plugins/medcli/Makefile.am b/src/charon/plugins/medcli/Makefile.am index f15950af9..a5f018f82 100644 --- a/src/charon/plugins/medcli/Makefile.am +++ b/src/charon/plugins/medcli/Makefile.am @@ -8,5 +8,5 @@ libstrongswan_medcli_la_SOURCES = medcli_plugin.h medcli_plugin.c \ medcli_creds.h medcli_creds.c \ medcli_config.h medcli_config.c \ medcli_listener.h medcli_listener.c -libstrongswan_medcli_la_LDFLAGS = -module +libstrongswan_medcli_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/medcli/Makefile.in b/src/charon/plugins/medcli/Makefile.in index cef486411..9a2b3f889 100644 --- a/src/charon/plugins/medcli/Makefile.in +++ b/src/charon/plugins/medcli/Makefile.in @@ -75,12 +75,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -145,6 +147,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -185,7 +188,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -227,7 +232,7 @@ libstrongswan_medcli_la_SOURCES = medcli_plugin.h medcli_plugin.c \ medcli_config.h medcli_config.c \ medcli_listener.h medcli_listener.c -libstrongswan_medcli_la_LDFLAGS = -module +libstrongswan_medcli_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/medsrv/Makefile.am b/src/charon/plugins/medsrv/Makefile.am index 476da1878..f3611a79e 100644 --- a/src/charon/plugins/medsrv/Makefile.am +++ b/src/charon/plugins/medsrv/Makefile.am @@ -7,5 +7,5 @@ plugin_LTLIBRARIES = libstrongswan-medsrv.la libstrongswan_medsrv_la_SOURCES = medsrv_plugin.h medsrv_plugin.c \ medsrv_creds.h medsrv_creds.c \ medsrv_config.h medsrv_config.c -libstrongswan_medsrv_la_LDFLAGS = -module +libstrongswan_medsrv_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/medsrv/Makefile.in b/src/charon/plugins/medsrv/Makefile.in index ec537e505..ba599499b 100644 --- a/src/charon/plugins/medsrv/Makefile.in +++ b/src/charon/plugins/medsrv/Makefile.in @@ -75,12 +75,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -145,6 +147,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -185,7 +188,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -226,7 +231,7 @@ libstrongswan_medsrv_la_SOURCES = medsrv_plugin.h medsrv_plugin.c \ medsrv_creds.h medsrv_creds.c \ medsrv_config.h medsrv_config.c -libstrongswan_medsrv_la_LDFLAGS = -module +libstrongswan_medsrv_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/nm/Makefile.am b/src/charon/plugins/nm/Makefile.am index 9a0b48cd2..b74a4e46f 100644 --- a/src/charon/plugins/nm/Makefile.am +++ b/src/charon/plugins/nm/Makefile.am @@ -9,5 +9,5 @@ libstrongswan_nm_la_SOURCES = \ nm_service.h nm_service.c \ nm_creds.h nm_creds.c \ nm_handler.h nm_handler.c -libstrongswan_nm_la_LDFLAGS = -module +libstrongswan_nm_la_LDFLAGS = -module -avoid-version libstrongswan_nm_la_LIBADD = ${nm_LIBS} diff --git a/src/charon/plugins/nm/Makefile.in b/src/charon/plugins/nm/Makefile.in index a75af8a0f..c7c428c2a 100644 --- a/src/charon/plugins/nm/Makefile.in +++ b/src/charon/plugins/nm/Makefile.in @@ -75,12 +75,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -145,6 +147,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -185,7 +188,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -228,7 +233,7 @@ libstrongswan_nm_la_SOURCES = \ nm_creds.h nm_creds.c \ nm_handler.h nm_handler.c -libstrongswan_nm_la_LDFLAGS = -module +libstrongswan_nm_la_LDFLAGS = -module -avoid-version libstrongswan_nm_la_LIBADD = ${nm_LIBS} all: all-am diff --git a/src/charon/plugins/nm/nm_creds.c b/src/charon/plugins/nm/nm_creds.c index d93b81c9a..4ea2c36dd 100644 --- a/src/charon/plugins/nm/nm_creds.c +++ b/src/charon/plugins/nm/nm_creds.c @@ -322,7 +322,7 @@ nm_creds_t *nm_creds_create() this->public.clear = (void(*)(nm_creds_t*))clear; this->public.destroy = (void(*)(nm_creds_t*))destroy; - this->lock = rwlock_create(RWLOCK_DEFAULT); + this->lock = rwlock_create(RWLOCK_TYPE_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 bca4d9e09..88a3cc95e 100644 --- a/src/charon/plugins/nm/nm_service.c +++ b/src/charon/plugins/nm/nm_service.c @@ -14,6 +14,7 @@ */ #include <nm-setting-vpn.h> +#include <nm-setting-connection.h> #include "nm_service.h" #include <daemon.h> @@ -25,8 +26,6 @@ #include <stdio.h> -#define CONFIG_NAME "NetworkManager" - G_DEFINE_TYPE(NMStrongswanPlugin, nm_strongswan_plugin, NM_TYPE_VPN_PLUGIN) /** @@ -43,6 +42,8 @@ typedef struct { nm_creds_t *creds; /* attribute handler for DNS/NBNS server information */ nm_handler_t *handler; + /* name of the connection */ + char *name; } NMStrongswanPluginPrivate; #define NM_STRONGSWAN_PLUGIN_GET_PRIVATE(o) \ @@ -121,14 +122,14 @@ static void signal_ipv4_config(NMVPNPlugin *plugin, /** * signal failure to NM, connecting failed */ -static void signal_failure(NMVPNPlugin *plugin) +static void signal_failure(NMVPNPlugin *plugin, NMVPNPluginFailure failure) { nm_handler_t *handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler; handler->reset(handler); /* TODO: NM does not handle this failure!? */ - nm_vpn_plugin_failure(plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); + nm_vpn_plugin_failure(plugin, failure); nm_vpn_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED); } @@ -140,16 +141,10 @@ static bool ike_state_change(listener_t *listener, ike_sa_t *ike_sa, { NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; - if (private->ike_sa == ike_sa) + if (private->ike_sa == ike_sa && state == IKE_DESTROYING) { - switch (state) - { - case IKE_DESTROYING: - signal_failure(private->plugin); - return FALSE; - default: - break; - } + signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); + return FALSE; } return TRUE; } @@ -161,32 +156,63 @@ 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 && state == CHILD_DESTROYING) + { + signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); + return FALSE; + } + return TRUE; +} +/** + * Implementation of listener_t.child_updown + */ +static bool child_updown(listener_t *listener, ike_sa_t *ike_sa, + child_sa_t *child_sa, bool up) +{ + NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; + if (private->ike_sa == ike_sa) { - switch (state) + if (up) + { /* disable initiate-failure-detection hooks */ + private->listener.ike_state_change = NULL; + private->listener.child_state_change = NULL; + signal_ipv4_config(private->plugin, ike_sa, child_sa); + } + else { - 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; + signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); + return FALSE; } } return TRUE; } /** + * Implementation of listener_t.ike_rekey + */ +static bool ike_rekey(listener_t *listener, ike_sa_t *old, ike_sa_t *new) +{ + NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; + + if (private->ike_sa == old) + { /* follow a rekeyed IKE_SA */ + private->ike_sa = new; + } + return TRUE; +} + +/** * Connect function called from NM via DBUS */ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, GError **err) { - nm_creds_t *creds; - NMSettingVPN *settings; + NMStrongswanPluginPrivate *priv; + NMSettingConnection *conn; + NMSettingVPN *vpn; identification_t *user = NULL, *gateway; const char *address, *str; bool virtual, encap, ipcomp; @@ -204,25 +230,34 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, /** * Read parameters */ - settings = NM_SETTING_VPN(nm_connection_get_setting(connection, - NM_TYPE_SETTING_VPN)); - - DBG4(DBG_CFG, "received NetworkManager connection: %s", - nm_setting_to_string(NM_SETTING(settings))); - address = nm_setting_vpn_get_data_item(settings, "address"); + priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); + conn = NM_SETTING_CONNECTION(nm_connection_get_setting(connection, + NM_TYPE_SETTING_CONNECTION)); + vpn = NM_SETTING_VPN(nm_connection_get_setting(connection, + NM_TYPE_SETTING_VPN)); + 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) { g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, "Gateway address missing."); 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"); - str = nm_setting_vpn_get_data_item(settings, "encap"); + str = nm_setting_vpn_get_data_item(vpn, "encap"); 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"); - str = nm_setting_vpn_get_data_item(settings, "method"); + str = nm_setting_vpn_get_data_item(vpn, "method"); if (str) { if (streq(str, "psk")) @@ -243,16 +278,15 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, /** * Register credentials */ - creds = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds; - creds->clear(creds); + priv->creds->clear(priv->creds); /* gateway/CA cert */ - str = nm_setting_vpn_get_data_item(settings, "certificate"); + str = nm_setting_vpn_get_data_item(vpn, "certificate"); if (str) { cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, str, BUILD_END); - creds->set_certificate(creds, cert); + priv->creds->set_certificate(priv->creds, cert); } if (!cert) { @@ -279,19 +313,19 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, if (auth_class == AUTH_CLASS_EAP) { /* username/password authentication ... */ - str = nm_setting_vpn_get_data_item(settings, "user"); + str = nm_setting_vpn_get_data_item(vpn, "user"); if (str) { user = identification_create_from_string((char*)str); - str = nm_setting_vpn_get_secret(settings, "password"); - creds->set_username_password(creds, user, (char*)str); + str = nm_setting_vpn_get_secret(vpn, "password"); + priv->creds->set_username_password(priv->creds, user, (char*)str); } } if (auth_class == AUTH_CLASS_PUBKEY) { /* ... 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) { public_key_t *public; @@ -308,7 +342,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, return FALSE; } /* try agent */ - str = nm_setting_vpn_get_secret(settings, "agent"); + str = nm_setting_vpn_get_secret(vpn, "agent"); if (agent && str) { public = cert->get_public_key(cert); @@ -329,14 +363,13 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, } } /* ... or key file */ - str = nm_setting_vpn_get_data_item(settings, "userkey"); + str = nm_setting_vpn_get_data_item(vpn, "userkey"); if (!agent && str) { chunk_t secret, chunk; bool pgp = FALSE; - secret.ptr = (char*)nm_setting_vpn_get_secret(settings, - "password"); + secret.ptr = (char*)nm_setting_vpn_get_secret(vpn, "password"); if (secret.ptr) { secret.len = strlen(secret.ptr); @@ -358,7 +391,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, { user = cert->get_subject(cert); user = user->clone(user); - creds->set_cert_and_key(creds, cert, private); + priv->creds->set_cert_and_key(priv->creds, cert, private); } else { @@ -382,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->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 */ 36000, 0, /* rekey 10h, reauth none */ 600, 600, /* jitter, over 10min */ @@ -398,11 +431,11 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, auth->add(auth, AUTH_RULE_IDENTITY, gateway); 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 */ 300, /* jitter 5min */ NULL, TRUE, MODE_TUNNEL, /* updown, hostaccess */ - ACTION_NONE, ACTION_RESTART, ipcomp); + ACTION_NONE, ACTION_NONE, ipcomp); 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); @@ -413,7 +446,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, peer_cfg->add_child_cfg(peer_cfg, child_cfg); /** - * Start to initiate + * Prepare IKE_SA */ ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, peer_cfg); @@ -425,21 +458,27 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, { peer_cfg->destroy(peer_cfg); } + + /** + * Register listener, enable initiate-failure-detection hooks + */ + priv->ike_sa = ike_sa; + priv->listener.ike_state_change = ike_state_change; + priv->listener.child_state_change = child_state_change; + charon->bus->add_listener(charon->bus, &priv->listener); + + /** + * Initiate + */ if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS) { + charon->bus->remove_listener(charon->bus, &priv->listener); 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, "Initiating failed."); return FALSE; } - - /** - * Register listener - */ - NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->ike_sa = ike_sa; - charon->bus->add_listener(charon->bus, - &NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->listener); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); return TRUE; } @@ -501,14 +540,16 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection, */ static gboolean disconnect(NMVPNPlugin *plugin, GError **err) { + NMStrongswanPluginPrivate *priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); enumerator_t *enumerator; ike_sa_t *ike_sa; u_int id; + /* our ike_sa pointer might be invalid, lookup sa */ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); 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); enumerator->destroy(enumerator); @@ -529,13 +570,13 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err) */ static void nm_strongswan_plugin_init(NMStrongswanPlugin *plugin) { - NMStrongswanPluginPrivate *private; + NMStrongswanPluginPrivate *priv; - 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; + priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); + priv->plugin = NM_VPN_PLUGIN(plugin); + memset(&priv->listener.log, 0, sizeof(listener_t)); + priv->listener.child_updown = child_updown; + priv->listener.ike_rekey = ike_rekey; } /** @@ -565,8 +606,12 @@ NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds, NULL); if (plugin) { - NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds = creds; - NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler = handler; + NMStrongswanPluginPrivate *priv; + + priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); + priv->creds = creds; + priv->handler = handler; + priv->name = NULL; } return plugin; } diff --git a/src/charon/plugins/resolv_conf/Makefile.am b/src/charon/plugins/resolv_conf/Makefile.am index 917964f93..be7f862f2 100644 --- a/src/charon/plugins/resolv_conf/Makefile.am +++ b/src/charon/plugins/resolv_conf/Makefile.am @@ -8,6 +8,6 @@ plugin_LTLIBRARIES = libstrongswan-resolv-conf.la libstrongswan_resolv_conf_la_SOURCES = \ resolv_conf_plugin.h resolv_conf_plugin.c \ resolv_conf_handler.h resolv_conf_handler.c -libstrongswan_resolv_conf_la_LDFLAGS = -module +libstrongswan_resolv_conf_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/resolv_conf/Makefile.in b/src/charon/plugins/resolv_conf/Makefile.in index 91ddae582..19c20467a 100644 --- a/src/charon/plugins/resolv_conf/Makefile.in +++ b/src/charon/plugins/resolv_conf/Makefile.in @@ -76,12 +76,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -146,6 +148,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -186,7 +189,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -229,7 +234,7 @@ libstrongswan_resolv_conf_la_SOURCES = \ resolv_conf_plugin.h resolv_conf_plugin.c \ resolv_conf_handler.h resolv_conf_handler.c -libstrongswan_resolv_conf_la_LDFLAGS = -module +libstrongswan_resolv_conf_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/resolv_conf/resolv_conf_handler.c b/src/charon/plugins/resolv_conf/resolv_conf_handler.c index 19e3b3275..749cfbc5b 100644 --- a/src/charon/plugins/resolv_conf/resolv_conf_handler.c +++ b/src/charon/plugins/resolv_conf/resolv_conf_handler.c @@ -183,7 +183,7 @@ resolv_conf_handler_t *resolv_conf_handler_create() this->public.handler.release = (void(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))release; this->public.destroy = (void(*)(resolv_conf_handler_t*))destroy; - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); this->file = lib->settings->get_str(lib->settings, "charon.plugins.resolv-conf.file", RESOLV_CONF); diff --git a/src/charon/plugins/smp/Makefile.am b/src/charon/plugins/smp/Makefile.am index 1679f1c68..a434b388b 100644 --- a/src/charon/plugins/smp/Makefile.am +++ b/src/charon/plugins/smp/Makefile.am @@ -5,6 +5,6 @@ AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\" plugin_LTLIBRARIES = libstrongswan-smp.la libstrongswan_smp_la_SOURCES = smp.h smp.c -libstrongswan_smp_la_LDFLAGS = -module +libstrongswan_smp_la_LDFLAGS = -module -avoid-version libstrongswan_smp_la_LIBADD = ${xml_LIBS} diff --git a/src/charon/plugins/smp/Makefile.in b/src/charon/plugins/smp/Makefile.in index f06321ba7..d23d2d001 100644 --- a/src/charon/plugins/smp/Makefile.in +++ b/src/charon/plugins/smp/Makefile.in @@ -74,12 +74,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -144,6 +146,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -184,7 +187,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -222,7 +227,7 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${xml_CF AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\" plugin_LTLIBRARIES = libstrongswan-smp.la libstrongswan_smp_la_SOURCES = smp.h smp.c -libstrongswan_smp_la_LDFLAGS = -module +libstrongswan_smp_la_LDFLAGS = -module -avoid-version libstrongswan_smp_la_LIBADD = ${xml_LIBS} all: all-am diff --git a/src/charon/plugins/sql/Makefile.am b/src/charon/plugins/sql/Makefile.am index ea39ce0d5..bf4963f29 100644 --- a/src/charon/plugins/sql/Makefile.am +++ b/src/charon/plugins/sql/Makefile.am @@ -10,7 +10,7 @@ plugin_LTLIBRARIES = libstrongswan-sql.la libstrongswan_sql_la_SOURCES = sql_plugin.h sql_plugin.c \ sql_config.h sql_config.c sql_cred.h sql_cred.c \ sql_attribute.h sql_attribute.c sql_logger.h sql_logger.c -libstrongswan_sql_la_LDFLAGS = -module +libstrongswan_sql_la_LDFLAGS = -module -avoid-version ipsec_PROGRAMS = pool pool_SOURCES = pool.c diff --git a/src/charon/plugins/sql/Makefile.in b/src/charon/plugins/sql/Makefile.in index 0848ea0dd..f6fd8e4f7 100644 --- a/src/charon/plugins/sql/Makefile.in +++ b/src/charon/plugins/sql/Makefile.in @@ -82,12 +82,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -152,6 +154,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -192,7 +195,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -237,7 +242,7 @@ libstrongswan_sql_la_SOURCES = sql_plugin.h sql_plugin.c \ sql_config.h sql_config.c sql_cred.h sql_cred.c \ sql_attribute.h sql_attribute.c sql_logger.h sql_logger.c -libstrongswan_sql_la_LDFLAGS = -module +libstrongswan_sql_la_LDFLAGS = -module -avoid-version pool_SOURCES = pool.c pool_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la all: all-am diff --git a/src/charon/plugins/sql/pool.c b/src/charon/plugins/sql/pool.c index 7d393b6f7..ebcc9adc7 100644 --- a/src/charon/plugins/sql/pool.c +++ b/src/charon/plugins/sql/pool.c @@ -637,8 +637,19 @@ int main(int argc, char *argv[]) } operation = OP_USAGE; dbg = dbg_stderr; - library_init(STRONGSWAN_CONF); atexit(library_deinit); + + /* initialize library */ + if (!library_init(STRONGSWAN_CONF)) + { + exit(SS_RC_LIBSTRONGSWAN_INTEGRITY); + } + if (lib->integrity && + !lib->integrity->check_file(lib->integrity, "pool", argv[0])) + { + fprintf(stderr, "integrity check of pool failed\n"); + exit(SS_RC_DAEMON_INTEGRITY); + } lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR, lib->settings->get_str(lib->settings, "pool.load", PLUGINS)); diff --git a/src/charon/plugins/sql/sql_attribute.c b/src/charon/plugins/sql/sql_attribute.c index 95d0d30d4..77601e612 100644 --- a/src/charon/plugins/sql/sql_attribute.c +++ b/src/charon/plugins/sql/sql_attribute.c @@ -92,25 +92,18 @@ static u_int get_pool(private_sql_attribute_t *this, char *name, u_int *timeout) } /** - * Lookup a lease + * Look up an existing lease */ -static host_t *get_address(private_sql_attribute_t *this, char *name, - u_int pool, u_int timeout, u_int identity) +static host_t* check_lease(private_sql_attribute_t *this, char *name, + u_int pool, u_int identity) { - enumerator_t *e; - u_int id; - chunk_t address; - host_t *host; - time_t now = time(NULL); - - /* We check for leases for that identity first and for other expired - * leases afterwards. We select an address as a candidate, but double - * check if it is still valid in the update. This allows us to work - * without locking. */ - - /* check for an existing lease for that identity */ while (TRUE) { + u_int id; + chunk_t address; + enumerator_t *e; + time_t now = time(NULL); + e = this->db->query(this->db, "SELECT id, address FROM addresses " "WHERE pool = ? AND identity = ? AND released != 0 LIMIT 1", @@ -122,11 +115,14 @@ static host_t *get_address(private_sql_attribute_t *this, char *name, } address = chunk_clonea(address); e->destroy(e); + if (this->db->execute(this->db, NULL, "UPDATE addresses SET acquired = ?, released = 0 " "WHERE id = ? AND identity = ? AND released != 0", DB_UINT, now, DB_UINT, id, DB_UINT, identity) > 0) { + host_t *host; + host = host_create_from_chunk(AF_UNSPEC, address, 0); if (host) { @@ -136,14 +132,43 @@ static host_t *get_address(private_sql_attribute_t *this, char *name, } } } - - /* check for an expired lease */ + return NULL; +} + +/** + * We check for unallocated addresses or expired leases. First we select an + * address as a candidate, but double check later on if it is still available + * during the update operation. This allows us to work without locking. + */ +static host_t* get_lease(private_sql_attribute_t *this, char *name, + u_int pool, u_int timeout, u_int identity) +{ while (TRUE) { - e = this->db->query(this->db, + u_int id; + chunk_t address; + enumerator_t *e; + time_t now = time(NULL); + int hits; + + if (timeout) + { + /* check for an expired lease */ + e = this->db->query(this->db, "SELECT id, address FROM addresses " "WHERE pool = ? AND released != 0 AND released < ? LIMIT 1", DB_UINT, pool, DB_UINT, now - timeout, DB_UINT, DB_BLOB); + } + else + { + /* with static leases, check for an unallocated address */ + e = this->db->query(this->db, + "SELECT id, address FROM addresses " + "WHERE pool = ? AND identity = 0 LIMIT 1", + DB_UINT, pool, DB_UINT, DB_BLOB); + + } + if (!e || !e->enumerate(e, &id, &address)) { DESTROY_IF(e); @@ -152,13 +177,27 @@ static host_t *get_address(private_sql_attribute_t *this, char *name, address = chunk_clonea(address); e->destroy(e); - if (this->db->execute(this->db, NULL, - "UPDATE addresses SET " - "acquired = ?, released = 0, identity = ? " - "WHERE id = ? AND released != 0 AND released < ?", - DB_UINT, now, DB_UINT, identity, - DB_UINT, id, DB_UINT, now - timeout) > 0) + if (timeout) + { + hits = this->db->execute(this->db, NULL, + "UPDATE addresses SET " + "acquired = ?, released = 0, identity = ? " + "WHERE id = ? AND released != 0 AND released < ?", + DB_UINT, now, DB_UINT, identity, + DB_UINT, id, DB_UINT, now - timeout); + } + else { + hits = this->db->execute(this->db, NULL, + "UPDATE addresses SET " + "acquired = ?, released = 0, identity = ? " + "WHERE id = ? AND identity = 0", + DB_UINT, now, DB_UINT, identity, DB_UINT, id); + } + if (hits > 0) + { + host_t *host; + host = host_create_from_chunk(AF_UNSPEC, address, 0); if (host) { @@ -169,37 +208,75 @@ static host_t *get_address(private_sql_attribute_t *this, char *name, } } DBG1(DBG_CFG, "no available address found in pool '%s'", name); - return 0; + return NULL; } /** * Implementation of attribute_provider_t.acquire_address */ static host_t* acquire_address(private_sql_attribute_t *this, - char *name, identification_t *id, + char *names, identification_t *id, host_t *requested) { - enumerator_t *enumerator; - u_int pool, timeout, identity; host_t *address = NULL; - + u_int identity, pool, timeout; + identity = get_identity(this, id); if (identity) { - enumerator = enumerator_create_token(name, ",", " "); - while (enumerator->enumerate(enumerator, &name)) + /* check for a single pool first (no concatenation and enumeration) */ + if (strchr(names, ',') == NULL) { - pool = get_pool(this, name, &timeout); + pool = get_pool(this, names, &timeout); if (pool) { - address = get_address(this, name, pool, timeout, identity); - if (address) + /* check for an existing lease */ + address = check_lease(this, names, pool, identity); + if (address == NULL) + { + /* get an unallocated address or expired lease */ + address = get_lease(this, names, pool, timeout, identity); + } + } + } + else + { + enumerator_t *enumerator; + char *name; + + /* in a first step check for an existing lease over all pools */ + enumerator = enumerator_create_token(names, ",", " "); + while (enumerator->enumerate(enumerator, &name)) + { + pool = get_pool(this, name, &timeout); + if (pool) + { + address = check_lease(this, name, pool, identity); + if (address) + { + enumerator->destroy(enumerator); + return address; + } + } + } + enumerator->destroy(enumerator); + + /* in a second step get an unallocated address or expired lease */ + enumerator = enumerator_create_token(names, ",", " "); + while (enumerator->enumerate(enumerator, &name)) + { + pool = get_pool(this, name, &timeout); + if (pool) { - break; + address = get_lease(this, name, pool, timeout, identity); + if (address) + { + break; + } } } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); } return address; } diff --git a/src/charon/plugins/sql/sql_config.c b/src/charon/plugins/sql/sql_config.c index 3e5efce34..e7dfe573b 100644 --- a/src/charon/plugins/sql/sql_config.c +++ b/src/charon/plugins/sql/sql_config.c @@ -295,10 +295,10 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e, mediation, mediated_cfg, peer_id); auth = auth_cfg_create(); auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_method); - auth->add(auth, AUTH_RULE_IDENTITY, local_id->clone(local_id)); + auth->add(auth, AUTH_RULE_IDENTITY, local_id); peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE); auth = auth_cfg_create(); - auth->add(auth, AUTH_RULE_IDENTITY, remote_id->clone(remote_id)); + auth->add(auth, AUTH_RULE_IDENTITY, remote_id); if (eap_type) { auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP); diff --git a/src/charon/plugins/stroke/Makefile.am b/src/charon/plugins/stroke/Makefile.am index fb58ba62b..79a63f2c2 100644 --- a/src/charon/plugins/stroke/Makefile.am +++ b/src/charon/plugins/stroke/Makefile.am @@ -18,5 +18,5 @@ libstrongswan_stroke_la_SOURCES = stroke_plugin.h stroke_plugin.c \ stroke_list.h stroke_list.c \ stroke_shared_key.h stroke_shared_key.c -libstrongswan_stroke_la_LDFLAGS = -module +libstrongswan_stroke_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/stroke/Makefile.in b/src/charon/plugins/stroke/Makefile.in index f246286a0..19822ebc8 100644 --- a/src/charon/plugins/stroke/Makefile.in +++ b/src/charon/plugins/stroke/Makefile.in @@ -76,12 +76,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -146,6 +148,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -186,7 +189,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -237,7 +242,7 @@ libstrongswan_stroke_la_SOURCES = stroke_plugin.h stroke_plugin.c \ stroke_list.h stroke_list.c \ stroke_shared_key.h stroke_shared_key.c -libstrongswan_stroke_la_LDFLAGS = -module +libstrongswan_stroke_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/stroke/stroke_attribute.c b/src/charon/plugins/stroke/stroke_attribute.c index a7925ce3e..d3211fd67 100644 --- a/src/charon/plugins/stroke/stroke_attribute.c +++ b/src/charon/plugins/stroke/stroke_attribute.c @@ -539,7 +539,7 @@ stroke_attribute_t *stroke_attribute_create() this->public.destroy = (void(*)(stroke_attribute_t*))destroy; this->pools = linked_list_create(); - this->mutex = mutex_create(MUTEX_RECURSIVE); + this->mutex = mutex_create(MUTEX_TYPE_RECURSIVE); return &this->public; } diff --git a/src/charon/plugins/stroke/stroke_ca.c b/src/charon/plugins/stroke/stroke_ca.c index fab06e6c5..c354d8cb8 100644 --- a/src/charon/plugins/stroke/stroke_ca.c +++ b/src/charon/plugins/stroke/stroke_ca.c @@ -447,7 +447,7 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred) this->public.destroy = (void(*)(stroke_ca_t*))destroy; this->sections = linked_list_create(); - this->lock = rwlock_create(RWLOCK_DEFAULT); + this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); this->cred = cred; return &this->public; diff --git a/src/charon/plugins/stroke/stroke_config.c b/src/charon/plugins/stroke/stroke_config.c index 028e71e71..0b6a4ac31 100644 --- a/src/charon/plugins/stroke/stroke_config.c +++ b/src/charon/plugins/stroke/stroke_config.c @@ -924,7 +924,7 @@ stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred) this->public.destroy = (void(*)(stroke_config_t*))destroy; this->list = linked_list_create(); - this->mutex = mutex_create(MUTEX_RECURSIVE); + this->mutex = mutex_create(MUTEX_TYPE_RECURSIVE); this->ca = ca; this->cred = cred; diff --git a/src/charon/plugins/stroke/stroke_cred.c b/src/charon/plugins/stroke/stroke_cred.c index dc73299b8..31bcfe9f4 100644 --- a/src/charon/plugins/stroke/stroke_cred.c +++ b/src/charon/plugins/stroke/stroke_cred.c @@ -16,6 +16,8 @@ #include <sys/stat.h> #include <limits.h> +#include <glob.h> +#include <libgen.h> #include "stroke_cred.h" #include "stroke_shared_key.h" @@ -41,6 +43,8 @@ #define CRL_DIR IPSEC_D_DIR "/crls" #define SECRETS_FILE CONFIG_DIR "/ipsec.secrets" +#define MAX_SECRETS_RECURSION 10 + typedef struct private_stroke_cred_t private_stroke_cred_t; /** @@ -691,7 +695,7 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line) /** * reload ipsec.secrets */ -static void load_secrets(private_stroke_cred_t *this) +static void load_secrets(private_stroke_cred_t *this, char *file, int level) { size_t bytes; int line_nr = 0; @@ -700,9 +704,9 @@ static void load_secrets(private_stroke_cred_t *this) private_key_t *private; shared_key_t *shared; - DBG1(DBG_CFG, "loading secrets from '%s'", SECRETS_FILE); + DBG1(DBG_CFG, "loading secrets from '%s'", file); - fd = fopen(SECRETS_FILE, "r"); + fd = fopen(file, "r"); if (fd == NULL) { DBG1(DBG_CFG, "opening secrets file '%s' failed"); @@ -719,15 +723,19 @@ static void load_secrets(private_stroke_cred_t *this) src = chunk; this->lock->write_lock(this->lock); - while (this->shared->remove_last(this->shared, - (void**)&shared) == SUCCESS) - { - shared->destroy(shared); - } - while (this->private->remove_last(this->private, - (void**)&private) == SUCCESS) + if (level == 0) { - private->destroy(private); + /* flush secrets on non-recursive invocation */ + while (this->shared->remove_last(this->shared, + (void**)&shared) == SUCCESS) + { + shared->destroy(shared); + } + while (this->private->remove_last(this->private, + (void**)&private) == SUCCESS) + { + private->destroy(private); + } } while (fetchline(&src, &line)) @@ -741,6 +749,66 @@ static void load_secrets(private_stroke_cred_t *this) { continue; } + if (line.len > strlen("include ") && + strneq(line.ptr, "include ", strlen("include "))) + { + glob_t buf; + char **expanded, *dir, pattern[PATH_MAX]; + u_char *pos; + + if (level > MAX_SECRETS_RECURSION) + { + DBG1(DBG_CFG, "maximum level of %d includes reached, ignored", + MAX_SECRETS_RECURSION); + continue; + } + /* terminate filename by space */ + line = chunk_skip(line, strlen("include ")); + pos = memchr(line.ptr, ' ', line.len); + if (pos) + { + line.len = pos - line.ptr; + } + if (line.len && line.ptr[0] == '/') + { + if (line.len + 1 > sizeof(pattern)) + { + DBG1(DBG_CFG, "include pattern too long, ignored"); + continue; + } + snprintf(pattern, sizeof(pattern), "%.*s", line.len, line.ptr); + } + else + { /* use directory of current file if relative */ + dir = strdup(file); + dir = dirname(dir); + + if (line.len + 1 + strlen(dir) + 1 > sizeof(pattern)) + { + DBG1(DBG_CFG, "include pattern too long, ignored"); + free(dir); + continue; + } + snprintf(pattern, sizeof(pattern), "%s/%.*s", + dir, line.len, line.ptr); + free(dir); + } + if (glob(pattern, GLOB_ERR, NULL, &buf) != 0) + { + DBG1(DBG_CFG, "expanding file expression '%s' failed", pattern); + globfree(&buf); + } + else + { + for (expanded = buf.gl_pathv; *expanded != NULL; expanded++) + { + load_secrets(this, *expanded, level + 1); + } + } + globfree(&buf); + continue; + } + if (line.len > 2 && strneq(": ", line.ptr, 2)) { /* no ids, skip the ':' */ @@ -989,7 +1057,7 @@ static void reread(private_stroke_cred_t *this, stroke_msg_t *msg) if (msg->reread.flags & REREAD_SECRETS) { DBG1(DBG_CFG, "rereading secrets"); - load_secrets(this); + load_secrets(this, SECRETS_FILE, 0); } if (msg->reread.flags & REREAD_CACERTS) { @@ -1057,10 +1125,10 @@ stroke_cred_t *stroke_cred_create() this->certs = linked_list_create(); this->shared = linked_list_create(); this->private = linked_list_create(); - this->lock = rwlock_create(RWLOCK_DEFAULT); + this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); load_certs(this); - load_secrets(this); + load_secrets(this, SECRETS_FILE, 0); this->cachecrl = FALSE; diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c index 564a511a1..6f421bd30 100644 --- a/src/charon/plugins/stroke/stroke_list.c +++ b/src/charon/plugins/stroke/stroke_list.c @@ -146,8 +146,8 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all) */ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) { - u_int32_t rekey, now = time(NULL); - u_int32_t use_in, use_out; + time_t use_in, use_out, rekey, now = time(NULL); + u_int64_t bytes_in, bytes_out; proposal_t *proposal; child_cfg_t *config = child_sa->get_config(child_sa); @@ -205,6 +205,20 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) } } } + + child_sa->get_usestats(child_sa, TRUE, &use_in, &bytes_in); + fprintf(out, ", %llu bytes_i", bytes_in); + if (use_in) + { + fprintf(out, " (%ds ago)", now - use_in); + } + + child_sa->get_usestats(child_sa, FALSE, &use_out, &bytes_out); + fprintf(out, ", %llu bytes_o", bytes_out); + if (use_out) + { + fprintf(out, " (%ds ago)", now - use_out); + } fprintf(out, ", rekeying "); rekey = child_sa->get_lifetime(child_sa, FALSE); @@ -224,25 +238,6 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) fprintf(out, "disabled"); } - fprintf(out, ", last use: "); - use_in = child_sa->get_usetime(child_sa, TRUE); - if (use_in) - { - fprintf(out, "%ds_i ", now - use_in); - } - else - { - fprintf(out, "no_i "); - } - use_out = child_sa->get_usetime(child_sa, FALSE); - if (use_out) - { - fprintf(out, "%ds_o ", now - use_out); - } - else - { - fprintf(out, "no_o "); - } } } diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c index f61171e22..9b6a8a3a7 100644 --- a/src/charon/plugins/stroke/stroke_socket.c +++ b/src/charon/plugins/stroke/stroke_socket.c @@ -27,6 +27,7 @@ #include <processing/jobs/callback_job.h> #include <daemon.h> +#include <utils/mutex.h> /* for Mac OS X compatible accept */ #include "stroke_config.h" #include "stroke_control.h" diff --git a/src/charon/plugins/uci/Makefile.am b/src/charon/plugins/uci/Makefile.am index 0136bf5e9..9fdbfb709 100644 --- a/src/charon/plugins/uci/Makefile.am +++ b/src/charon/plugins/uci/Makefile.am @@ -8,7 +8,7 @@ libstrongswan_uci_la_SOURCES = \ uci_plugin.h uci_plugin.c uci_parser.h uci_parser.c \ uci_config.h uci_config.c uci_creds.h uci_creds.c \ uci_control.h uci_control.c -libstrongswan_uci_la_LDFLAGS = -module +libstrongswan_uci_la_LDFLAGS = -module -avoid-version libstrongswan_uci_la_LIBADD = -luci diff --git a/src/charon/plugins/uci/Makefile.in b/src/charon/plugins/uci/Makefile.in index e599135cb..c4fb335d7 100644 --- a/src/charon/plugins/uci/Makefile.in +++ b/src/charon/plugins/uci/Makefile.in @@ -74,12 +74,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -144,6 +146,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -184,7 +187,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -226,7 +231,7 @@ libstrongswan_uci_la_SOURCES = \ uci_config.h uci_config.c uci_creds.h uci_creds.c \ uci_control.h uci_control.c -libstrongswan_uci_la_LDFLAGS = -module +libstrongswan_uci_la_LDFLAGS = -module -avoid-version libstrongswan_uci_la_LIBADD = -luci all: all-am diff --git a/src/charon/plugins/unit_tester/Makefile.am b/src/charon/plugins/unit_tester/Makefile.am index 50c5e0362..64846f995 100644 --- a/src/charon/plugins/unit_tester/Makefile.am +++ b/src/charon/plugins/unit_tester/Makefile.am @@ -20,5 +20,5 @@ libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h tests.h \ tests/test_agent.c \ tests/test_id.c -libstrongswan_unit_tester_la_LDFLAGS = -module +libstrongswan_unit_tester_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/unit_tester/Makefile.in b/src/charon/plugins/unit_tester/Makefile.in index 2ee5e48d8..0bf0cf301 100644 --- a/src/charon/plugins/unit_tester/Makefile.in +++ b/src/charon/plugins/unit_tester/Makefile.in @@ -79,12 +79,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -149,6 +151,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -189,7 +192,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -241,7 +246,7 @@ libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h tests.h \ tests/test_agent.c \ tests/test_id.c -libstrongswan_unit_tester_la_LDFLAGS = -module +libstrongswan_unit_tester_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/plugins/unit_tester/tests.h b/src/charon/plugins/unit_tester/tests.h index dcf2a5d18..b99940c1a 100644 --- a/src/charon/plugins/unit_tester/tests.h +++ b/src/charon/plugins/unit_tester/tests.h @@ -36,5 +36,8 @@ DEFINE_TEST("Base64 converter", test_chunk_base64, FALSE) DEFINE_TEST("IP pool", test_pool, FALSE) DEFINE_TEST("SSH agent", test_agent, FALSE) DEFINE_TEST("ID parts", test_id_parts, FALSE) +DEFINE_TEST("ID wildcards", test_id_wildcards, FALSE) +DEFINE_TEST("ID equals", test_id_equals, FALSE) +DEFINE_TEST("ID matches", test_id_matches, FALSE) /** @}*/ diff --git a/src/charon/plugins/unit_tester/tests/test_id.c b/src/charon/plugins/unit_tester/tests/test_id.c index 56dab2421..a1ef76be8 100644 --- a/src/charon/plugins/unit_tester/tests/test_id.c +++ b/src/charon/plugins/unit_tester/tests/test_id.c @@ -67,3 +67,183 @@ bool test_id_parts() return TRUE; } +/******************************************************************************* + * identification contains_wildcards() test + ******************************************************************************/ + +static bool test_id_wildcards_has(char *string) +{ + identification_t *id; + bool contains; + + id = identification_create_from_string(string); + contains = id->contains_wildcards(id); + id->destroy(id); + return contains; +} + +bool test_id_wildcards() +{ + if (!test_id_wildcards_has("C=*, O=strongSwan, CN=gw")) + { + return FALSE; + } + if (!test_id_wildcards_has("C=CH, O=strongSwan, CN=*")) + { + return FALSE; + } + if (test_id_wildcards_has("C=**, O=a*, CN=*a")) + { + return FALSE; + } + if (!test_id_wildcards_has("*@strongswan.org")) + { + return FALSE; + } + if (!test_id_wildcards_has("*.strongswan.org")) + { + return FALSE; + } + return TRUE; +} + +/******************************************************************************* + * identification equals test + ******************************************************************************/ + +static bool test_id_equals_one(identification_t *a, char *b_str) +{ + identification_t *b; + bool equals; + + b = identification_create_from_string(b_str); + equals = a->equals(a, b); + b->destroy(b); + return equals; +} + +bool test_id_equals() +{ + identification_t *a; + chunk_t encoding, fuzzed; + int i; + + a = identification_create_from_string( + "C=CH, E=martin@strongswan.org, CN=martin"); + + if (!test_id_equals_one(a, "C=CH, E=martin@strongswan.org, CN=martin")) + { + return FALSE; + } + if (!test_id_equals_one(a, "C=ch, E=martin@STRONGSWAN.ORG, CN=Martin")) + { + return FALSE; + } + if (test_id_equals_one(a, "C=CN, E=martin@strongswan.org, CN=martin")) + { + return FALSE; + } + if (test_id_equals_one(a, "E=martin@strongswan.org, C=CH, CN=martin")) + { + return FALSE; + } + if (test_id_equals_one(a, "E=martin@strongswan.org, C=CH, CN=martin")) + { + return FALSE; + } + encoding = chunk_clone(a->get_encoding(a)); + a->destroy(a); + + /* simple fuzzing, increment each byte of encoding */ + for (i = 0; i < encoding.len; i++) + { + if (i == 11 || i == 30 || i == 62) + { /* skip ASN.1 type fields, as equals() handles them graceful */ + continue; + } + fuzzed = chunk_clone(encoding); + fuzzed.ptr[i]++; + a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed); + if (test_id_equals_one(a, "C=CH, E=martin@strongswan.org, CN=martin")) + { + return FALSE; + } + a->destroy(a); + free(fuzzed.ptr); + } + + /* and decrement each byte of encoding */ + for (i = 0; i < encoding.len; i++) + { + if (i == 11 || i == 30 || i == 62) + { + continue; + } + fuzzed = chunk_clone(encoding); + fuzzed.ptr[i]--; + a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed); + if (test_id_equals_one(a, "C=CH, E=martin@strongswan.org, CN=martin")) + { + return FALSE; + } + a->destroy(a); + free(fuzzed.ptr); + } + free(encoding.ptr); + return TRUE; +} + +/******************************************************************************* + * identification matches test + ******************************************************************************/ + +static id_match_t test_id_matches_one(identification_t *a, char *b_str) +{ + identification_t *b; + id_match_t match; + + b = identification_create_from_string(b_str); + match = a->matches(a, b); + b->destroy(b); + return match; +} + +bool test_id_matches() +{ + identification_t *a; + + a = identification_create_from_string( + "C=CH, E=martin@strongswan.org, CN=martin"); + + if (test_id_matches_one(a, "C=CH, E=martin@strongswan.org, CN=martin") + != ID_MATCH_PERFECT) + { + return FALSE; + } + if (test_id_matches_one(a, "C=CH, E=*, CN=martin") != ID_MATCH_ONE_WILDCARD) + { + return FALSE; + } + if (test_id_matches_one(a, "C=CH, E=*, CN=*") != ID_MATCH_ONE_WILDCARD - 1) + { + return FALSE; + } + if (test_id_matches_one(a, "C=*, E=*, CN=*") != ID_MATCH_ONE_WILDCARD - 2) + { + return FALSE; + } + if (test_id_matches_one(a, "C=*, E=*, CN=*, O=BADInc") != ID_MATCH_NONE) + { + return FALSE; + } + if (test_id_matches_one(a, "C=*, E=*") != ID_MATCH_NONE) + { + return FALSE; + } + if (test_id_matches_one(a, "C=*, E=a@b.c, CN=*") != ID_MATCH_NONE) + { + return FALSE; + } + a->destroy(a); + return TRUE; +} diff --git a/src/charon/plugins/unit_tester/tests/test_mutex.c b/src/charon/plugins/unit_tester/tests/test_mutex.c index a305d5082..cb315276b 100644 --- a/src/charon/plugins/unit_tester/tests/test_mutex.c +++ b/src/charon/plugins/unit_tester/tests/test_mutex.c @@ -65,7 +65,7 @@ bool test_mutex() int i; pthread_t threads[THREADS]; - mutex = mutex_create(MUTEX_RECURSIVE); + mutex = mutex_create(MUTEX_TYPE_RECURSIVE); for (i = 0; i < 10; i++) { diff --git a/src/charon/plugins/updown/Makefile.am b/src/charon/plugins/updown/Makefile.am index de60d9fbf..fe6e0bb52 100644 --- a/src/charon/plugins/updown/Makefile.am +++ b/src/charon/plugins/updown/Makefile.am @@ -7,6 +7,6 @@ plugin_LTLIBRARIES = libstrongswan-updown.la libstrongswan_updown_la_SOURCES = \ updown_plugin.h updown_plugin.c \ updown_listener.h updown_listener.c -libstrongswan_updown_la_LDFLAGS = -module +libstrongswan_updown_la_LDFLAGS = -module -avoid-version diff --git a/src/charon/plugins/updown/Makefile.in b/src/charon/plugins/updown/Makefile.in index d0aac79f9..b1b6fb497 100644 --- a/src/charon/plugins/updown/Makefile.in +++ b/src/charon/plugins/updown/Makefile.in @@ -75,12 +75,14 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -145,6 +147,7 @@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ VERSION = @VERSION@ YACC = @YACC@ @@ -185,7 +188,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ @@ -226,7 +231,7 @@ libstrongswan_updown_la_SOURCES = \ updown_plugin.h updown_plugin.c \ updown_listener.h updown_listener.c -libstrongswan_updown_la_LDFLAGS = -module +libstrongswan_updown_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: diff --git a/src/charon/processing/jobs/callback_job.c b/src/charon/processing/jobs/callback_job.c index 82b4643eb..f4beb5abd 100644 --- a/src/charon/processing/jobs/callback_job.c +++ b/src/charon/processing/jobs/callback_job.c @@ -182,7 +182,7 @@ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data, this->public.cancel = (void(*)(callback_job_t*))cancel; /* private variables */ - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); this->callback = cb; this->data = data; this->cleanup = cleanup; diff --git a/src/charon/processing/processor.c b/src/charon/processing/processor.c index eb1db331b..4a3943323 100644 --- a/src/charon/processing/processor.c +++ b/src/charon/processing/processor.c @@ -240,9 +240,9 @@ processor_t *processor_create(size_t pool_size) this->public.destroy = (void(*)(processor_t*))destroy; this->list = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); - this->job_added = condvar_create(CONDVAR_DEFAULT); - this->thread_terminated = condvar_create(CONDVAR_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->job_added = condvar_create(CONDVAR_TYPE_DEFAULT); + this->thread_terminated = condvar_create(CONDVAR_TYPE_DEFAULT); this->total_threads = 0; this->desired_threads = 0; this->idle_threads = 0; diff --git a/src/charon/processing/scheduler.c b/src/charon/processing/scheduler.c index b3633f263..1f59205af 100644 --- a/src/charon/processing/scheduler.c +++ b/src/charon/processing/scheduler.c @@ -347,8 +347,8 @@ scheduler_t * scheduler_create() this->heap_size = HEAP_SIZE_DEFAULT; this->heap = (event_t**)calloc(this->heap_size + 1, sizeof(event_t*)); - this->mutex = mutex_create(MUTEX_DEFAULT); - this->condvar = condvar_create(CONDVAR_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT); this->job = callback_job_create((callback_job_cb_t)schedule, this, NULL, NULL); charon->processor->queue_job(charon->processor, (job_t*)this->job); diff --git a/src/charon/sa/authenticators/eap/eap_manager.c b/src/charon/sa/authenticators/eap/eap_manager.c index b8316036e..24a4fd6ed 100644 --- a/src/charon/sa/authenticators/eap/eap_manager.c +++ b/src/charon/sa/authenticators/eap/eap_manager.c @@ -163,7 +163,7 @@ eap_manager_t *eap_manager_create() this->public.destroy = (void(*)(eap_manager_t*))destroy; this->methods = linked_list_create(); - this->lock = rwlock_create(RWLOCK_DEFAULT); + this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); return &this->public; } diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c index 9202e972e..14d174ab5 100644 --- a/src/charon/sa/child_sa.c +++ b/src/charon/sa/child_sa.c @@ -136,6 +136,26 @@ struct private_child_sa_t { * config used to create this child */ child_cfg_t *config; + + /** + * time of last use in seconds (inbound) + */ + u_int32_t my_usetime; + + /** + * time of last use in seconds (outbound) + */ + u_int32_t other_usetime; + + /** + * last number of inbound bytes + */ + u_int64_t my_usebytes; + + /** + * last number of outbound bytes + */ + u_int64_t other_usebytes; }; /** @@ -355,20 +375,72 @@ static enumerator_t* create_policy_enumerator(private_child_sa_t *this) } /** - * Implementation of child_sa_t.get_usetime + * update the cached usebytes + * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs + * are available, and NOT_SUPPORTED if the kernel interface does not support + * querying the usebytes. + */ +static status_t update_usebytes(private_child_sa_t *this, bool inbound) +{ + status_t status = FAILED; + u_int64_t bytes; + + if (inbound) + { + if (this->my_spi) + { + status = charon->kernel_interface->query_sa( + charon->kernel_interface, + this->other_addr, this->my_addr, + this->my_spi, this->protocol, &bytes); + if (status == SUCCESS) + { + if (bytes > this->my_usebytes) + { + this->my_usebytes = bytes; + return SUCCESS; + } + return FAILED; + } + } + } + else + { + if (this->other_spi) + { + status = charon->kernel_interface->query_sa( + charon->kernel_interface, + this->my_addr, this->other_addr, + this->other_spi, this->protocol, &bytes); + if (status == SUCCESS) + { + if (bytes > this->other_usebytes) + { + this->other_usebytes = bytes; + return SUCCESS; + } + return FAILED; + } + } + } + return status; +} + +/** + * updates the cached usetime */ -static u_int32_t get_usetime(private_child_sa_t *this, bool inbound) +static void update_usetime(private_child_sa_t *this, bool inbound) { enumerator_t *enumerator; traffic_selector_t *my_ts, *other_ts; u_int32_t last_use = 0; - + enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { u_int32_t in, out, fwd; - if (inbound) + if (inbound) { if (charon->kernel_interface->query_policy(charon->kernel_interface, other_ts, my_ts, POLICY_IN, &in) == SUCCESS) @@ -394,7 +466,42 @@ static u_int32_t get_usetime(private_child_sa_t *this, bool inbound) } } enumerator->destroy(enumerator); - return last_use; + + if (last_use == 0) + { + return; + } + if (inbound) + { + this->my_usetime = last_use; + } + else + { + this->other_usetime = last_use; + } +} + +/** + * Implementation of child_sa_t.get_usestats + */ +static void get_usestats(private_child_sa_t *this, bool inbound, + time_t *time, u_int64_t *bytes) +{ + if (update_usebytes(this, inbound) != FAILED) + { + /* there was traffic since last update or the kernel interface + * does not support querying the number of usebytes. + */ + update_usetime(this, inbound); + } + if (time) + { + *time = inbound ? this->my_usetime : this->other_usetime; + } + if (bytes) + { + *bytes = inbound ? this->my_usebytes : this->other_usebytes; + } } /** @@ -566,13 +673,13 @@ static status_t add_policies(private_child_sa_t *this, * Implementation of child_sa_t.update. */ static status_t update(private_child_sa_t *this, host_t *me, host_t *other, - host_t *vip, bool encap) + host_t *vip, bool encap) { child_sa_state_t old; bool transport_proxy_mode; /* anything changed at all? */ - if (me->equals(me, this->my_addr) && + if (me->equals(me, this->my_addr) && other->equals(other, this->other_addr) && this->encap == encap) { return SUCCESS; @@ -661,7 +768,7 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other, me, other, my_ts, other_ts, POLICY_OUT, this->other_spi, this->protocol, this->reqid, this->mode, this->ipcomp, this->other_cpi, FALSE); - charon->kernel_interface->add_policy(charon->kernel_interface, + charon->kernel_interface->add_policy(charon->kernel_interface, other, me, other_ts, my_ts, POLICY_IN, this->my_spi, this->protocol, this->reqid, this->mode, this->ipcomp, this->my_cpi, FALSE); @@ -775,7 +882,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, this->public.get_proposal = (proposal_t*(*)(child_sa_t*))get_proposal; this->public.set_proposal = (void(*)(child_sa_t*, proposal_t *proposal))set_proposal; this->public.get_lifetime = (u_int32_t(*)(child_sa_t*, bool))get_lifetime; - this->public.get_usetime = (u_int32_t(*)(child_sa_t*, bool))get_usetime; + this->public.get_usestats = (void(*)(child_sa_t*,bool,time_t*,u_int64_t*))get_usestats; this->public.has_encap = (bool(*)(child_sa_t*))has_encap; this->public.get_ipcomp = (ipcomp_transform_t(*)(child_sa_t*))get_ipcomp; this->public.set_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t))set_ipcomp; @@ -798,6 +905,10 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, this->encap = encap; this->ipcomp = IPCOMP_NONE; this->state = CHILD_CREATED; + this->my_usetime = 0; + this->other_usetime = 0; + this->my_usebytes = 0; + this->other_usebytes = 0; /* reuse old reqid if we are rekeying an existing CHILD_SA */ this->reqid = rekey ? rekey : ++reqid; this->my_ts = linked_list_create(); @@ -810,7 +921,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, this->config = config; config->get_ref(config); - /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */ + /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */ if (config->get_mode(config) == MODE_TRANSPORT && config->use_proxy_mode(config)) { @@ -837,7 +948,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, host = host_create_from_chunk(family, addr, 0); free(addr.ptr); DBG1(DBG_CHD, "my address: %H is a transport mode proxy for %H", - this->my_addr, host); + this->my_addr, host); this->my_addr->destroy(this->my_addr); this->my_addr = host; } @@ -858,7 +969,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, host = host_create_from_chunk(family, addr, 0); free(addr.ptr); DBG1(DBG_CHD, "other address: %H is a transport mode proxy for %H", - this->other_addr, host); + this->other_addr, host); this->other_addr->destroy(this->other_addr); this->other_addr = host; } diff --git a/src/charon/sa/child_sa.h b/src/charon/sa/child_sa.h index ec9b36dab..698da8bc7 100644 --- a/src/charon/sa/child_sa.h +++ b/src/charon/sa/child_sa.h @@ -85,11 +85,11 @@ extern enum_name_t *child_sa_state_names; /** * Represents an IPsec SAs between two hosts. - * + * * A child_sa_t contains two SAs. SAs for both * directions are managed in one child_sa_t object. Both * SAs and the policies have the same reqid. - * + * * The procedure for child sa setup is as follows: * - A gets SPIs for a all protocols in its proposals via child_sa_t.alloc * - A send the proposals with the allocated SPIs to B @@ -98,7 +98,7 @@ extern enum_name_t *child_sa_state_names; * - B calls child_sa_t.install for both, the allocated and received SPI * - B sends the proposal with the allocated SPI to A * - A calls child_sa_t.install for both, the allocated and recevied SPI - * + * * Once SAs are set up, policies can be added using add_policies. */ struct child_sa_t { @@ -112,7 +112,7 @@ struct child_sa_t { /** * Get the reqid of the CHILD SA. - * + * * Every CHILD_SA has a reqid. The kernel uses this ID to * identify it. * @@ -131,19 +131,19 @@ struct child_sa_t { * Get the state of the CHILD_SA. * * @return CHILD_SA state - */ + */ child_sa_state_t (*get_state) (child_sa_t *this); /** * Set the state of the CHILD_SA. * * @param state state to set on CHILD_SA - */ + */ void (*set_state) (child_sa_t *this, child_sa_state_t state); /** * Get the SPI of this CHILD_SA. - * + * * Set the boolean parameter inbound to TRUE to * get the SPI for which we receive packets, use * FALSE to get those we use for sending packets. @@ -155,7 +155,7 @@ struct child_sa_t { /** * Get the CPI of this CHILD_SA. - * + * * Set the boolean parameter inbound to TRUE to * get the CPI for which we receive packets, use * FALSE to get those we use for sending packets. @@ -202,7 +202,7 @@ struct child_sa_t { /** * Set the IPComp algorithm to use. - * + * * @param ipcomp the IPComp transform to use */ void (*set_ipcomp)(child_sa_t *this, ipcomp_transform_t ipcomp); @@ -219,7 +219,7 @@ struct child_sa_t { * * @param proposal selected proposal */ - void (*set_proposal)(child_sa_t *this, proposal_t *proposal); + void (*set_proposal)(child_sa_t *this, proposal_t *proposal); /** * Check if this CHILD_SA uses UDP encapsulation. @@ -237,19 +237,21 @@ struct child_sa_t { u_int32_t (*get_lifetime)(child_sa_t *this, bool hard); /** - * Get last use time of the CHILD_SA. + * Get last use time and the number of bytes processed. * - * @param inbound TRUE for inbound traffic, FALSE for outbound - * @return time of last use in seconds + * @param inbound TRUE for inbound traffic, FALSE for outbound + * @param[out] time time of last use in seconds (NULL to ignore) + * @param[out] bytes number of processed bytes (NULL to ignore) */ - u_int32_t (*get_usetime)(child_sa_t *this, bool inbound); + void (*get_usestats)(child_sa_t *this, bool inbound, time_t *time, + u_int64_t *bytes); /** * Get the traffic selectors list added for one side. * * @param local TRUE for own traffic selectors, FALSE for remote * @return list of traffic selectors - */ + */ linked_list_t* (*get_traffic_selectors) (child_sa_t *this, bool local); /** @@ -296,7 +298,7 @@ struct child_sa_t { * @param my_ts traffic selectors for local site * @param other_ts traffic selectors for remote site * @return SUCCESS or FAILED - */ + */ status_t (*add_policies)(child_sa_t *this, linked_list_t *my_ts_list, linked_list_t *other_ts_list); /** diff --git a/src/charon/sa/connect_manager.c b/src/charon/sa/connect_manager.c index a1b037de4..f26cf9405 100644 --- a/src/charon/sa/connect_manager.c +++ b/src/charon/sa/connect_manager.c @@ -1568,7 +1568,7 @@ connect_manager_t *connect_manager_create() this->checklists = linked_list_create(); this->initiated = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); return (connect_manager_t*)this; } diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index 6b7fa3582..be973a2ce 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -260,7 +260,7 @@ static time_t get_use_time(private_ike_sa_t* this, bool inbound) { enumerator_t *enumerator; child_sa_t *child_sa; - time_t use_time; + time_t use_time, current; if (inbound) { @@ -273,7 +273,8 @@ static time_t get_use_time(private_ike_sa_t* this, bool inbound) enumerator = this->child_sas->create_enumerator(this->child_sas); while (enumerator->enumerate(enumerator, &child_sa)) { - use_time = max(use_time, child_sa->get_usetime(child_sa, inbound)); + child_sa->get_usestats(child_sa, inbound, ¤t, NULL); + use_time = max(use_time, current); } enumerator->destroy(enumerator); @@ -1169,7 +1170,8 @@ static status_t initiate(private_ike_sa_t *this, #endif /* ME */ { /* normal IKE_SA with CHILD_SA */ - task = (task_t*)child_create_create(&this->public, child_cfg, tsi, tsr); + task = (task_t*)child_create_create(&this->public, child_cfg, FALSE, + tsi, tsr); child_cfg->destroy(child_cfg); if (reqid) { @@ -1747,6 +1749,7 @@ static status_t roam(private_ike_sa_t *this, bool address) { case IKE_CREATED: case IKE_DELETING: + case IKE_DESTROYING: case IKE_PASSIVE: return SUCCESS; default: @@ -1775,10 +1778,46 @@ static status_t roam(private_ike_sa_t *this, bool address) DBG2(DBG_IKE, "keeping connection path %H - %H", src, this->other_host); src->destroy(src); + set_condition(this, COND_STALE, FALSE); + return SUCCESS; + } + src->destroy(src); + + } + else + { + /* check if we find a route at all */ + enumerator_t *enumerator; + host_t *addr; + + src = charon->kernel_interface->get_source_addr(charon->kernel_interface, + this->other_host, NULL); + if (!src) + { + enumerator = this->additional_addresses->create_enumerator( + this->additional_addresses); + while (enumerator->enumerate(enumerator, &addr)) + { + DBG1(DBG_IKE, "looking for a route to %H ...", addr); + src = charon->kernel_interface->get_source_addr( + charon->kernel_interface, addr, NULL); + if (src) + { + break; + } + } + enumerator->destroy(enumerator); + } + if (!src) + { + DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred", + this->other_host); + set_condition(this, COND_STALE, TRUE); return SUCCESS; } src->destroy(src); } + set_condition(this, COND_STALE, FALSE); /* update addresses with mobike, if supported ... */ if (supports_extension(this, EXT_MOBIKE)) diff --git a/src/charon/sa/ike_sa.h b/src/charon/sa/ike_sa.h index b751bda0c..41d7a7976 100644 --- a/src/charon/sa/ike_sa.h +++ b/src/charon/sa/ike_sa.h @@ -127,6 +127,11 @@ enum ike_condition_t { * Local peer is the "original" IKE initiator. Unaffected from rekeying. */ COND_ORIGINAL_INITIATOR = (1<<6), + + /** + * IKE_SA is stale, the peer is currently unreachable (MOBIKE) + */ + COND_STALE = (1<<7), }; /** diff --git a/src/charon/sa/ike_sa_manager.c b/src/charon/sa/ike_sa_manager.c index efe7c228c..ec1a7f741 100644 --- a/src/charon/sa/ike_sa_manager.c +++ b/src/charon/sa/ike_sa_manager.c @@ -133,7 +133,7 @@ static entry_t *entry_create() entry_t *this = malloc_thing(entry_t); this->waiting_threads = 0; - this->condvar = condvar_create(CONDVAR_DEFAULT); + this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT); /* we set checkout flag when we really give it out */ this->checked_out = FALSE; @@ -1050,7 +1050,8 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this, enumerator_t *enumerator; entry_t *entry; ike_sa_t *ike_sa = NULL; - peer_cfg_t *current_cfg; + peer_cfg_t *current_peer; + ike_cfg_t *current_ike; u_int segment; if (!this->reuse_ikesa) @@ -1072,14 +1073,18 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this, continue; } - current_cfg = entry->ike_sa->get_peer_cfg(entry->ike_sa); - if (current_cfg && current_cfg->equals(current_cfg, peer_cfg)) + current_peer = entry->ike_sa->get_peer_cfg(entry->ike_sa); + if (current_peer && current_peer->equals(current_peer, peer_cfg)) { - DBG2(DBG_MGR, "found an existing IKE_SA with a '%s' config", - current_cfg->get_name(current_cfg)); - entry->checked_out = TRUE; - ike_sa = entry->ike_sa; - break; + current_ike = current_peer->get_ike_cfg(current_peer); + if (current_ike->equals(current_ike, peer_cfg->get_ike_cfg(peer_cfg))) + { + DBG2(DBG_MGR, "found an existing IKE_SA with a '%s' config", + current_peer->get_name(current_peer)); + entry->checked_out = TRUE; + ike_sa = entry->ike_sa; + break; + } } } enumerator->destroy(enumerator); @@ -1554,6 +1559,17 @@ static void flush(private_ike_sa_manager_t *this) while (enumerator->enumerate(enumerator, &entry, &segment)) { charon->bus->set_sa(charon->bus, entry->ike_sa); + /* as the delete never gets processed, fire down events */ + switch (entry->ike_sa->get_state(entry->ike_sa)) + { + case IKE_ESTABLISHED: + case IKE_REKEYING: + case IKE_DELETING: + charon->bus->ike_updown(charon->bus, entry->ike_sa, FALSE); + break; + default: + break; + } entry->ike_sa->delete(entry->ike_sa); } enumerator->destroy(enumerator); @@ -1695,7 +1711,7 @@ ike_sa_manager_t *ike_sa_manager_create() this->segments = (segment_t*)calloc(this->segment_count, sizeof(segment_t)); for (i = 0; i < this->segment_count; ++i) { - this->segments[i].mutex = mutex_create(MUTEX_RECURSIVE); + this->segments[i].mutex = mutex_create(MUTEX_TYPE_RECURSIVE); this->segments[i].count = 0; } @@ -1704,7 +1720,7 @@ ike_sa_manager_t *ike_sa_manager_create() this->half_open_segments = calloc(this->segment_count, sizeof(shareable_segment_t)); for (i = 0; i < this->segment_count; ++i) { - this->half_open_segments[i].lock = rwlock_create(RWLOCK_DEFAULT); + this->half_open_segments[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT); this->half_open_segments[i].count = 0; } @@ -1713,7 +1729,7 @@ ike_sa_manager_t *ike_sa_manager_create() this->connected_peers_segments = calloc(this->segment_count, sizeof(shareable_segment_t)); for (i = 0; i < this->segment_count; ++i) { - this->connected_peers_segments[i].lock = rwlock_create(RWLOCK_DEFAULT); + this->connected_peers_segments[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT); this->connected_peers_segments[i].count = 0; } diff --git a/src/charon/sa/keymat.c b/src/charon/sa/keymat.c index 117d260ba..46fb79587 100644 --- a/src/charon/sa/keymat.c +++ b/src/charon/sa/keymat.c @@ -419,6 +419,9 @@ static bool derive_child_keys(private_keymat_t *this, case ENCR_AES_CCM_ICV8: case ENCR_AES_CCM_ICV12: case ENCR_AES_CCM_ICV16: + case ENCR_CAMELLIA_CCM_ICV8: + case ENCR_CAMELLIA_CCM_ICV12: + case ENCR_CAMELLIA_CCM_ICV16: enc_size += 3; break; case ENCR_AES_GCM_ICV8: diff --git a/src/charon/sa/mediation_manager.c b/src/charon/sa/mediation_manager.c index 890e567c7..a69c00173 100644 --- a/src/charon/sa/mediation_manager.c +++ b/src/charon/sa/mediation_manager.c @@ -331,7 +331,7 @@ mediation_manager_t *mediation_manager_create() this->public.check_and_register = (ike_sa_id_t*(*)(mediation_manager_t*,identification_t*,identification_t*))check_and_register; this->peers = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); return (mediation_manager_t*)this; } diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c index 2cd9532eb..f33fcd6d4 100644 --- a/src/charon/sa/task_manager.c +++ b/src/charon/sa/task_manager.c @@ -220,6 +220,10 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id) { DBG1(DBG_IKE, "giving up after %d retransmits", this->initiating.retransmitted - 1); + if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING) + { + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + } return DESTROY_ME; } @@ -240,6 +244,7 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id) { DBG1(DBG_IKE, "giving up after %d path probings", this->initiating.retransmitted - 1); + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); return DESTROY_ME; } @@ -431,6 +436,12 @@ static status_t build_request(private_task_manager_t *this) break; case FAILED: default: + if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING) + { + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + } + /* FALL */ + case DESTROY_ME: /* critical failure, destroy IKE_SA */ iterator->destroy(iterator); message->destroy(message); @@ -451,6 +462,7 @@ static status_t build_request(private_task_manager_t *this) * close the SA */ message->destroy(message); flush(this); + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); return DESTROY_ME; } @@ -474,6 +486,7 @@ static status_t process_response(private_task_manager_t *this, DBG1(DBG_IKE, "received %N response, but expected %N", exchange_type_names, message->get_exchange_type(message), exchange_type_names, this->initiating.type); + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); return DESTROY_ME; } @@ -494,6 +507,9 @@ static status_t process_response(private_task_manager_t *this, break; case FAILED: default: + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + /* FALL */ + case DESTROY_ME: /* critical failure, destroy IKE_SA */ iterator->remove(iterator); iterator->destroy(iterator); @@ -604,6 +620,9 @@ static status_t build_response(private_task_manager_t *this, message_t *request) break; case FAILED: default: + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + /* FALL */ + case DESTROY_ME: /* destroy IKE_SA, but SEND response first */ delete = TRUE; break; @@ -631,6 +650,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request) message->destroy(message); if (status != SUCCESS) { + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); return DESTROY_ME; } @@ -678,7 +698,8 @@ static status_t process_request(private_task_manager_t *this, this->passive_tasks->insert_last(this->passive_tasks, task); task = (task_t*)ike_config_create(this->ike_sa, FALSE); this->passive_tasks->insert_last(this->passive_tasks, task); - task = (task_t*)child_create_create(this->ike_sa, NULL, NULL, NULL); + task = (task_t*)child_create_create(this->ike_sa, NULL, FALSE, + NULL, NULL); this->passive_tasks->insert_last(this->passive_tasks, task); task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE); this->passive_tasks->insert_last(this->passive_tasks, task); @@ -726,8 +747,8 @@ static status_t process_request(private_task_manager_t *this, } else { - task = (task_t*)child_create_create(this->ike_sa, - NULL, NULL, NULL); + task = (task_t*)child_create_create(this->ike_sa, NULL, + FALSE, NULL, NULL); } } else @@ -831,6 +852,9 @@ static status_t process_request(private_task_manager_t *this, break; case FAILED: default: + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + /* FALL */ + case DESTROY_ME: /* critical failure, destroy IKE_SA */ iterator->remove(iterator); iterator->destroy(iterator); diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c index f51443738..558938f2e 100644 --- a/src/charon/sa/tasks/child_create.c +++ b/src/charon/sa/tasks/child_create.c @@ -158,6 +158,11 @@ struct private_child_create_t { * successfully established the CHILD? */ bool established; + + /** + * whether the CHILD_SA rekeys an existing one + */ + bool rekey; }; /** @@ -249,7 +254,7 @@ static bool allocate_spi(private_child_create_t *this) */ static status_t select_and_install(private_child_create_t *this, bool no_dh) { - status_t status; + status_t status, status_i, status_o; chunk_t nonce_i, nonce_r; chunk_t encr_i = chunk_empty, encr_r = chunk_empty; chunk_t integ_i = chunk_empty, integ_r = chunk_empty; @@ -401,22 +406,22 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) this->my_cpi = this->other_cpi = 0; this->ipcomp = IPCOMP_NONE; } - status = FAILED; + status_i = status_o = FAILED; if (this->keymat->derive_child_keys(this->keymat, this->proposal, this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r)) { if (this->initiator) { - status = this->child_sa->install(this->child_sa, encr_r, integ_r, + status_i = this->child_sa->install(this->child_sa, encr_r, integ_r, this->my_spi, this->my_cpi, TRUE); - status = this->child_sa->install(this->child_sa, encr_i, integ_i, + status_o = this->child_sa->install(this->child_sa, encr_i, integ_i, this->other_spi, this->other_cpi, FALSE); } else { - status = this->child_sa->install(this->child_sa, encr_i, integ_i, + status_i = this->child_sa->install(this->child_sa, encr_i, integ_i, this->my_spi, this->my_cpi, TRUE); - status = this->child_sa->install(this->child_sa, encr_r, integ_r, + status_o = this->child_sa->install(this->child_sa, encr_r, integ_r, this->other_spi, this->other_cpi, FALSE); } } @@ -425,9 +430,12 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) chunk_clear(&encr_i); chunk_clear(&encr_r); - if (status != SUCCESS) + if (status_i != SUCCESS || status_o != SUCCESS) { - DBG1(DBG_IKE, "unable to install IPsec SA (SAD) in kernel"); + DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel", + (status_i != SUCCESS) ? "inbound " : "", + (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "", + (status_o != SUCCESS) ? "outbound " : ""); return FAILED; } @@ -939,7 +947,11 @@ static status_t build_r(private_child_create_t *this, message_t *message) ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), this->child_sa->get_traffic_selectors(this->child_sa, TRUE), this->child_sa->get_traffic_selectors(this->child_sa, FALSE)); - + + if (!this->rekey) + { /* invoke the child_up() hook if we are not rekeying */ + charon->bus->child_updown(charon->bus, this->child_sa, TRUE); + } return SUCCESS; } @@ -1052,6 +1064,11 @@ static status_t process_i(private_child_create_t *this, message_t *message) ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), this->child_sa->get_traffic_selectors(this->child_sa, TRUE), this->child_sa->get_traffic_selectors(this->child_sa, FALSE)); + + if (!this->rekey) + { /* invoke the child_up() hook if we are not rekeying */ + charon->bus->child_updown(charon->bus, this->child_sa, TRUE); + } } else { @@ -1174,7 +1191,8 @@ static void destroy(private_child_create_t *this) /* * Described in header. */ -child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config, +child_create_t *child_create_create(ike_sa_t *ike_sa, + child_cfg_t *config, bool rekey, traffic_selector_t *tsi, traffic_selector_t *tsr) { private_child_create_t *this = malloc_thing(private_child_create_t); @@ -1222,6 +1240,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config, this->other_cpi = 0; this->reqid = 0; this->established = FALSE; + this->rekey = rekey; return &this->public; } diff --git a/src/charon/sa/tasks/child_create.h b/src/charon/sa/tasks/child_create.h index ce2829a9a..41f4fe2c8 100644 --- a/src/charon/sa/tasks/child_create.h +++ b/src/charon/sa/tasks/child_create.h @@ -71,11 +71,13 @@ struct child_create_t { * * @param ike_sa IKE_SA this task works for * @param config child_cfg if task initiator, NULL if responder + * @param rekey whether we do a rekey or not * @param tsi source of triggering packet, or NULL * @param tsr destination of triggering packet, or NULL * @return child_create task to handle by the task_manager */ -child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config, +child_create_t *child_create_create(ike_sa_t *ike_sa, + child_cfg_t *config, bool rekey, traffic_selector_t *tsi, traffic_selector_t *tsr); #endif /** CHILD_CREATE_H_ @}*/ diff --git a/src/charon/sa/tasks/child_delete.c b/src/charon/sa/tasks/child_delete.c index 0d89c148e..7abb07a84 100644 --- a/src/charon/sa/tasks/child_delete.c +++ b/src/charon/sa/tasks/child_delete.c @@ -52,11 +52,16 @@ struct private_child_delete_t { u_int32_t spi; /** - * wheter to enforce delete action policy + * whether to enforce delete action policy */ bool check_delete_action; /** + * is this delete exchange following a rekey? + */ + bool rekeyed; + + /** * CHILD_SAs which get deleted */ linked_list_t *child_sas; @@ -148,6 +153,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message) switch (child_sa->get_state(child_sa)) { case CHILD_REKEYING: + this->rekeyed = TRUE; /* we reply as usual, rekeying will fail */ break; case CHILD_DELETING: @@ -190,6 +196,11 @@ static status_t destroy_and_reestablish(private_child_delete_t *this) iterator = this->child_sas->create_iterator(this->child_sas, TRUE); while (iterator->iterate(iterator, (void**)&child_sa)) { + /* signal child down event if we are not rekeying */ + if (!this->rekeyed) + { + charon->bus->child_updown(charon->bus, child_sa, FALSE); + } spi = child_sa->get_spi(child_sa, TRUE); protocol = child_sa->get_protocol(child_sa); child_cfg = child_sa->get_config(child_sa); @@ -229,15 +240,19 @@ static void log_children(private_child_delete_t *this) { iterator_t *iterator; child_sa_t *child_sa; + u_int64_t bytes_in, bytes_out; iterator = this->child_sas->create_iterator(this->child_sas, TRUE); while (iterator->iterate(iterator, (void**)&child_sa)) { + child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in); + child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out); + DBG0(DBG_IKE, "closing CHILD_SA %s{%d} " - "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", + "with SPIs %.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R", child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), - ntohl(child_sa->get_spi(child_sa, TRUE)), - ntohl(child_sa->get_spi(child_sa, FALSE)), + ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in, + ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out, child_sa->get_traffic_selectors(child_sa, TRUE), child_sa->get_traffic_selectors(child_sa, FALSE)); } @@ -258,7 +273,10 @@ static status_t build_i(private_child_delete_t *this, message_t *message) return SUCCESS; } this->child_sas->insert_last(this->child_sas, child_sa); - + if (child_sa->get_state(child_sa) == CHILD_REKEYING) + { + this->rekeyed = TRUE; + } log_children(this); build_payloads(this, message); return NEED_MORE; @@ -359,6 +377,7 @@ child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol, this->child_sas = linked_list_create(); this->protocol = protocol; this->spi = spi; + this->rekeyed = FALSE; if (protocol != PROTO_NONE) { diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c index 6ab00dc5b..601e054ea 100644 --- a/src/charon/sa/tasks/child_rekey.c +++ b/src/charon/sa/tasks/child_rekey.c @@ -157,7 +157,8 @@ static status_t build_i(private_child_rekey_t *this, message_t *message) /* ... our CHILD_CREATE task does the hard work for us. */ reqid = this->child_sa->get_reqid(this->child_sa); - this->child_create = child_create_create(this->ike_sa, config, NULL, NULL); + this->child_create = child_create_create(this->ike_sa, config, TRUE, + NULL, NULL); this->child_create->use_reqid(this->child_create, reqid); this->child_create->task.build(&this->child_create->task, message); @@ -207,6 +208,10 @@ static status_t build_r(private_child_rekey_t *this, message_t *message) } this->child_sa->set_state(this->child_sa, CHILD_REKEYING); + + /* invoke rekey hook */ + charon->bus->child_rekey(charon->bus, this->child_sa, + this->child_create->get_child(this->child_create)); return SUCCESS; } @@ -303,6 +308,12 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) } } + if (to_delete != this->child_create->get_child(this->child_create)) + { /* invoke rekey hook if rekeying successful */ + charon->bus->child_rekey(charon->bus, this->child_sa, + this->child_create->get_child(this->child_create)); + } + spi = to_delete->get_spi(to_delete, TRUE); protocol = to_delete->get_protocol(to_delete); @@ -416,7 +427,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol, this->public.task.build = (status_t(*)(task_t*,message_t*))build_r; this->public.task.process = (status_t(*)(task_t*,message_t*))process_r; this->initiator = FALSE; - this->child_create = child_create_create(ike_sa, NULL, NULL, NULL); + this->child_create = child_create_create(ike_sa, NULL, TRUE, NULL, NULL); } this->ike_sa = ike_sa; diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c index 8d6cd56bd..d0b2a7e91 100644 --- a/src/charon/sa/tasks/ike_auth.c +++ b/src/charon/sa/tasks/ike_auth.c @@ -738,6 +738,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) this->ike_sa->get_my_id(this->ike_sa), this->ike_sa->get_other_host(this->ike_sa), this->ike_sa->get_other_id(this->ike_sa)); + charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE); return SUCCESS; } return NEED_MORE; @@ -916,6 +917,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) this->ike_sa->get_my_id(this->ike_sa), this->ike_sa->get_other_host(this->ike_sa), this->ike_sa->get_other_id(this->ike_sa)); + charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE); return SUCCESS; } return NEED_MORE; diff --git a/src/charon/sa/tasks/ike_delete.c b/src/charon/sa/tasks/ike_delete.c index f308a6358..cde117934 100644 --- a/src/charon/sa/tasks/ike_delete.c +++ b/src/charon/sa/tasks/ike_delete.c @@ -21,7 +21,7 @@ typedef struct private_ike_delete_t private_ike_delete_t; -/**file +/** * Private members of a ike_delete_t task. */ struct private_ike_delete_t { @@ -42,6 +42,11 @@ struct private_ike_delete_t { bool initiator; /** + * are we deleting a rekeyed SA? + */ + bool rekeyed; + + /** * are we responding to a delete, but have initated our own? */ bool simultaneous; @@ -64,6 +69,11 @@ static status_t build_i(private_ike_delete_t *this, message_t *message) delete_payload = delete_payload_create(PROTO_IKE); message->add_payload(message, (payload_t*)delete_payload); + + if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING) + { + this->rekeyed = TRUE; + } this->ike_sa->set_state(this->ike_sa, IKE_DELETING); DBG1(DBG_IKE, "sending DELETE for IKE_SA %s[%d]", @@ -79,8 +89,12 @@ static status_t build_i(private_ike_delete_t *this, message_t *message) static status_t process_i(private_ike_delete_t *this, message_t *message) { DBG0(DBG_IKE, "IKE_SA deleted"); - /* completed, delete IKE_SA by returning FAILED */ - return FAILED; + if (!this->rekeyed) + { /* invoke ike_down() hook if SA has not been rekeyed */ + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + } + /* completed, delete IKE_SA by returning DESTROY_ME */ + return DESTROY_ME; } /** @@ -106,14 +120,17 @@ static status_t process_r(private_ike_delete_t *this, message_t *message) case IKE_ESTABLISHED: this->ike_sa->set_state(this->ike_sa, IKE_DELETING); this->ike_sa->reestablish(this->ike_sa); + return NEED_MORE; + case IKE_REKEYING: + this->rekeyed = TRUE; break; case IKE_DELETING: this->simultaneous = TRUE; - /* FALL */ + break; default: - this->ike_sa->set_state(this->ike_sa, IKE_DELETING); break; } + this->ike_sa->set_state(this->ike_sa, IKE_DELETING); return NEED_MORE; } @@ -129,8 +146,12 @@ static status_t build_r(private_ike_delete_t *this, message_t *message) /* wait for peer's response for our delete request, but set a timeout */ return SUCCESS; } - /* completed, delete IKE_SA by returning FAILED */ - return FAILED; + if (!this->rekeyed) + { /* invoke ike_down() hook if SA has not been rekeyed */ + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + } + /* completed, delete IKE_SA by returning DESTROY_ME */ + return DESTROY_ME; } /** @@ -182,6 +203,7 @@ ike_delete_t *ike_delete_create(ike_sa_t *ike_sa, bool initiator) this->ike_sa = ike_sa; this->initiator = initiator; + this->rekeyed = FALSE; this->simultaneous = FALSE; return &this->public; diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c index bead408a6..3a049b566 100644 --- a/src/charon/sa/tasks/ike_rekey.c +++ b/src/charon/sa/tasks/ike_rekey.c @@ -367,6 +367,8 @@ static void destroy(private_ike_rekey_t *this) if (this->new_sa->get_state(this->new_sa) == IKE_ESTABLISHED && this->new_sa->inherit(this->new_sa, this->ike_sa) != DESTROY_ME) { + /* invoke hook if rekeying was successful */ + charon->bus->ike_rekey(charon->bus, this->ike_sa, this->new_sa); charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa); } else diff --git a/src/charon/sa/tasks/task.h b/src/charon/sa/tasks/task.h index f9b409f35..3d2014599 100644 --- a/src/charon/sa/tasks/task.h +++ b/src/charon/sa/tasks/task.h @@ -100,7 +100,8 @@ struct task_t { * * @param message message to add payloads to * @return - * - FAILED if a critical error occured + * - FAILED if a critical error occured + * - DESTROY_ME if IKE_SA has been properly deleted * - NEED_MORE if another call to build/process needed * - SUCCESS if task completed */ @@ -112,6 +113,7 @@ struct task_t { * @param message message to read payloads from * @return * - FAILED if a critical error occured + * - DESTROY_ME if IKE_SA has been properly deleted * - NEED_MORE if another call to build/process needed * - SUCCESS if task completed */ diff --git a/src/charon/sa/trap_manager.c b/src/charon/sa/trap_manager.c index a74fab93f..570335eb4 100644 --- a/src/charon/sa/trap_manager.c +++ b/src/charon/sa/trap_manager.c @@ -156,6 +156,10 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer, me->destroy(me); other->destroy(other); + /* while we don't know the finally negotiated protocol (ESP|AH), we + * could iterate all proposals for a best guest (TODO). But as we + * support ESP only for now, we set here. */ + child_sa->set_protocol(child_sa, PROTO_ESP); child_sa->set_mode(child_sa, child->get_mode(child)); status = child_sa->add_policies(child_sa, my_ts, other_ts); my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); @@ -358,7 +362,7 @@ trap_manager_t *trap_manager_create() this->public.destroy = (void(*)(trap_manager_t*))destroy; this->traps = linked_list_create(); - this->lock = rwlock_create(RWLOCK_DEFAULT); + this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); /* register listener for IKE state changes */ this->listener.traps = this; |