diff options
Diffstat (limited to 'src/libcharon')
393 files changed, 17177 insertions, 9486 deletions
diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk index 90e2bdc6a..f98d36a61 100644 --- a/src/libcharon/Android.mk +++ b/src/libcharon/Android.mk @@ -41,10 +41,9 @@ encoding/payloads/ts_payload.c encoding/payloads/ts_payload.h \ encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \ encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \ kernel/kernel_handler.c kernel/kernel_handler.h \ -network/packet.c network/packet.h \ -network/receiver.c network/receiver.h \ -network/sender.c network/sender.h \ -network/socket_manager.c network/socket_manager.h network/socket.h \ +network/receiver.c network/receiver.h network/sender.c network/sender.h \ +network/packet.c network/packet.h network/socket.c network/socket.h \ +network/socket_manager.c network/socket_manager.h \ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \ processing/jobs/delete_child_sa_job.c processing/jobs/delete_child_sa_job.h \ processing/jobs/delete_ike_sa_job.c processing/jobs/delete_ike_sa_job.h \ @@ -63,9 +62,6 @@ sa/authenticators/authenticator.c sa/authenticators/authenticator.h \ sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \ sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \ sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \ -sa/authenticators/eap/sim_manager.c sa/authenticators/eap/sim_manager.h \ -sa/authenticators/eap/sim_card.h sa/authenticators/eap/sim_provider.h \ -sa/authenticators/eap/sim_hooks.h \ sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \ sa/authenticators/pubkey_authenticator.c sa/authenticators/pubkey_authenticator.h \ sa/child_sa.c sa/child_sa.h \ @@ -74,6 +70,7 @@ sa/ike_sa_id.c sa/ike_sa_id.h \ sa/ike_sa_manager.c sa/ike_sa_manager.h \ sa/task_manager.c sa/task_manager.h \ sa/keymat.c sa/keymat.h \ +sa/shunt_manager.c sa/shunt_manager.h \ sa/trap_manager.c sa/trap_manager.h \ sa/tasks/child_create.c sa/tasks/child_create.h \ sa/tasks/child_delete.c sa/tasks/child_delete.h \ @@ -91,13 +88,7 @@ sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \ sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \ sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \ sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \ -sa/tasks/task.c sa/tasks/task.h \ -tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h tnc/tncifimv.c \ -tnc/imc/imc.h tnc/imc/imc_manager.h \ -tnc/imv/imv.h tnc/imv/imv_manager.h \ -tnc/imv/imv_recommendations.c tnc/imv/imv_recommendations.h \ -tnc/tnccs/tnccs.c tnc/tnccs/tnccs.h \ -tnc/tnccs/tnccs_manager.c tnc/tnccs/tnccs_manager.h +sa/tasks/task.c sa/tasks/task.h # adding the plugin source files @@ -141,6 +132,8 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libsimaka/ LOCAL_SRC_FILES += $(addprefix ../libsimaka/, \ simaka_message.h simaka_message.c \ simaka_crypto.h simaka_crypto.c \ + simaka_manager.h simaka_manager.c \ + simaka_card.h simaka_provider.h simaka_hooks.h \ ) endif @@ -150,18 +143,30 @@ LOCAL_SRC_FILES += $(call add_plugin, socket-default) LOCAL_SRC_FILES += $(call add_plugin, socket-dynamic) +LOCAL_SRC_FILES += $(call add_plugin, socket-raw) + +LOCAL_SRC_FILES += $(call add_plugin, stroke) +ifneq ($(call plugin_enabled, stroke),) +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../stroke/ +endif + + # build libcharon -------------------------------------------------------------- LOCAL_C_INCLUDES += \ $(libvstr_PATH) \ $(strongswan_PATH)/src/include \ $(strongswan_PATH)/src/libhydra \ - $(strongswan_PATH)/src/libstrongswan + $(strongswan_PATH)/src/libstrongswan \ + $(strongswan_PATH)/src/libtncif -LOCAL_CFLAGS := $(strongswan_CFLAGS) +LOCAL_CFLAGS := $(strongswan_CFLAGS) \ + -DPLUGINS='"$(strongswan_CHARON_PLUGINS)"' LOCAL_MODULE := libcharon +LOCAL_MODULE_TAGS := optional + LOCAL_ARM_MODE := arm LOCAL_PRELINK_MODULE := false diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index 9a4b28c3a..b86bd428c 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -1,4 +1,4 @@ -lib_LTLIBRARIES = libcharon.la +ipseclib_LTLIBRARIES = libcharon.la libcharon_la_SOURCES = \ bus/bus.c bus/bus.h \ @@ -39,10 +39,9 @@ encoding/payloads/ts_payload.c encoding/payloads/ts_payload.h \ encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \ encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \ kernel/kernel_handler.c kernel/kernel_handler.h \ -network/packet.c network/packet.h \ -network/receiver.c network/receiver.h \ -network/sender.c network/sender.h \ -network/socket_manager.c network/socket_manager.h network/socket.h \ +network/receiver.c network/receiver.h network/sender.c network/sender.h \ +network/packet.c network/packet.h network/socket.c network/socket.h \ +network/socket_manager.c network/socket_manager.h \ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \ processing/jobs/delete_child_sa_job.c processing/jobs/delete_child_sa_job.h \ processing/jobs/delete_ike_sa_job.c processing/jobs/delete_ike_sa_job.h \ @@ -61,9 +60,6 @@ sa/authenticators/authenticator.c sa/authenticators/authenticator.h \ sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \ sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \ sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \ -sa/authenticators/eap/sim_manager.c sa/authenticators/eap/sim_manager.h \ -sa/authenticators/eap/sim_card.h sa/authenticators/eap/sim_provider.h \ -sa/authenticators/eap/sim_hooks.h \ sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \ sa/authenticators/pubkey_authenticator.c sa/authenticators/pubkey_authenticator.h \ sa/child_sa.c sa/child_sa.h \ @@ -72,6 +68,7 @@ sa/ike_sa_id.c sa/ike_sa_id.h \ sa/ike_sa_manager.c sa/ike_sa_manager.h \ sa/task_manager.c sa/task_manager.h \ sa/keymat.c sa/keymat.h \ +sa/shunt_manager.c sa/shunt_manager.h \ sa/trap_manager.c sa/trap_manager.h \ sa/tasks/child_create.c sa/tasks/child_create.h \ sa/tasks/child_delete.c sa/tasks/child_delete.h \ @@ -89,13 +86,7 @@ sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \ sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \ sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \ sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \ -sa/tasks/task.c sa/tasks/task.h \ -tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h tnc/tncifimv.c \ -tnc/imc/imc.h tnc/imc/imc_manager.h \ -tnc/imv/imv.h tnc/imv/imv_manager.h \ -tnc/imv/imv_recommendations.c tnc/imv/imv_recommendations.h \ -tnc/tnccs/tnccs.c tnc/tnccs/tnccs.h \ -tnc/tnccs/tnccs_manager.c tnc/tnccs/tnccs_manager.h +sa/tasks/task.c sa/tasks/task.h daemon.lo : $(top_builddir)/config.status @@ -335,6 +326,27 @@ if MONOLITHIC endif endif +if USE_RADIUS +if MONOLITHIC + # otherwise this library is linked to eap_radius + libcharon_la_LIBADD += $(top_builddir)/src/libradius/libradius.la +endif +endif + +if USE_TNC_IFMAP + SUBDIRS += plugins/tnc_ifmap +if MONOLITHIC + libcharon_la_LIBADD += plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la +endif +endif + +if USE_TNC_PDP + SUBDIRS += plugins/tnc_pdp +if MONOLITHIC + libcharon_la_LIBADD += plugins/tnc_pdp/libstrongswan-tnc-pdp.la +endif +endif + if USE_TNC_IMC SUBDIRS += plugins/tnc_imc if MONOLITHIC @@ -349,6 +361,13 @@ if MONOLITHIC endif endif +if USE_TNC_TNCCS + SUBDIRS += plugins/tnc_tnccs +if MONOLITHIC + libcharon_la_LIBADD += plugins/tnc_tnccs/libstrongswan-tnc-tnccs.la +endif +endif + if USE_TNCCS_11 SUBDIRS += plugins/tnccs_11 if MONOLITHIC @@ -370,6 +389,13 @@ if MONOLITHIC endif endif +if USE_LIBTNCCS +if MONOLITHIC + # otherwise this library is linked to the respective plugins + libcharon_la_LIBADD += $(top_builddir)/src/libtnccs/libtnccs.la +endif +endif + if USE_MEDSRV SUBDIRS += plugins/medsrv if MONOLITHIC @@ -426,6 +452,13 @@ if MONOLITHIC endif endif +if USE_CERTEXPIRE + SUBDIRS += plugins/certexpire +if MONOLITHIC + libcharon_la_LIBADD += plugins/certexpire/libstrongswan-certexpire.la +endif +endif + if USE_LED SUBDIRS += plugins/led if MONOLITHIC @@ -447,6 +480,13 @@ if MONOLITHIC endif endif +if USE_RADATTR + SUBDIRS += plugins/radattr +if MONOLITHIC + libcharon_la_LIBADD += plugins/radattr/libstrongswan-radattr.la +endif +endif + if USE_UCI SUBDIRS += plugins/uci if MONOLITHIC diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in index 70385f306..ccbd4add2 100644 --- a/src/libcharon/Makefile.in +++ b/src/libcharon/Makefile.in @@ -99,44 +99,56 @@ host_triplet = @host@ @USE_EAP_TNC_TRUE@am__append_54 = plugins/eap_tnc @MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_55 = plugins/eap_tnc/libstrongswan-eap-tnc.la @MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_56 = $(top_builddir)/src/libtls/libtls.la -@USE_TNC_IMC_TRUE@am__append_57 = plugins/tnc_imc -@MONOLITHIC_TRUE@@USE_TNC_IMC_TRUE@am__append_58 = plugins/tnc_imc/libstrongswan-tnc-imc.la -@USE_TNC_IMV_TRUE@am__append_59 = plugins/tnc_imv -@MONOLITHIC_TRUE@@USE_TNC_IMV_TRUE@am__append_60 = plugins/tnc_imv/libstrongswan-tnc-imv.la -@USE_TNCCS_11_TRUE@am__append_61 = plugins/tnccs_11 -@MONOLITHIC_TRUE@@USE_TNCCS_11_TRUE@am__append_62 = plugins/tnccs_11/libstrongswan-tnccs-11.la -@USE_TNCCS_20_TRUE@am__append_63 = plugins/tnccs_20 -@MONOLITHIC_TRUE@@USE_TNCCS_20_TRUE@am__append_64 = plugins/tnccs_20/libstrongswan-tnccs-20.la -@USE_TNCCS_DYNAMIC_TRUE@am__append_65 = plugins/tnccs_dynamic -@MONOLITHIC_TRUE@@USE_TNCCS_DYNAMIC_TRUE@am__append_66 = plugins/tnccs_dynamic/libstrongswan-tnccs-dynamic.la -@USE_MEDSRV_TRUE@am__append_67 = plugins/medsrv -@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_68 = plugins/medsrv/libstrongswan-medsrv.la -@USE_MEDCLI_TRUE@am__append_69 = plugins/medcli -@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_70 = plugins/medcli/libstrongswan-medcli.la -@USE_NM_TRUE@am__append_71 = plugins/nm -@MONOLITHIC_TRUE@@USE_NM_TRUE@am__append_72 = plugins/nm/libstrongswan-nm.la -@USE_DHCP_TRUE@am__append_73 = plugins/dhcp -@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_74 = plugins/dhcp/libstrongswan-dhcp.la -@USE_ANDROID_TRUE@am__append_75 = plugins/android -@MONOLITHIC_TRUE@@USE_ANDROID_TRUE@am__append_76 = plugins/android/libstrongswan-android.la -@USE_MAEMO_TRUE@am__append_77 = plugins/maemo -@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_78 = plugins/maemo/libstrongswan-maemo.la -@USE_HA_TRUE@am__append_79 = plugins/ha -@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_80 = plugins/ha/libstrongswan-ha.la -@USE_WHITELIST_TRUE@am__append_81 = plugins/whitelist -@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_82 = plugins/whitelist/libstrongswan-whitelist.la -@USE_LED_TRUE@am__append_83 = plugins/led -@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_84 = plugins/led/libstrongswan-led.la -@USE_DUPLICHECK_TRUE@am__append_85 = plugins/duplicheck -@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_86 = plugins/duplicheck/libstrongswan-duplicheck.la -@USE_COUPLING_TRUE@am__append_87 = plugins/coupling -@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_88 = plugins/coupling/libstrongswan-coupling.la -@USE_UCI_TRUE@am__append_89 = plugins/uci -@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_90 = plugins/uci/libstrongswan-uci.la -@USE_ADDRBLOCK_TRUE@am__append_91 = plugins/addrblock -@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_92 = plugins/uci/libstrongswan-addrblock.la -@USE_UNIT_TESTS_TRUE@am__append_93 = plugins/unit_tester -@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_94 = plugins/unit_tester/libstrongswan-unit-tester.la +@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@am__append_57 = $(top_builddir)/src/libradius/libradius.la +@USE_TNC_IFMAP_TRUE@am__append_58 = plugins/tnc_ifmap +@MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE@am__append_59 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la +@USE_TNC_PDP_TRUE@am__append_60 = plugins/tnc_pdp +@MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE@am__append_61 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la +@USE_TNC_IMC_TRUE@am__append_62 = plugins/tnc_imc +@MONOLITHIC_TRUE@@USE_TNC_IMC_TRUE@am__append_63 = plugins/tnc_imc/libstrongswan-tnc-imc.la +@USE_TNC_IMV_TRUE@am__append_64 = plugins/tnc_imv +@MONOLITHIC_TRUE@@USE_TNC_IMV_TRUE@am__append_65 = plugins/tnc_imv/libstrongswan-tnc-imv.la +@USE_TNC_TNCCS_TRUE@am__append_66 = plugins/tnc_tnccs +@MONOLITHIC_TRUE@@USE_TNC_TNCCS_TRUE@am__append_67 = plugins/tnc_tnccs/libstrongswan-tnc-tnccs.la +@USE_TNCCS_11_TRUE@am__append_68 = plugins/tnccs_11 +@MONOLITHIC_TRUE@@USE_TNCCS_11_TRUE@am__append_69 = plugins/tnccs_11/libstrongswan-tnccs-11.la +@USE_TNCCS_20_TRUE@am__append_70 = plugins/tnccs_20 +@MONOLITHIC_TRUE@@USE_TNCCS_20_TRUE@am__append_71 = plugins/tnccs_20/libstrongswan-tnccs-20.la +@USE_TNCCS_DYNAMIC_TRUE@am__append_72 = plugins/tnccs_dynamic +@MONOLITHIC_TRUE@@USE_TNCCS_DYNAMIC_TRUE@am__append_73 = plugins/tnccs_dynamic/libstrongswan-tnccs-dynamic.la +@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@am__append_74 = $(top_builddir)/src/libtnccs/libtnccs.la +@USE_MEDSRV_TRUE@am__append_75 = plugins/medsrv +@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_76 = plugins/medsrv/libstrongswan-medsrv.la +@USE_MEDCLI_TRUE@am__append_77 = plugins/medcli +@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_78 = plugins/medcli/libstrongswan-medcli.la +@USE_NM_TRUE@am__append_79 = plugins/nm +@MONOLITHIC_TRUE@@USE_NM_TRUE@am__append_80 = plugins/nm/libstrongswan-nm.la +@USE_DHCP_TRUE@am__append_81 = plugins/dhcp +@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_82 = plugins/dhcp/libstrongswan-dhcp.la +@USE_ANDROID_TRUE@am__append_83 = plugins/android +@MONOLITHIC_TRUE@@USE_ANDROID_TRUE@am__append_84 = plugins/android/libstrongswan-android.la +@USE_MAEMO_TRUE@am__append_85 = plugins/maemo +@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_86 = plugins/maemo/libstrongswan-maemo.la +@USE_HA_TRUE@am__append_87 = plugins/ha +@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_88 = plugins/ha/libstrongswan-ha.la +@USE_WHITELIST_TRUE@am__append_89 = plugins/whitelist +@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_90 = plugins/whitelist/libstrongswan-whitelist.la +@USE_CERTEXPIRE_TRUE@am__append_91 = plugins/certexpire +@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_92 = plugins/certexpire/libstrongswan-certexpire.la +@USE_LED_TRUE@am__append_93 = plugins/led +@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_94 = plugins/led/libstrongswan-led.la +@USE_DUPLICHECK_TRUE@am__append_95 = plugins/duplicheck +@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_96 = plugins/duplicheck/libstrongswan-duplicheck.la +@USE_COUPLING_TRUE@am__append_97 = plugins/coupling +@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_98 = plugins/coupling/libstrongswan-coupling.la +@USE_RADATTR_TRUE@am__append_99 = plugins/radattr +@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_100 = plugins/radattr/libstrongswan-radattr.la +@USE_UCI_TRUE@am__append_101 = plugins/uci +@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_102 = plugins/uci/libstrongswan-uci.la +@USE_ADDRBLOCK_TRUE@am__append_103 = plugins/addrblock +@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_104 = plugins/uci/libstrongswan-addrblock.la +@USE_UNIT_TESTS_TRUE@am__append_105 = plugins/unit_tester +@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_106 = plugins/unit_tester/libstrongswan-unit-tester.la subdir = src/libcharon DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -175,8 +187,8 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(libdir)" -LTLIBRARIES = $(lib_LTLIBRARIES) +am__installdirs = "$(DESTDIR)$(ipseclibdir)" +LTLIBRARIES = $(ipseclib_LTLIBRARIES) am__DEPENDENCIES_1 = libcharon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @@ -189,13 +201,16 @@ libcharon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__append_38) $(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_55) $(am__append_56) $(am__append_58) \ - $(am__append_60) $(am__append_62) $(am__append_64) \ - $(am__append_66) $(am__append_68) $(am__append_70) \ - $(am__append_72) $(am__append_74) $(am__append_76) \ - $(am__append_78) $(am__append_80) $(am__append_82) \ - $(am__append_84) $(am__append_86) $(am__append_88) \ - $(am__append_90) $(am__append_92) $(am__append_94) + $(am__append_55) $(am__append_56) $(am__append_57) \ + $(am__append_59) $(am__append_61) $(am__append_63) \ + $(am__append_65) $(am__append_67) $(am__append_69) \ + $(am__append_71) $(am__append_73) $(am__append_74) \ + $(am__append_76) $(am__append_78) $(am__append_80) \ + $(am__append_82) $(am__append_84) $(am__append_86) \ + $(am__append_88) $(am__append_90) $(am__append_92) \ + $(am__append_94) $(am__append_96) $(am__append_98) \ + $(am__append_100) $(am__append_102) $(am__append_104) \ + $(am__append_106) am__libcharon_la_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 \ @@ -244,10 +259,10 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ encoding/payloads/unknown_payload.h \ encoding/payloads/vendor_id_payload.c \ encoding/payloads/vendor_id_payload.h kernel/kernel_handler.c \ - kernel/kernel_handler.h network/packet.c network/packet.h \ - network/receiver.c network/receiver.h network/sender.c \ - network/sender.h network/socket_manager.c \ - network/socket_manager.h network/socket.h \ + kernel/kernel_handler.h network/receiver.c network/receiver.h \ + network/sender.c network/sender.h network/packet.c \ + network/packet.h network/socket.c network/socket.h \ + network/socket_manager.c network/socket_manager.h \ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \ processing/jobs/delete_child_sa_job.c \ processing/jobs/delete_child_sa_job.h \ @@ -279,11 +294,6 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ sa/authenticators/eap/eap_method.h \ sa/authenticators/eap/eap_manager.c \ sa/authenticators/eap/eap_manager.h \ - sa/authenticators/eap/sim_manager.c \ - sa/authenticators/eap/sim_manager.h \ - sa/authenticators/eap/sim_card.h \ - sa/authenticators/eap/sim_provider.h \ - sa/authenticators/eap/sim_hooks.h \ sa/authenticators/psk_authenticator.c \ sa/authenticators/psk_authenticator.h \ sa/authenticators/pubkey_authenticator.c \ @@ -291,7 +301,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \ sa/ike_sa_id.h sa/ike_sa_manager.c sa/ike_sa_manager.h \ sa/task_manager.c sa/task_manager.h sa/keymat.c sa/keymat.h \ - sa/trap_manager.c sa/trap_manager.h sa/tasks/child_create.c \ + sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \ + sa/trap_manager.h sa/tasks/child_create.c \ sa/tasks/child_create.h sa/tasks/child_delete.c \ sa/tasks/child_delete.h sa/tasks/child_rekey.c \ sa/tasks/child_rekey.h sa/tasks/ike_auth.c sa/tasks/ike_auth.h \ @@ -306,12 +317,7 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \ sa/tasks/ike_auth_lifetime.h sa/tasks/ike_vendor.c \ sa/tasks/ike_vendor.h sa/tasks/task.c sa/tasks/task.h \ - tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h tnc/tncifimv.c \ - tnc/imc/imc.h tnc/imc/imc_manager.h tnc/imv/imv.h \ - tnc/imv/imv_manager.h tnc/imv/imv_recommendations.c \ - tnc/imv/imv_recommendations.h tnc/tnccs/tnccs.c \ - tnc/tnccs/tnccs.h tnc/tnccs/tnccs_manager.c \ - tnc/tnccs/tnccs_manager.h encoding/payloads/endpoint_notify.c \ + encoding/payloads/endpoint_notify.c \ encoding/payloads/endpoint_notify.h \ processing/jobs/initiate_mediation_job.c \ processing/jobs/initiate_mediation_job.h \ @@ -333,21 +339,20 @@ am_libcharon_la_OBJECTS = bus.lo file_logger.lo sys_logger.lo \ sa_payload.lo traffic_selector_substructure.lo \ transform_attribute.lo transform_substructure.lo ts_payload.lo \ unknown_payload.lo vendor_id_payload.lo kernel_handler.lo \ - packet.lo receiver.lo sender.lo socket_manager.lo \ + receiver.lo sender.lo packet.lo socket.lo socket_manager.lo \ acquire_job.lo delete_child_sa_job.lo delete_ike_sa_job.lo \ migrate_job.lo process_message_job.lo rekey_child_sa_job.lo \ rekey_ike_sa_job.lo retransmit_job.lo send_dpd_job.lo \ send_keepalive_job.lo start_action_job.lo roam_job.lo \ update_sa_job.lo inactivity_job.lo authenticator.lo \ eap_authenticator.lo eap_method.lo eap_manager.lo \ - sim_manager.lo psk_authenticator.lo pubkey_authenticator.lo \ - child_sa.lo ike_sa.lo ike_sa_id.lo ike_sa_manager.lo \ - task_manager.lo keymat.lo trap_manager.lo child_create.lo \ + psk_authenticator.lo pubkey_authenticator.lo child_sa.lo \ + ike_sa.lo ike_sa_id.lo ike_sa_manager.lo task_manager.lo \ + keymat.lo shunt_manager.lo trap_manager.lo child_create.lo \ child_delete.lo child_rekey.lo ike_auth.lo ike_cert_pre.lo \ ike_cert_post.lo ike_config.lo ike_delete.lo ike_dpd.lo \ ike_init.lo ike_natd.lo ike_mobike.lo ike_rekey.lo \ ike_reauth.lo ike_auth_lifetime.lo ike_vendor.lo task.lo \ - tncifimv.lo imv_recommendations.lo tnccs.lo tnccs_manager.lo \ $(am__objects_1) libcharon_la_OBJECTS = $(am_libcharon_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ @@ -388,12 +393,14 @@ DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \ plugins/eap_aka plugins/eap_aka_3gpp2 plugins/eap_md5 \ plugins/eap_gtc plugins/eap_mschapv2 plugins/eap_radius \ plugins/eap_tls plugins/eap_ttls plugins/eap_peap \ - plugins/eap_tnc plugins/tnc_imc plugins/tnc_imv \ + plugins/eap_tnc plugins/tnc_ifmap plugins/tnc_pdp \ + plugins/tnc_imc plugins/tnc_imv plugins/tnc_tnccs \ plugins/tnccs_11 plugins/tnccs_20 plugins/tnccs_dynamic \ plugins/medsrv plugins/medcli plugins/nm plugins/dhcp \ plugins/android plugins/maemo plugins/ha plugins/whitelist \ - plugins/led plugins/duplicheck plugins/coupling plugins/uci \ - plugins/addrblock plugins/unit_tester + plugins/certexpire plugins/led plugins/duplicheck \ + plugins/coupling plugins/radattr plugins/uci plugins/addrblock \ + plugins/unit_tester DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -511,6 +518,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -519,6 +529,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -535,11 +546,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -583,6 +596,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -593,7 +607,7 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -lib_LTLIBRARIES = libcharon.la +ipseclib_LTLIBRARIES = libcharon.la libcharon_la_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 \ @@ -642,10 +656,10 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ encoding/payloads/unknown_payload.h \ encoding/payloads/vendor_id_payload.c \ encoding/payloads/vendor_id_payload.h kernel/kernel_handler.c \ - kernel/kernel_handler.h network/packet.c network/packet.h \ - network/receiver.c network/receiver.h network/sender.c \ - network/sender.h network/socket_manager.c \ - network/socket_manager.h network/socket.h \ + kernel/kernel_handler.h network/receiver.c network/receiver.h \ + network/sender.c network/sender.h network/packet.c \ + network/packet.h network/socket.c network/socket.h \ + network/socket_manager.c network/socket_manager.h \ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \ processing/jobs/delete_child_sa_job.c \ processing/jobs/delete_child_sa_job.h \ @@ -677,11 +691,6 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ sa/authenticators/eap/eap_method.h \ sa/authenticators/eap/eap_manager.c \ sa/authenticators/eap/eap_manager.h \ - sa/authenticators/eap/sim_manager.c \ - sa/authenticators/eap/sim_manager.h \ - sa/authenticators/eap/sim_card.h \ - sa/authenticators/eap/sim_provider.h \ - sa/authenticators/eap/sim_hooks.h \ sa/authenticators/psk_authenticator.c \ sa/authenticators/psk_authenticator.h \ sa/authenticators/pubkey_authenticator.c \ @@ -689,7 +698,8 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \ sa/ike_sa_id.h sa/ike_sa_manager.c sa/ike_sa_manager.h \ sa/task_manager.c sa/task_manager.h sa/keymat.c sa/keymat.h \ - sa/trap_manager.c sa/trap_manager.h sa/tasks/child_create.c \ + sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \ + sa/trap_manager.h sa/tasks/child_create.c \ sa/tasks/child_create.h sa/tasks/child_delete.c \ sa/tasks/child_delete.h sa/tasks/child_rekey.c \ sa/tasks/child_rekey.h sa/tasks/ike_auth.c sa/tasks/ike_auth.h \ @@ -704,12 +714,7 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \ sa/tasks/ike_auth_lifetime.h sa/tasks/ike_vendor.c \ sa/tasks/ike_vendor.h sa/tasks/task.c sa/tasks/task.h \ - tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h tnc/tncifimv.c \ - tnc/imc/imc.h tnc/imc/imc_manager.h tnc/imv/imv.h \ - tnc/imv/imv_manager.h tnc/imv/imv_recommendations.c \ - tnc/imv/imv_recommendations.h tnc/tnccs/tnccs.c \ - tnc/tnccs/tnccs.h tnc/tnccs/tnccs_manager.c \ - tnc/tnccs/tnccs_manager.h $(am__append_1) + $(am__append_1) INCLUDES = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ @@ -731,13 +736,16 @@ libcharon_la_LIBADD = -lm $(PTHREADLIB) $(DLLIB) $(SOCKLIB) \ $(am__append_38) $(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_55) $(am__append_56) $(am__append_58) \ - $(am__append_60) $(am__append_62) $(am__append_64) \ - $(am__append_66) $(am__append_68) $(am__append_70) \ - $(am__append_72) $(am__append_74) $(am__append_76) \ - $(am__append_78) $(am__append_80) $(am__append_82) \ - $(am__append_84) $(am__append_86) $(am__append_88) \ - $(am__append_90) $(am__append_92) $(am__append_94) + $(am__append_55) $(am__append_56) $(am__append_57) \ + $(am__append_59) $(am__append_61) $(am__append_63) \ + $(am__append_65) $(am__append_67) $(am__append_69) \ + $(am__append_71) $(am__append_73) $(am__append_74) \ + $(am__append_76) $(am__append_78) $(am__append_80) \ + $(am__append_82) $(am__append_84) $(am__append_86) \ + $(am__append_88) $(am__append_90) $(am__append_92) \ + $(am__append_94) $(am__append_96) $(am__append_98) \ + $(am__append_100) $(am__append_102) $(am__append_104) \ + $(am__append_106) EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@SUBDIRS = . $(am__append_3) $(am__append_5) \ @MONOLITHIC_FALSE@ $(am__append_7) $(am__append_9) \ @@ -752,16 +760,18 @@ EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@ $(am__append_44) $(am__append_46) \ @MONOLITHIC_FALSE@ $(am__append_48) $(am__append_50) \ @MONOLITHIC_FALSE@ $(am__append_52) $(am__append_54) \ -@MONOLITHIC_FALSE@ $(am__append_57) $(am__append_59) \ -@MONOLITHIC_FALSE@ $(am__append_61) $(am__append_63) \ -@MONOLITHIC_FALSE@ $(am__append_65) $(am__append_67) \ -@MONOLITHIC_FALSE@ $(am__append_69) $(am__append_71) \ -@MONOLITHIC_FALSE@ $(am__append_73) $(am__append_75) \ -@MONOLITHIC_FALSE@ $(am__append_77) $(am__append_79) \ -@MONOLITHIC_FALSE@ $(am__append_81) $(am__append_83) \ -@MONOLITHIC_FALSE@ $(am__append_85) $(am__append_87) \ -@MONOLITHIC_FALSE@ $(am__append_89) $(am__append_91) \ -@MONOLITHIC_FALSE@ $(am__append_93) +@MONOLITHIC_FALSE@ $(am__append_58) $(am__append_60) \ +@MONOLITHIC_FALSE@ $(am__append_62) $(am__append_64) \ +@MONOLITHIC_FALSE@ $(am__append_66) $(am__append_68) \ +@MONOLITHIC_FALSE@ $(am__append_70) $(am__append_72) \ +@MONOLITHIC_FALSE@ $(am__append_75) $(am__append_77) \ +@MONOLITHIC_FALSE@ $(am__append_79) $(am__append_81) \ +@MONOLITHIC_FALSE@ $(am__append_83) $(am__append_85) \ +@MONOLITHIC_FALSE@ $(am__append_87) $(am__append_89) \ +@MONOLITHIC_FALSE@ $(am__append_91) $(am__append_93) \ +@MONOLITHIC_FALSE@ $(am__append_95) $(am__append_97) \ +@MONOLITHIC_FALSE@ $(am__append_99) $(am__append_101) \ +@MONOLITHIC_FALSE@ $(am__append_103) $(am__append_105) # build optional plugins ######################## @@ -778,16 +788,18 @@ EXTRA_DIST = Android.mk @MONOLITHIC_TRUE@ $(am__append_44) $(am__append_46) \ @MONOLITHIC_TRUE@ $(am__append_48) $(am__append_50) \ @MONOLITHIC_TRUE@ $(am__append_52) $(am__append_54) \ -@MONOLITHIC_TRUE@ $(am__append_57) $(am__append_59) \ -@MONOLITHIC_TRUE@ $(am__append_61) $(am__append_63) \ -@MONOLITHIC_TRUE@ $(am__append_65) $(am__append_67) \ -@MONOLITHIC_TRUE@ $(am__append_69) $(am__append_71) \ -@MONOLITHIC_TRUE@ $(am__append_73) $(am__append_75) \ -@MONOLITHIC_TRUE@ $(am__append_77) $(am__append_79) \ -@MONOLITHIC_TRUE@ $(am__append_81) $(am__append_83) \ -@MONOLITHIC_TRUE@ $(am__append_85) $(am__append_87) \ -@MONOLITHIC_TRUE@ $(am__append_89) $(am__append_91) \ -@MONOLITHIC_TRUE@ $(am__append_93) +@MONOLITHIC_TRUE@ $(am__append_58) $(am__append_60) \ +@MONOLITHIC_TRUE@ $(am__append_62) $(am__append_64) \ +@MONOLITHIC_TRUE@ $(am__append_66) $(am__append_68) \ +@MONOLITHIC_TRUE@ $(am__append_70) $(am__append_72) \ +@MONOLITHIC_TRUE@ $(am__append_75) $(am__append_77) \ +@MONOLITHIC_TRUE@ $(am__append_79) $(am__append_81) \ +@MONOLITHIC_TRUE@ $(am__append_83) $(am__append_85) \ +@MONOLITHIC_TRUE@ $(am__append_87) $(am__append_89) \ +@MONOLITHIC_TRUE@ $(am__append_91) $(am__append_93) \ +@MONOLITHIC_TRUE@ $(am__append_95) $(am__append_97) \ +@MONOLITHIC_TRUE@ $(am__append_99) $(am__append_101) \ +@MONOLITHIC_TRUE@ $(am__append_103) $(am__append_105) all: all-recursive .SUFFIXES: @@ -822,39 +834,39 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-libLTLIBRARIES: $(lib_LTLIBRARIES) +install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)" + @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ipseclibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \ } -uninstall-libLTLIBRARIES: +uninstall-ipseclibLTLIBRARIES: @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \ done -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ +clean-ipseclibLTLIBRARIES: + -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES) + @list='$(ipseclib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libcharon.la: $(libcharon_la_OBJECTS) $(libcharon_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libcharon_la_OBJECTS) $(libcharon_la_LIBADD) $(LIBS) + $(LINK) -rpath $(ipseclibdir) $(libcharon_la_OBJECTS) $(libcharon_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -911,7 +923,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_sa_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_sa_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_vendor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_recommendations.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inactivity_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initiate_mediation_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ke_payload.Plo@am__quote@ @@ -941,15 +952,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send_dpd_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send_keepalive_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sender.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sim_manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shunt_manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/start_action_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sys_logger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task_manager.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_manager.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tncifimv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/traffic_selector_substructure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform_attribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform_substructure.Plo@am__quote@ @@ -1232,13 +1241,6 @@ kernel_handler.lo: kernel/kernel_handler.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o kernel_handler.lo `test -f 'kernel/kernel_handler.c' || echo '$(srcdir)/'`kernel/kernel_handler.c -packet.lo: network/packet.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT packet.lo -MD -MP -MF $(DEPDIR)/packet.Tpo -c -o packet.lo `test -f 'network/packet.c' || echo '$(srcdir)/'`network/packet.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/packet.Tpo $(DEPDIR)/packet.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/packet.c' object='packet.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o packet.lo `test -f 'network/packet.c' || echo '$(srcdir)/'`network/packet.c - receiver.lo: network/receiver.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT receiver.lo -MD -MP -MF $(DEPDIR)/receiver.Tpo -c -o receiver.lo `test -f 'network/receiver.c' || echo '$(srcdir)/'`network/receiver.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/receiver.Tpo $(DEPDIR)/receiver.Plo @@ -1253,6 +1255,20 @@ sender.lo: network/sender.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sender.lo `test -f 'network/sender.c' || echo '$(srcdir)/'`network/sender.c +packet.lo: network/packet.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT packet.lo -MD -MP -MF $(DEPDIR)/packet.Tpo -c -o packet.lo `test -f 'network/packet.c' || echo '$(srcdir)/'`network/packet.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/packet.Tpo $(DEPDIR)/packet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/packet.c' object='packet.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o packet.lo `test -f 'network/packet.c' || echo '$(srcdir)/'`network/packet.c + +socket.lo: network/socket.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket.lo -MD -MP -MF $(DEPDIR)/socket.Tpo -c -o socket.lo `test -f 'network/socket.c' || echo '$(srcdir)/'`network/socket.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/socket.Tpo $(DEPDIR)/socket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/socket.c' object='socket.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o socket.lo `test -f 'network/socket.c' || echo '$(srcdir)/'`network/socket.c + socket_manager.lo: network/socket_manager.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket_manager.lo -MD -MP -MF $(DEPDIR)/socket_manager.Tpo -c -o socket_manager.lo `test -f 'network/socket_manager.c' || echo '$(srcdir)/'`network/socket_manager.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/socket_manager.Tpo $(DEPDIR)/socket_manager.Plo @@ -1386,13 +1402,6 @@ eap_manager.lo: sa/authenticators/eap/eap_manager.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_manager.lo `test -f 'sa/authenticators/eap/eap_manager.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_manager.c -sim_manager.lo: sa/authenticators/eap/sim_manager.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sim_manager.lo -MD -MP -MF $(DEPDIR)/sim_manager.Tpo -c -o sim_manager.lo `test -f 'sa/authenticators/eap/sim_manager.c' || echo '$(srcdir)/'`sa/authenticators/eap/sim_manager.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sim_manager.Tpo $(DEPDIR)/sim_manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/sim_manager.c' object='sim_manager.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sim_manager.lo `test -f 'sa/authenticators/eap/sim_manager.c' || echo '$(srcdir)/'`sa/authenticators/eap/sim_manager.c - psk_authenticator.lo: sa/authenticators/psk_authenticator.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT psk_authenticator.lo -MD -MP -MF $(DEPDIR)/psk_authenticator.Tpo -c -o psk_authenticator.lo `test -f 'sa/authenticators/psk_authenticator.c' || echo '$(srcdir)/'`sa/authenticators/psk_authenticator.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/psk_authenticator.Tpo $(DEPDIR)/psk_authenticator.Plo @@ -1449,6 +1458,13 @@ keymat.lo: sa/keymat.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o keymat.lo `test -f 'sa/keymat.c' || echo '$(srcdir)/'`sa/keymat.c +shunt_manager.lo: sa/shunt_manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shunt_manager.lo -MD -MP -MF $(DEPDIR)/shunt_manager.Tpo -c -o shunt_manager.lo `test -f 'sa/shunt_manager.c' || echo '$(srcdir)/'`sa/shunt_manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/shunt_manager.Tpo $(DEPDIR)/shunt_manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/shunt_manager.c' object='shunt_manager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shunt_manager.lo `test -f 'sa/shunt_manager.c' || echo '$(srcdir)/'`sa/shunt_manager.c + trap_manager.lo: sa/trap_manager.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trap_manager.lo -MD -MP -MF $(DEPDIR)/trap_manager.Tpo -c -o trap_manager.lo `test -f 'sa/trap_manager.c' || echo '$(srcdir)/'`sa/trap_manager.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/trap_manager.Tpo $(DEPDIR)/trap_manager.Plo @@ -1575,34 +1591,6 @@ task.lo: sa/tasks/task.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o task.lo `test -f 'sa/tasks/task.c' || echo '$(srcdir)/'`sa/tasks/task.c -tncifimv.lo: tnc/tncifimv.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tncifimv.lo -MD -MP -MF $(DEPDIR)/tncifimv.Tpo -c -o tncifimv.lo `test -f 'tnc/tncifimv.c' || echo '$(srcdir)/'`tnc/tncifimv.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tncifimv.Tpo $(DEPDIR)/tncifimv.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/tncifimv.c' object='tncifimv.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tncifimv.lo `test -f 'tnc/tncifimv.c' || echo '$(srcdir)/'`tnc/tncifimv.c - -imv_recommendations.lo: tnc/imv/imv_recommendations.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imv_recommendations.lo -MD -MP -MF $(DEPDIR)/imv_recommendations.Tpo -c -o imv_recommendations.lo `test -f 'tnc/imv/imv_recommendations.c' || echo '$(srcdir)/'`tnc/imv/imv_recommendations.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/imv_recommendations.Tpo $(DEPDIR)/imv_recommendations.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/imv/imv_recommendations.c' object='imv_recommendations.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imv_recommendations.lo `test -f 'tnc/imv/imv_recommendations.c' || echo '$(srcdir)/'`tnc/imv/imv_recommendations.c - -tnccs.lo: tnc/tnccs/tnccs.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs.lo -MD -MP -MF $(DEPDIR)/tnccs.Tpo -c -o tnccs.lo `test -f 'tnc/tnccs/tnccs.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs.Tpo $(DEPDIR)/tnccs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/tnccs/tnccs.c' object='tnccs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs.lo `test -f 'tnc/tnccs/tnccs.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs.c - -tnccs_manager.lo: tnc/tnccs/tnccs_manager.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_manager.lo -MD -MP -MF $(DEPDIR)/tnccs_manager.Tpo -c -o tnccs_manager.lo `test -f 'tnc/tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs_manager.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_manager.Tpo $(DEPDIR)/tnccs_manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/tnccs/tnccs_manager.c' object='tnccs_manager.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_manager.lo `test -f 'tnc/tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs_manager.c - endpoint_notify.lo: encoding/payloads/endpoint_notify.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT endpoint_notify.lo -MD -MP -MF $(DEPDIR)/endpoint_notify.Tpo -c -o endpoint_notify.lo `test -f 'encoding/payloads/endpoint_notify.c' || echo '$(srcdir)/'`encoding/payloads/endpoint_notify.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/endpoint_notify.Tpo $(DEPDIR)/endpoint_notify.Plo @@ -1849,7 +1837,7 @@ check: check-recursive all-am: Makefile $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(libdir)"; do \ + for dir in "$(DESTDIR)$(ipseclibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -1879,7 +1867,7 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ +clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive @@ -1900,13 +1888,13 @@ info: info-recursive info-am: -install-data-am: +install-data-am: install-ipseclibLTLIBRARIES install-dvi: install-dvi-recursive install-dvi-am: -install-exec-am: install-libLTLIBRARIES +install-exec-am: install-html: install-html-recursive @@ -1946,26 +1934,26 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-libLTLIBRARIES +uninstall-am: uninstall-ipseclibLTLIBRARIES .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic \ - clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \ + clean-ipseclibLTLIBRARIES clean-libtool ctags ctags-recursive \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ - uninstall-libLTLIBRARIES + install-info-am install-ipseclibLTLIBRARIES install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-ipseclibLTLIBRARIES daemon.lo : $(top_builddir)/config.status @@ -1974,6 +1962,10 @@ daemon.lo : $(top_builddir)/config.status @MONOLITHIC_TRUE@@USE_TLS_TRUE@ # otherwise this library is linked to eap_tls +@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@ # otherwise this library is linked to eap_radius + +@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@ # otherwise this library is linked to the respective plugins + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index 23931c47d..bf0ab2286 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -151,11 +151,20 @@ static void listener_cleanup(cleanup_data_t *data) entry_destroy(data->entry); } -METHOD(bus_t, listen_, void, - private_bus_t *this, listener_t *listener, job_t *job) +METHOD(bus_t, listen_, bool, + private_bus_t *this, listener_t *listener, job_t *job, u_int timeout) { - bool old; + bool old, timed_out = FALSE; cleanup_data_t data; + timeval_t tv, add; + + if (timeout) + { + add.tv_sec = timeout / 1000; + add.tv_usec = (timeout - (add.tv_sec * 1000)) * 1000; + time_monotonic(&tv); + timeradd(&tv, &add, &tv); + } data.this = this; data.entry = entry_create(listener, TRUE); @@ -168,13 +177,27 @@ METHOD(bus_t, listen_, void, old = thread_cancelability(TRUE); while (data.entry->blocker) { - data.entry->condvar->wait(data.entry->condvar, this->mutex); + if (timeout) + { + if (data.entry->condvar->timed_wait_abs(data.entry->condvar, + this->mutex, tv)) + { + this->listeners->remove(this->listeners, data.entry, NULL); + timed_out = TRUE; + break; + } + } + else + { + data.entry->condvar->wait(data.entry->condvar, this->mutex); + } } thread_cancelability(old); thread_cleanup_pop(FALSE); /* unlock mutex */ thread_cleanup_pop(TRUE); entry_destroy(data.entry); + return timed_out; } METHOD(bus_t, set_sa, void, @@ -564,15 +587,15 @@ METHOD(bus_t, ike_updown, void, /* a down event for IKE_SA implicitly downs all CHILD_SAs */ if (!up) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; - iterator = ike_sa->create_child_sa_iterator(ike_sa); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = ike_sa->create_child_sa_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { child_updown(this, child_sa, FALSE); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } } diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h index 6a306afcc..69060d383 100644 --- a/src/libcharon/bus/bus.h +++ b/src/libcharon/bus/bus.h @@ -80,10 +80,14 @@ typedef struct bus_t bus_t; * Kind of alerts to raise. */ enum alert_t { - /* a RADIUS server did not respond, no additional arguments */ + /** a RADIUS server did not respond, no additional arguments */ ALERT_RADIUS_NOT_RESPONDING, - /* a shutdown signal has been received, argument is a int with the signal */ + /** a shutdown signal has been received, argument is the signal (int) */ ALERT_SHUTDOWN_SIGNAL, + /** peer authentication failed, no arguments */ + ALERT_PEER_AUTH_FAILED, + /** failed to resolve peer address, no arguments */ + ALERT_PEER_ADDR_FAILED, }; /** @@ -148,8 +152,10 @@ struct bus_t { * * @param listener listener to register * @param job job to execute asynchronously when registered, or NULL + * @param timeout max timeout in ms to listen for events, 0 to disable + * @return TRUE if timed out */ - void (*listen)(bus_t *this, listener_t *listener, job_t *job); + bool (*listen)(bus_t *this, listener_t *listener, job_t *job, u_int timeout); /** * Set the IKE_SA the calling thread is using. @@ -177,7 +183,7 @@ struct bus_t { /** * Send a log message to the bus. * - * The signal specifies the type of the event occured. The format string + * The signal specifies the type of the event occurred. The format string * specifies an additional informational or error message with a * printf() like variable argument list. * Use the DBG() macros. diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h index e7873ee8c..21caed064 100644 --- a/src/libcharon/bus/listeners/listener.h +++ b/src/libcharon/bus/listeners/listener.h @@ -84,7 +84,7 @@ struct listener_t { /** * Hook called for received/sent messages of an IKE_SA. * - * @param ike_sa IKE_SA sending/receving a message + * @param ike_sa IKE_SA sending/receiving a message * @param message message object * @param incoming TRUE for incoming messages, FALSE for outgoing * @return TRUE to stay registered, FALSE to unregister diff --git a/src/libcharon/config/backend_manager.c b/src/libcharon/config/backend_manager.c index e78cb702d..a93457ea4 100644 --- a/src/libcharon/config/backend_manager.c +++ b/src/libcharon/config/backend_manager.c @@ -351,10 +351,18 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*, id_match_t match_peer_me, match_peer_other; ike_cfg_match_t match_ike; match_entry_t *entry; + chunk_t data; match_peer_me = get_peer_match(my_id, cfg, TRUE); + data = my_id->get_encoding(my_id); + DBG3(DBG_CFG, "match_peer_me: %d (%N -> %#B)", match_peer_me, + id_type_names, my_id->get_type(my_id), &data); match_peer_other = get_peer_match(other_id, cfg, FALSE); + data = other_id->get_encoding(other_id); + DBG3(DBG_CFG, "match_peer_other: %d (%N -> %#B)", match_peer_other, + id_type_names, other_id->get_type(other_id), &data); match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other); + DBG3(DBG_CFG, "match_ike: %d (%H %H)", match_ike, me, other); if (match_peer_me && match_peer_other && match_ike) { diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h index 175ced76c..370ff9d58 100644 --- a/src/libcharon/config/child_cfg.h +++ b/src/libcharon/config/child_cfg.h @@ -73,7 +73,7 @@ struct child_cfg_t { * Add a proposal to the list. * * The proposals are stored by priority, first added - * is the most prefered. + * is the most preferred. * After add, proposal is owned by child_cfg. * * @param proposal proposal to add @@ -95,7 +95,7 @@ struct child_cfg_t { * * Returned propsal is newly created and must be destroyed after usage. * - * @param proposals list from from wich proposals are selected + * @param proposals list from which proposals are selected * @param strip_dh TRUE strip out diffie hellman groups * @param private accept algorithms from a private range * @return selected proposal, or NULL if nothing matches diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c index 89dcd8022..342b9ddbe 100644 --- a/src/libcharon/config/ike_cfg.c +++ b/src/libcharon/config/ike_cfg.c @@ -138,26 +138,26 @@ METHOD(ike_cfg_t, get_proposals, linked_list_t*, METHOD(ike_cfg_t, select_proposal, proposal_t*, private_ike_cfg_t *this, linked_list_t *proposals, bool private) { - iterator_t *stored_iter, *supplied_iter; + enumerator_t *stored_enum, *supplied_enum; proposal_t *stored, *supplied, *selected; - stored_iter = this->proposals->create_iterator(this->proposals, TRUE); - supplied_iter = proposals->create_iterator(proposals, TRUE); + stored_enum = this->proposals->create_enumerator(this->proposals); + supplied_enum = proposals->create_enumerator(proposals); /* compare all stored proposals with all supplied. Stored ones are preferred.*/ - while (stored_iter->iterate(stored_iter, (void**)&stored)) + while (stored_enum->enumerate(stored_enum, (void**)&stored)) { - supplied_iter->reset(supplied_iter); + proposals->reset_enumerator(proposals, supplied_enum); - while (supplied_iter->iterate(supplied_iter, (void**)&supplied)) + while (supplied_enum->enumerate(supplied_enum, (void**)&supplied)) { selected = stored->select(stored, supplied, private); if (selected) { /* they match, return */ - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); + stored_enum->destroy(stored_enum); + supplied_enum->destroy(supplied_enum); DBG2(DBG_CFG, "received proposals: %#P", proposals); DBG2(DBG_CFG, "configured proposals: %#P", this->proposals); DBG2(DBG_CFG, "selected proposal: %P", selected); @@ -166,8 +166,8 @@ METHOD(ike_cfg_t, select_proposal, proposal_t*, } } /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */ - stored_iter->destroy(stored_iter); - supplied_iter->destroy(supplied_iter); + stored_enum->destroy(stored_enum); + supplied_enum->destroy(supplied_enum); DBG1(DBG_CFG, "received proposals: %#P", proposals); DBG1(DBG_CFG, "configured proposals: %#P", this->proposals); diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c index 6f0c87279..c623cbc9b 100644 --- a/src/libcharon/config/peer_cfg.c +++ b/src/libcharon/config/peer_cfg.c @@ -110,7 +110,7 @@ struct private_peer_cfg_t { u_int32_t reauth_time; /** - * Time, which specifies the range of a random value substracted from above. + * Time, which specifies the range of a random value subtracted from above. */ u_int32_t jitter_time; @@ -163,34 +163,26 @@ struct private_peer_cfg_t { #endif /* ME */ }; -/** - * Implementation of peer_cfg_t.get_name - */ -static char *get_name(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_name, char*, + private_peer_cfg_t *this) { return this->name; } -/** - * Implementation of peer_cfg_t.get_ike_version - */ -static u_int get_ike_version(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_ike_version, u_int, + private_peer_cfg_t *this) { return this->ike_version; } -/** - * Implementation of peer_cfg_t.get_ike_cfg - */ -static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_ike_cfg, ike_cfg_t*, + private_peer_cfg_t *this) { return this->ike_cfg; } -/** - * Implementation of peer_cfg_t.add_child_cfg. - */ -static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg) +METHOD(peer_cfg_t, add_child_cfg, void, + private_peer_cfg_t *this, child_cfg_t *child_cfg) { this->mutex->lock(this->mutex); this->child_cfgs->insert_last(this->child_cfgs, child_cfg); @@ -206,44 +198,39 @@ typedef struct { mutex_t *mutex; } child_cfg_enumerator_t; -/** - * Implementation of peer_cfg_t.remove_child_cfg. - */ -static void remove_child_cfg(private_peer_cfg_t *this, - child_cfg_enumerator_t *enumerator) +METHOD(peer_cfg_t, remove_child_cfg, void, + private_peer_cfg_t *this, child_cfg_enumerator_t *enumerator) { this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped); } -/** - * Implementation of child_cfg_enumerator_t.destroy - */ -static void child_cfg_enumerator_destroy(child_cfg_enumerator_t *this) +METHOD(enumerator_t, child_cfg_enumerator_destroy, void, + child_cfg_enumerator_t *this) { this->mutex->unlock(this->mutex); this->wrapped->destroy(this->wrapped); free(this); } -/** - * Implementation of child_cfg_enumerator_t.enumerate - */ -static bool child_cfg_enumerate(child_cfg_enumerator_t *this, child_cfg_t **chd) +METHOD(enumerator_t, child_cfg_enumerate, bool, + child_cfg_enumerator_t *this, child_cfg_t **chd) { return this->wrapped->enumerate(this->wrapped, chd); } -/** - * Implementation of peer_cfg_t.create_child_cfg_enumerator. - */ -static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this) +METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*, + private_peer_cfg_t *this) { - child_cfg_enumerator_t *enumerator = malloc_thing(child_cfg_enumerator_t); + child_cfg_enumerator_t *enumerator; - enumerator->public.enumerate = (void*)child_cfg_enumerate; - enumerator->public.destroy = (void*)child_cfg_enumerator_destroy; - enumerator->mutex = this->mutex; - enumerator->wrapped = this->child_cfgs->create_enumerator(this->child_cfgs); + INIT(enumerator, + .public = { + .enumerate = (void*)_child_cfg_enumerate, + .destroy = (void*)_child_cfg_enumerator_destroy, + }, + .mutex = this->mutex, + .wrapped = this->child_cfgs->create_enumerator(this->child_cfgs), + ); this->mutex->lock(this->mutex); return &enumerator->public; @@ -292,13 +279,9 @@ static int get_ts_match(child_cfg_t *cfg, bool local, return match; } -/** - * Implementation of peer_cfg_t.select_child_cfg - */ -static child_cfg_t* select_child_cfg(private_peer_cfg_t *this, - linked_list_t *my_ts, - linked_list_t *other_ts, - host_t *my_host, host_t *other_host) +METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*, + private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts, + host_t *my_host, host_t *other_host) { child_cfg_t *current, *found = NULL; enumerator_t *enumerator; @@ -334,34 +317,26 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this, return found; } -/** - * Implementation of peer_cfg_t.get_cert_policy. - */ -static cert_policy_t get_cert_policy(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_cert_policy, cert_policy_t, + private_peer_cfg_t *this) { return this->cert_policy; } -/** - * Implementation of peer_cfg_t.get_unique_policy. - */ -static unique_policy_t get_unique_policy(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_unique_policy, unique_policy_t, + private_peer_cfg_t *this) { return this->unique; } -/** - * Implementation of peer_cfg_t.get_keyingtries. - */ -static u_int32_t get_keyingtries(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_keyingtries, u_int32_t, + private_peer_cfg_t *this) { return this->keyingtries; } -/** - * Implementation of peer_cfg_t.get_rekey_time. - */ -static u_int32_t get_rekey_time(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_rekey_time, u_int32_t, + private_peer_cfg_t *this) { if (this->rekey_time == 0) { @@ -374,10 +349,8 @@ static u_int32_t get_rekey_time(private_peer_cfg_t *this) return this->rekey_time - (random() % this->jitter_time); } -/** - * Implementation of peer_cfg_t.get_reauth_time. - */ -static u_int32_t get_reauth_time(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_reauth_time, u_int32_t, + private_peer_cfg_t *this) { if (this->reauth_time == 0) { @@ -390,51 +363,38 @@ static u_int32_t get_reauth_time(private_peer_cfg_t *this) return this->reauth_time - (random() % this->jitter_time); } -/** - * Implementation of peer_cfg_t.get_over_time. - */ -static u_int32_t get_over_time(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_over_time, u_int32_t, + private_peer_cfg_t *this) { return this->over_time; } -/** - * Implementation of peer_cfg_t.use_mobike. - */ -static bool use_mobike(private_peer_cfg_t *this) +METHOD(peer_cfg_t, use_mobike, bool, + private_peer_cfg_t *this) { return this->use_mobike; } -/** - * Implements peer_cfg_t.get_dpd - */ -static u_int32_t get_dpd(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_dpd, u_int32_t, + private_peer_cfg_t *this) { return this->dpd; } -/** - * Implementation of peer_cfg_t.get_virtual_ip. - */ -static host_t* get_virtual_ip(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_virtual_ip, host_t*, + private_peer_cfg_t *this) { return this->virtual_ip; } -/** - * Implementation of peer_cfg_t.get_pool. - */ -static char* get_pool(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_pool, char*, + private_peer_cfg_t *this) { return this->pool; } -/** - * Implementation of peer_cfg_t.add_auth_cfg - */ -static void add_auth_cfg(private_peer_cfg_t *this, - auth_cfg_t *cfg, bool local) +METHOD(peer_cfg_t, add_auth_cfg, void, + private_peer_cfg_t *this, auth_cfg_t *cfg, bool local) { if (local) { @@ -446,11 +406,8 @@ static void add_auth_cfg(private_peer_cfg_t *this, } } -/** - * Implementation of peer_cfg_t.create_auth_cfg_enumerator - */ -static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this, - bool local) +METHOD(peer_cfg_t, create_auth_cfg_enumerator, enumerator_t*, + private_peer_cfg_t *this, bool local) { if (local) { @@ -460,26 +417,20 @@ static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this, } #ifdef ME -/** - * Implementation of peer_cfg_t.is_mediation. - */ -static bool is_mediation(private_peer_cfg_t *this) +METHOD(peer_cfg_t, is_mediation, bool, + private_peer_cfg_t *this) { return this->mediation; } -/** - * Implementation of peer_cfg_t.get_mediated_by. - */ -static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_mediated_by, peer_cfg_t*, + private_peer_cfg_t *this) { return this->mediated_by; } -/** - * Implementation of peer_cfg_t.get_peer_id. - */ -static identification_t* get_peer_id(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_peer_id, identification_t*, + private_peer_cfg_t *this) { return this->peer_id; } @@ -539,10 +490,8 @@ static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other) return equal; } -/** - * Implementation of peer_cfg_t.equals. - */ -static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other) +METHOD(peer_cfg_t, equals, bool, + private_peer_cfg_t *this, private_peer_cfg_t *other) { if (this == other) { @@ -580,19 +529,15 @@ static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other) ); } -/** - * Implements peer_cfg_t.get_ref. - */ -static peer_cfg_t* get_ref(private_peer_cfg_t *this) +METHOD(peer_cfg_t, get_ref, peer_cfg_t*, + private_peer_cfg_t *this) { ref_get(&this->refcount); return &this->public; } -/** - * Implements peer_cfg_t.destroy. - */ -static void destroy(private_peer_cfg_t *this) +METHOD(peer_cfg_t, destroy, void, + private_peer_cfg_t *this) { if (ref_put(&this->refcount)) { @@ -627,48 +572,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg, bool mediation, peer_cfg_t *mediated_by, identification_t *peer_id) { - private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t); - - /* public functions */ - this->public.get_name = (char* (*) (peer_cfg_t *))get_name; - this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version; - this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg; - this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg; - this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg; - this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator; - this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg; - this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy; - this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy; - this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries; - this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time; - this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time; - this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time; - this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike; - this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd; - this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip; - this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool; - this->public.add_auth_cfg = (void(*)(peer_cfg_t*, auth_cfg_t *cfg, bool local))add_auth_cfg; - this->public.create_auth_cfg_enumerator = (enumerator_t*(*)(peer_cfg_t*, bool local))create_auth_cfg_enumerator; - this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals; - this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref; - this->public.destroy = (void(*)(peer_cfg_t *))destroy; -#ifdef ME - this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation; - this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by; - this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id; -#endif /* ME */ + private_peer_cfg_t *this; - /* apply init values */ - this->name = strdup(name); - this->ike_version = ike_version; - this->ike_cfg = ike_cfg; - this->child_cfgs = linked_list_create(); - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - this->cert_policy = cert_policy; - this->unique = unique; - this->keyingtries = keyingtries; - this->rekey_time = rekey_time; - this->reauth_time = reauth_time; if (rekey_time && jitter_time > rekey_time) { jitter_time = rekey_time; @@ -677,15 +582,58 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg, { jitter_time = reauth_time; } - this->jitter_time = jitter_time; - this->over_time = over_time; - this->use_mobike = mobike; - this->dpd = dpd; - this->virtual_ip = virtual_ip; - this->pool = strdupnull(pool); - this->local_auth = linked_list_create(); - this->remote_auth = linked_list_create(); - this->refcount = 1; + + INIT(this, + .public = { + .get_name = _get_name, + .get_ike_version = _get_ike_version, + .get_ike_cfg = _get_ike_cfg, + .add_child_cfg = _add_child_cfg, + .remove_child_cfg = (void*)_remove_child_cfg, + .create_child_cfg_enumerator = _create_child_cfg_enumerator, + .select_child_cfg = _select_child_cfg, + .get_cert_policy = _get_cert_policy, + .get_unique_policy = _get_unique_policy, + .get_keyingtries = _get_keyingtries, + .get_rekey_time = _get_rekey_time, + .get_reauth_time = _get_reauth_time, + .get_over_time = _get_over_time, + .use_mobike = _use_mobike, + .get_dpd = _get_dpd, + .get_virtual_ip = _get_virtual_ip, + .get_pool = _get_pool, + .add_auth_cfg = _add_auth_cfg, + .create_auth_cfg_enumerator = _create_auth_cfg_enumerator, + .equals = (void*)_equals, + .get_ref = _get_ref, + .destroy = _destroy, +#ifdef ME + .is_mediation = _is_mediation, + .get_mediated_by = _get_mediated_by, + .get_peer_id = _get_peer_id, +#endif /* ME */ + }, + .name = strdup(name), + .ike_version = ike_version, + .ike_cfg = ike_cfg, + .child_cfgs = linked_list_create(), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .cert_policy = cert_policy, + .unique = unique, + .keyingtries = keyingtries, + .rekey_time = rekey_time, + .reauth_time = reauth_time, + .jitter_time = jitter_time, + .over_time = over_time, + .use_mobike = mobike, + .dpd = dpd, + .virtual_ip = virtual_ip, + .pool = strdupnull(pool), + .local_auth = linked_list_create(), + .remote_auth = linked_list_create(), + .refcount = 1, + ); + #ifdef ME this->mediation = mediation; this->mediated_by = mediated_by; diff --git a/src/libcharon/config/peer_cfg.h b/src/libcharon/config/peer_cfg.h index 723435cbb..f644fb547 100644 --- a/src/libcharon/config/peer_cfg.h +++ b/src/libcharon/config/peer_cfg.h @@ -82,8 +82,9 @@ extern enum_name_t *unique_policy_names; * Configuration of a peer, specified by IDs. * * The peer config defines a connection between two given IDs. It contains - * exactly one ike_cfg_t, which is use for initiation. Additionally, it contains - * multiple child_cfg_t defining which CHILD_SAs are allowed for this peer. + * exactly one ike_cfg_t, which is used for initiation. Additionally, it + * contains multiple child_cfg_t defining which CHILD_SAs are allowed for this + * peer. * @verbatim +-------------------+ +---------------+ +---------------+ | peer_cfg | +---------------+ | @@ -110,7 +111,7 @@ extern enum_name_t *unique_policy_names; * peer. Each config is enforced using the multiple authentication extension * (RFC4739). * The remote authentication configs are handled as constraints. The peer has - * to fullfill each of these rules (using multiple authentication, in any order) + * to fulfill each of these rules (using multiple authentication, in any order) * to gain access to the configuration. */ struct peer_cfg_t { @@ -127,7 +128,7 @@ struct peer_cfg_t { /** * Get the IKE version to use for initiating. * - * @return IKE major version + * @return IKE major version */ u_int (*get_ike_version)(peer_cfg_t *this); @@ -328,14 +329,14 @@ struct peer_cfg_t { * (rekeylifetime - random(0, jitter)). * * @param name name of the peer_cfg - * @param ike_version which IKE version we sould use for this peer + * @param ike_version which IKE version we should use for this peer * @param ike_cfg IKE config to use when acting as initiator * @param cert_policy should we send a certificate payload? * @param unique uniqueness of an IKE_SA * @param keyingtries how many keying tries should be done before giving up * @param rekey_time timeout before starting rekeying * @param reauth_time timeout before starting reauthentication - * @param jitter_time timerange to randomly substract from rekey/reauth time + * @param jitter_time timerange to randomly subtract from rekey/reauth time * @param over_time maximum overtime before closing a rekeying/reauth SA * @param mobike use MOBIKE (RFC4555) if peer supports it * @param dpd DPD check interval, 0 to disable @@ -344,7 +345,7 @@ struct peer_cfg_t { * @param mediation TRUE if this is a mediation connection * @param mediated_by peer_cfg_t of the mediation connection to mediate through * @param peer_id ID that identifies our peer at the mediation server - * @return peer_cfg_t object + * @return peer_cfg_t object */ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg, cert_policy_t cert_policy, unique_policy_t unique, diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index 2251b82dd..d3c60a469 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -598,6 +598,9 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg) case AUTH_CAMELLIA_XCBC_96: prf = PRF_CAMELLIA128_XCBC; break; + case AUTH_AES_CMAC_96: + prf = PRF_AES128_CMAC; + break; default: prf = PRF_UNDEFINED; } @@ -794,6 +797,7 @@ static void proposal_add_supported_ike(private_proposal_t *this) case AUTH_HMAC_SHA2_512_256: case AUTH_HMAC_MD5_96: case AUTH_AES_XCBC_96: + case AUTH_AES_CMAC_96: add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0); break; default: @@ -813,6 +817,7 @@ static void proposal_add_supported_ike(private_proposal_t *this) case PRF_HMAC_SHA2_512: case PRF_HMAC_MD5: case PRF_AES128_XCBC: + case PRF_AES128_CMAC: add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0); break; default: diff --git a/src/libcharon/config/proposal.h b/src/libcharon/config/proposal.h index 9337518bf..8f54d7e6e 100644 --- a/src/libcharon/config/proposal.h +++ b/src/libcharon/config/proposal.h @@ -120,7 +120,7 @@ struct proposal_t { * compared. If they have at least one algorithm of each type * in common, a resulting proposal of this kind is created. * - * @param other proposal to compair agains + * @param other proposal to compare against * @param private accepts algorithms allocated in a private range * @return selected proposal, NULL if proposals don't match */ @@ -180,7 +180,7 @@ struct proposal_t { * * @param protocol protocol, such as PROTO_ESP * @param number proposal number, as encoded in SA payload - * @return proposal_t object + * @return proposal_t object */ proposal_t *proposal_create(protocol_id_t protocol, u_int number); @@ -188,7 +188,7 @@ proposal_t *proposal_create(protocol_id_t protocol, u_int number); * Create a default proposal if nothing further specified. * * @param protocol protocol, such as PROTO_ESP - * @return proposal_t object + * @return proposal_t object */ proposal_t *proposal_create_default(protocol_id_t protocol); @@ -203,7 +203,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol); * * @param protocol protocol, such as PROTO_ESP * @param algs algorithms as string - * @return proposal_t object + * @return proposal_t object */ proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs); diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c index 5bc19d11b..0f247962b 100644 --- a/src/libcharon/control/controller.c +++ b/src/libcharon/control/controller.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2007 Martin Willi + * Copyright (C) 2007-2011 Martin Willi + * Copyright (C) 2011 revosec AG * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -96,6 +97,7 @@ typedef struct interface_job_t interface_job_t; * job for asynchronous listen operations */ struct interface_job_t { + /** * job interface */ @@ -107,12 +109,9 @@ struct interface_job_t { interface_listener_t listener; }; -/** - * listener log function - */ -static bool listener_log(interface_listener_t *this, debug_t group, - level_t level, int thread, ike_sa_t *ike_sa, - char* format, va_list args) +METHOD(listener_t, listener_log, bool, + interface_listener_t *this, debug_t group, level_t level, int thread, + ike_sa_t *ike_sa, char* format, va_list args) { if (this->ike_sa == ike_sa) { @@ -124,11 +123,14 @@ static bool listener_log(interface_listener_t *this, debug_t group, return TRUE; } -/** - * Implementation of listener_t.ike_state_change - */ -static bool listener_ike_state(interface_listener_t *this, ike_sa_t *ike_sa, - ike_sa_state_t state) +METHOD(job_t, get_priority_medium, job_priority_t, + job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + +METHOD(listener_t, ike_state_change, bool, + interface_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state) { if (this->ike_sa == ike_sa) { @@ -160,11 +162,9 @@ static bool listener_ike_state(interface_listener_t *this, ike_sa_t *ike_sa, return TRUE; } -/** - * Implementation of listener_t.child_state_change - */ -static bool listener_child_state(interface_listener_t *this, ike_sa_t *ike_sa, - child_sa_t *child_sa, child_sa_state_t state) +METHOD(listener_t, child_state_change, bool, + interface_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + child_sa_state_t state) { if (this->ike_sa == ike_sa) { @@ -191,10 +191,8 @@ static bool listener_child_state(interface_listener_t *this, ike_sa_t *ike_sa, return TRUE; } -/** - * cleanup job if job is never executed - */ -static void recheckin(interface_job_t *job) +METHOD(job_t, recheckin, void, + interface_job_t *job) { if (job->listener.ike_sa) { @@ -203,18 +201,15 @@ static void recheckin(interface_job_t *job) } } -/** - * Implementation of controller_t.create_ike_sa_iterator. - */ -static enumerator_t* create_ike_sa_enumerator(controller_t *this) +METHOD(controller_t, create_ike_sa_enumerator, enumerator_t*, + private_controller_t *this, bool wait) { - return charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager); + return charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager, + wait); } -/** - * execute function for initiate - */ -static status_t initiate_execute(interface_job_t *job) +METHOD(job_t, initiate_execute, void, + interface_job_t *job) { ike_sa_t *ike_sa; interface_listener_t *listener = &job->listener; @@ -233,25 +228,26 @@ static status_t initiate_execute(interface_job_t *job) if (ike_sa->initiate(ike_sa, listener->child_cfg, 0, NULL, NULL) == SUCCESS) { charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); - return SUCCESS; + listener->status = SUCCESS; + } + else + { + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, + ike_sa); + listener->status = FAILED; } - charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); - return FAILED; } -/** - * Implementation of controller_t.initiate. - */ -static status_t initiate(private_controller_t *this, - peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, - controller_cb_t callback, void *param) +METHOD(controller_t, initiate, status_t, + private_controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, + controller_cb_t callback, void *param, u_int timeout) { interface_job_t job = { .listener = { .public = { - .log = (void*)listener_log, - .ike_state_change = (void*)listener_ike_state, - .child_state_change = (void*)listener_child_state, + .log = _listener_log, + .ike_state_change = _ike_state_change, + .child_state_change = _child_state_change, }, .callback = callback, .param = param, @@ -260,22 +256,28 @@ static status_t initiate(private_controller_t *this, .peer_cfg = peer_cfg, }, .public = { - .execute = (void*)initiate_execute, - .destroy = (void*)recheckin, + .execute = _initiate_execute, + .get_priority = _get_priority_medium, + .destroy = _recheckin, }, }; if (callback == NULL) { - return initiate_execute(&job); + initiate_execute(&job); + } + else + { + if (charon->bus->listen(charon->bus, &job.listener.public, &job.public, + timeout)) + { + job.listener.status = OUT_OF_RES; + } } - charon->bus->listen(charon->bus, &job.listener.public, (job_t*)&job); return job.listener.status; } -/** - * execute function for terminate_ike - */ -static status_t terminate_ike_execute(interface_job_t *job) +METHOD(job_t, terminate_ike_execute, void, + interface_job_t *job) { interface_listener_t *listener = &job->listener; ike_sa_t *ike_sa = listener->ike_sa; @@ -286,25 +288,27 @@ static status_t terminate_ike_execute(interface_job_t *job) { charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); /* delete failed */ - return FAILED; + listener->status = FAILED; + } + else + { + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, + ike_sa); + listener->status = SUCCESS; } - charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); - return SUCCESS; } -/** - * Implementation of controller_t.terminate_ike. - */ -static status_t terminate_ike(controller_t *this, u_int32_t unique_id, - controller_cb_t callback, void *param) +METHOD(controller_t, terminate_ike, status_t, + controller_t *this, u_int32_t unique_id, + controller_cb_t callback, void *param, u_int timeout) { ike_sa_t *ike_sa; interface_job_t job = { .listener = { .public = { - .log = (void*)listener_log, - .ike_state_change = (void*)listener_ike_state, - .child_state_change = (void*)listener_child_state, + .log = _listener_log, + .ike_state_change = _ike_state_change, + .child_state_change = _child_state_change, }, .callback = callback, .param = param, @@ -312,8 +316,9 @@ static status_t terminate_ike(controller_t *this, u_int32_t unique_id, .id = unique_id, }, .public = { - .execute = (void*)terminate_ike_execute, - .destroy = (void*)recheckin, + .execute = _terminate_ike_execute, + .get_priority = _get_priority_medium, + .destroy = _recheckin, }, }; @@ -328,18 +333,23 @@ static status_t terminate_ike(controller_t *this, u_int32_t unique_id, if (callback == NULL) { - return terminate_ike_execute(&job); + terminate_ike_execute(&job); + } + else + { + if (charon->bus->listen(charon->bus, &job.listener.public, &job.public, + timeout)) + { + job.listener.status = OUT_OF_RES; + } + /* checkin of the ike_sa happened in the thread that executed the job */ + charon->bus->set_sa(charon->bus, NULL); } - charon->bus->listen(charon->bus, &job.listener.public, (job_t*)&job); - /* checkin of the ike_sa happend in the thread that executed the job */ - charon->bus->set_sa(charon->bus, NULL); return job.listener.status; } -/** - * execute function for terminate_child - */ -static status_t terminate_child_execute(interface_job_t *job) +METHOD(job_t, terminate_child_execute, void, + interface_job_t *job) { interface_listener_t *listener = &job->listener; ike_sa_t *ike_sa = listener->ike_sa; @@ -350,27 +360,29 @@ static status_t terminate_child_execute(interface_job_t *job) child_sa->get_spi(child_sa, TRUE)) != DESTROY_ME) { charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); - return SUCCESS; + listener->status = SUCCESS; + } + else + { + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, + ike_sa); + listener->status = FAILED; } - charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); - return FAILED; } -/** - * Implementation of controller_t.terminate_child. - */ -static status_t terminate_child(controller_t *this, u_int32_t reqid, - controller_cb_t callback, void *param) +METHOD(controller_t, terminate_child, status_t, + controller_t *this, u_int32_t reqid, + controller_cb_t callback, void *param, u_int timeout) { ike_sa_t *ike_sa; child_sa_t *child_sa; - iterator_t *iterator; + enumerator_t *enumerator; interface_job_t job = { .listener = { .public = { - .log = (void*)listener_log, - .ike_state_change = (void*)listener_ike_state, - .child_state_change = (void*)listener_child_state, + .log = _listener_log, + .ike_state_change = _ike_state_change, + .child_state_change = _child_state_change, }, .callback = callback, .param = param, @@ -378,8 +390,9 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid, .id = reqid, }, .public = { - .execute = (void*)terminate_child_execute, - .destroy = (void*)recheckin, + .execute = _terminate_child_execute, + .get_priority = _get_priority_medium, + .destroy = _recheckin, }, }; @@ -393,8 +406,8 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid, } job.listener.ike_sa = ike_sa; - iterator = ike_sa->create_child_sa_iterator(ike_sa); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = ike_sa->create_child_sa_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (child_sa->get_state(child_sa) != CHILD_ROUTED && child_sa->get_reqid(child_sa) == reqid) @@ -403,7 +416,7 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid, } child_sa = NULL; } - iterator->destroy(iterator); + enumerator->destroy(enumerator); if (child_sa == NULL) { @@ -416,11 +429,18 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid, if (callback == NULL) { - return terminate_child_execute(&job); + terminate_child_execute(&job); + } + else + { + if (charon->bus->listen(charon->bus, &job.listener.public, &job.public, + timeout)) + { + job.listener.status = OUT_OF_RES; + } + /* checkin of the ike_sa happened in the thread that executed the job */ + charon->bus->set_sa(charon->bus, NULL); } - charon->bus->listen(charon->bus, &job.listener.public, (job_t*)&job); - /* checkin of the ike_sa happend in the thread that executed the job */ - charon->bus->set_sa(charon->bus, NULL); return job.listener.status; } @@ -428,15 +448,13 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid, * See header */ bool controller_cb_empty(void *param, debug_t group, level_t level, - ike_sa_t *ike_sa, char *format, va_list args) + ike_sa_t *ike_sa, char *format, va_list args) { return TRUE; } -/** - * Implementation of stroke_t.destroy. - */ -static void destroy(private_controller_t *this) +METHOD(controller_t, destroy, void, + private_controller_t *this) { free(this); } @@ -446,13 +464,17 @@ static void destroy(private_controller_t *this) */ controller_t *controller_create(void) { - private_controller_t *this = malloc_thing(private_controller_t); + private_controller_t *this; - this->public.create_ike_sa_enumerator = (enumerator_t*(*)(controller_t*))create_ike_sa_enumerator; - this->public.initiate = (status_t(*)(controller_t*,peer_cfg_t*,child_cfg_t*,controller_cb_t,void*))initiate; - this->public.terminate_ike = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void*))terminate_ike; - this->public.terminate_child = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void *param))terminate_child; - this->public.destroy = (void (*)(controller_t*))destroy; + INIT(this, + .public = { + .create_ike_sa_enumerator = _create_ike_sa_enumerator, + .initiate = _initiate, + .terminate_ike = _terminate_ike, + .terminate_child = _terminate_child, + .destroy = _destroy, + }, + ); return &this->public; } diff --git a/src/libcharon/control/controller.h b/src/libcharon/control/controller.h index 31b69c78c..6adaef109 100644 --- a/src/libcharon/control/controller.h +++ b/src/libcharon/control/controller.h @@ -56,7 +56,7 @@ typedef struct controller_t controller_t; * * Passing NULL as callback to the managers function calls them asynchronously. * If a callback is specified, they are called synchronously. There is a default - * callback "controller_cb_empty" if you wan't to call a function + * callback "controller_cb_empty" if you want to call a function * synchronously, but don't need a callback. */ struct controller_t { @@ -65,11 +65,12 @@ struct controller_t { * Create an enumerator for all IKE_SAs. * * The enumerator blocks the IKE_SA manager until it gets destroyed. Do - * not call another interface/manager method while the iterator is alive. + * not call another interface/manager method while the enumerator is alive. * + * @param wait TRUE to wait for checked out SAs, FALSE to skip * @return enumerator, locks IKE_SA manager until destroyed */ - enumerator_t* (*create_ike_sa_enumerator)(controller_t *this); + enumerator_t* (*create_ike_sa_enumerator)(controller_t *this, bool wait); /** * Initiate a CHILD_SA, and if required, an IKE_SA. @@ -82,14 +83,16 @@ struct controller_t { * @param child_cfg child_cfg to set up CHILD_SA from * @param cb logging callback * @param param parameter to include in each call of cb + * @param timeout timeout in ms to wait for callbacks, 0 to disable * @return * - SUCCESS, if CHILD_SA established * - FAILED, if setup failed * - NEED_MORE, if callback returned FALSE + * - OUT_OF_RES if timed out */ status_t (*initiate)(controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, - controller_cb_t callback, void *param); + controller_cb_t callback, void *param, u_int timeout); /** * Terminate an IKE_SA and all of its CHILD_SAs. @@ -101,13 +104,16 @@ struct controller_t { * @param unique_id unique id of the IKE_SA to terminate. * @param cb logging callback * @param param parameter to include in each call of cb + * @param timeout timeout in ms to wait for callbacks, 0 to disable * @return * - SUCCESS, if CHILD_SA terminated * - NOT_FOUND, if no such CHILD_SA found * - NEED_MORE, if callback returned FALSE + * - OUT_OF_RES if timed out */ status_t (*terminate_ike)(controller_t *this, u_int32_t unique_id, - controller_cb_t callback, void *param); + controller_cb_t callback, void *param, + u_int timeout); /** * Terminate a CHILD_SA. @@ -115,13 +121,16 @@ struct controller_t { * @param reqid reqid of the CHILD_SA to terminate * @param cb logging callback * @param param parameter to include in each call of cb + * @param timeout timeout in ms to wait for callbacks, 0 to disable * @return * - SUCCESS, if CHILD_SA terminated * - NOT_FOUND, if no such CHILD_SA found * - NEED_MORE, if callback returned FALSE + * - OUT_OF_RES if timed out */ status_t (*terminate_child)(controller_t *this, u_int32_t reqid, - controller_cb_t callback, void *param); + controller_cb_t callback, void *param, + u_int timeout); /** * Destroy a controller_t instance. diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index 796e455a7..3fb49d475 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -32,6 +32,7 @@ #include "daemon.h" #include <library.h> +#include <plugins/plugin.h> #include <config/proposal.h> #include <kernel/kernel_handler.h> #include <processing/jobs/start_action_job.h> @@ -104,8 +105,18 @@ static void destroy(private_daemon_t *this) { this->public.ike_sa_manager->flush(this->public.ike_sa_manager); } + if (this->public.traps) + { + this->public.traps->flush(this->public.traps); + } DESTROY_IF(this->public.receiver); DESTROY_IF(this->public.sender); +#ifdef ME + DESTROY_IF(this->public.connect_manager); + DESTROY_IF(this->public.mediation_manager); +#endif /* ME */ + /* make sure the cache is clear before unloading plugins */ + lib->credmgr->flush_cache(lib->credmgr, CERT_ANY); /* unload plugins to release threads */ lib->plugins->unload(lib->plugins); #ifdef CAPABILITIES_LIBCAP @@ -113,15 +124,10 @@ static void destroy(private_daemon_t *this) #endif /* CAPABILITIES_LIBCAP */ DESTROY_IF(this->kernel_handler); DESTROY_IF(this->public.traps); + DESTROY_IF(this->public.shunts); DESTROY_IF(this->public.ike_sa_manager); DESTROY_IF(this->public.controller); DESTROY_IF(this->public.eap); - DESTROY_IF(this->public.sim); - DESTROY_IF(this->public.tnccs); -#ifdef ME - DESTROY_IF(this->public.connect_manager); - DESTROY_IF(this->public.mediation_manager); -#endif /* ME */ DESTROY_IF(this->public.backends); DESTROY_IF(this->public.socket); @@ -195,27 +201,6 @@ METHOD(daemon_t, start, void, DEFAULT_THREADS)); } -/** - * Log loaded plugins - */ -static void print_plugins() -{ - char buf[512]; - int len = 0; - enumerator_t *enumerator; - plugin_t *plugin; - - buf[0] = '\0'; - enumerator = lib->plugins->create_plugin_enumerator(lib->plugins); - while (len < sizeof(buf) && enumerator->enumerate(enumerator, &plugin)) - { - len += snprintf(&buf[len], sizeof(buf)-len, "%s ", - plugin->get_name(plugin)); - } - enumerator->destroy(enumerator); - DBG1(DBG_DMN, "loaded plugins: %s", buf); -} - METHOD(daemon_t, initialize, bool, private_daemon_t *this) { @@ -236,8 +221,8 @@ METHOD(daemon_t, initialize, bool, { return FALSE; } - - print_plugins(); + DBG1(DBG_DMN, "loaded plugins: %s", + lib->plugins->loaded_plugins(lib->plugins)); this->public.ike_sa_manager = ike_sa_manager_create(); if (this->public.ike_sa_manager == NULL) @@ -287,11 +272,10 @@ private_daemon_t *daemon_create() charon = &this->public; this->public.controller = controller_create(); this->public.eap = eap_manager_create(); - this->public.sim = sim_manager_create(); - this->public.tnccs = tnccs_manager_create(); this->public.backends = backend_manager_create(); this->public.socket = socket_manager_create(); this->public.traps = trap_manager_create(); + this->public.shunts = shunt_manager_create(); this->kernel_handler = kernel_handler_create(); #ifdef CAPABILITIES @@ -322,9 +306,7 @@ void libcharon_deinit() */ bool libcharon_init() { - private_daemon_t *this; - - this = daemon_create(); + daemon_create(); /* for uncritical pseudo random numbers */ srandom(time(NULL) + getpid()); diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h index 04f1fc249..2e01c8d9b 100644 --- a/src/libcharon/daemon.h +++ b/src/libcharon/daemon.h @@ -146,12 +146,9 @@ typedef struct daemon_t daemon_t; #include <bus/listeners/sys_logger.h> #include <sa/ike_sa_manager.h> #include <sa/trap_manager.h> +#include <sa/shunt_manager.h> #include <config/backend_manager.h> #include <sa/authenticators/eap/eap_manager.h> -#include <sa/authenticators/eap/sim_manager.h> -#include <tnc/imc/imc_manager.h> -#include <tnc/imv/imv_manager.h> -#include <tnc/tnccs/tnccs_manager.h> #ifdef ME #include <sa/connect_manager.h> @@ -194,6 +191,11 @@ struct daemon_t { trap_manager_t *traps; /** + * Manager for shunt PASS|DROP policies + */ + shunt_manager_t *shunts; + + /** * Manager for the different configuration backends. */ backend_manager_t *backends; @@ -233,26 +235,6 @@ struct daemon_t { */ eap_manager_t *eap; - /** - * SIM manager to maintain (U)SIM cards/providers - */ - sim_manager_t *sim; - - /** - * TNC IMC manager controlling Integrity Measurement Collectors - */ - imc_manager_t *imcs; - - /** - * TNC IMV manager controlling Integrity Measurement Verifiers - */ - imv_manager_t *imvs; - - /** - * TNCCS manager to maintain registered TNCCS protocols - */ - tnccs_manager_t *tnccs; - #ifdef ME /** * Connect manager diff --git a/src/libcharon/encoding/generator.c b/src/libcharon/encoding/generator.c index ce3844361..60fa7e0c4 100644 --- a/src/libcharon/encoding/generator.c +++ b/src/libcharon/encoding/generator.c @@ -523,7 +523,7 @@ METHOD(generator_t, generate_payload, void, payload_type_names, payload_type); DBG3(DBG_ENC, "generated data for this payload %b", this->buffer + offset_start, - this->out_position - this->buffer - offset_start); + (u_int)(this->out_position - this->buffer - offset_start)); } METHOD(generator_t, destroy, void, diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 214612fdb..2b5399294 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -63,13 +63,13 @@ typedef struct { /* Payload type */ payload_type_t type; - /* Minimal occurence of this payload. */ + /* Minimal occurrence of this payload. */ size_t min_occurence; - /* Max occurence of this payload. */ + /* Max occurrence of this payload. */ size_t max_occurence; /* TRUE if payload must be encrypted */ bool encrypted; - /* If payload occurs, the message rule is fullfilled */ + /* If payload occurs, the message rule is fulfilled */ bool sufficient; } payload_rule_t; @@ -861,9 +861,23 @@ static char* get_string(private_message_t *this, char *buf, int len) len -= written; if (payload->get_type(payload) == NOTIFY) { - notify_payload_t *notify = (notify_payload_t*)payload; - written = snprintf(pos, len, "(%N)", notify_type_short_names, - notify->get_notify_type(notify)); + notify_payload_t *notify; + notify_type_t type; + chunk_t data; + + notify = (notify_payload_t*)payload; + type = notify->get_notify_type(notify); + data = notify->get_notification_data(notify); + if (type == MS_NOTIFY_STATUS && data.len == 4) + { + written = snprintf(pos, len, "(%N(%d))", notify_type_short_names, + type, untoh32(data.ptr)); + } + else + { + written = snprintf(pos, len, "(%N)", notify_type_short_names, + type); + } if (written >= len || written < 0) { return buf; @@ -1065,7 +1079,7 @@ METHOD(message_t, generate, status_t, encryption_payload_t *encryption = NULL; enumerator_t *enumerator; chunk_t chunk; - char str[256]; + char str[BUF_LEN]; u_int32_t *lenpos; bool *reserved; int i; @@ -1312,7 +1326,7 @@ static status_t decrypt_payloads(private_message_t *this, aead_t *aead) DBG2(DBG_ENC, "found an encryption payload"); - if (enumerator->enumerate(enumerator, &payload)) + if (this->payloads->has_more(this->payloads, enumerator)) { DBG1(DBG_ENC, "encrypted payload is not last payload"); status = VERIFY_ERROR; @@ -1405,7 +1419,7 @@ static status_t verify(private_message_t *this) if (found > rule->max_occurence) { DBG1(DBG_ENC, "payload of type %N more than %d times (%d) " - "occured in current message", payload_type_names, + "occurred in current message", payload_type_names, type, rule->max_occurence, found); enumerator->destroy(enumerator); return VERIFY_ERROR; @@ -1416,7 +1430,7 @@ static status_t verify(private_message_t *this) if (!complete && found < rule->min_occurence) { - DBG1(DBG_ENC, "payload of type %N not occured %d times (%d)", + DBG1(DBG_ENC, "payload of type %N not occurred %d times (%d)", payload_type_names, rule->type, rule->min_occurence, found); return VERIFY_ERROR; } @@ -1434,7 +1448,7 @@ METHOD(message_t, parse_body, status_t, status_t status = SUCCESS; payload_t *payload; payload_type_t type; - char str[256]; + char str[BUF_LEN]; type = this->first_payload; diff --git a/src/libcharon/encoding/message.h b/src/libcharon/encoding/message.h index 51197308c..0e78ea436 100644 --- a/src/libcharon/encoding/message.h +++ b/src/libcharon/encoding/message.h @@ -321,7 +321,7 @@ struct message_t { /** * Find a payload of a specific type. * - * Returns the first occurance. + * Returns the first occurrence. * * @param type type of the payload to find * @return payload, or NULL if no such payload found diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c index 32cefb9e7..e49210309 100644 --- a/src/libcharon/encoding/parser.c +++ b/src/libcharon/encoding/parser.c @@ -86,12 +86,6 @@ struct private_parser_t { }; /** - * Forward declaration - */ -static status_t parse_payload(private_parser_t *this, - payload_type_t payload_type, payload_t **payload); - -/** * Log invalid length error */ static bool short_input(private_parser_t *this, int number) @@ -320,7 +314,8 @@ static bool parse_list(private_parser_t *this, int rule_number, DBG2(DBG_ENC, " %d bytes left, parsing recursively %N", length, payload_type_names, payload_type); - if (parse_payload(this, payload_type, &payload) != SUCCESS) + if (this->public.parse_payload(&this->public, payload_type, + &payload) != SUCCESS) { DBG1(DBG_ENC, " parsing of a %N substructure failed", payload_type_names, payload_type); @@ -363,11 +358,8 @@ static bool parse_chunk(private_parser_t *this, int rule_number, return TRUE; } -/** - * Implementation of parser_t.parse_payload. - */ -static status_t parse_payload(private_parser_t *this, - payload_type_t payload_type, payload_t **payload) +METHOD(parser_t, parse_payload, status_t, + private_parser_t *this, payload_type_t payload_type, payload_t **payload) { payload_t *pld; void *output; @@ -385,7 +377,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_names, payload_type, this->input_roof - this->byte_pos); DBG3(DBG_ENC, "parsing payload from %b", - this->byte_pos, this->input_roof - this->byte_pos); + this->byte_pos, (u_int)(this->input_roof - this->byte_pos)); /* base pointer for output, avoids casting in every rule */ output = pld; @@ -785,27 +777,21 @@ static status_t parse_payload(private_parser_t *this, return SUCCESS; } -/** - * Implementation of parser_t.get_remaining_byte_count. - */ -static int get_remaining_byte_count (private_parser_t *this) +METHOD(parser_t, get_remaining_byte_count, int, + private_parser_t *this) { return this->input_roof - this->byte_pos; } -/** - * Implementation of parser_t.reset_context. - */ -static void reset_context (private_parser_t *this) +METHOD(parser_t, reset_context, void, + private_parser_t *this) { this->byte_pos = this->input; this->bit_pos = 0; } -/** - * Implementation of parser_t.destroy. - */ -static void destroy(private_parser_t *this) +METHOD(parser_t, destroy, void, + private_parser_t *this) { free(this); } @@ -815,17 +801,19 @@ static void destroy(private_parser_t *this) */ parser_t *parser_create(chunk_t data) { - private_parser_t *this = malloc_thing(private_parser_t); - - this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**))parse_payload; - this->public.reset_context = (void(*)(parser_t*)) reset_context; - this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count; - this->public.destroy = (void(*)(parser_t*)) destroy; - - this->input = data.ptr; - this->byte_pos = data.ptr; - this->bit_pos = 0; - this->input_roof = data.ptr + data.len; + private_parser_t *this; + + INIT(this, + .public = { + .parse_payload = _parse_payload, + .reset_context = _reset_context, + .get_remaining_byte_count = _get_remaining_byte_count, + .destroy = _destroy, + }, + .input = data.ptr, + .byte_pos = data.ptr, + .input_roof = data.ptr + data.len, + ); return &this->public; } diff --git a/src/libcharon/encoding/payloads/certreq_payload.c b/src/libcharon/encoding/payloads/certreq_payload.c index 8e0836f0e..02015f273 100644 --- a/src/libcharon/encoding/payloads/certreq_payload.c +++ b/src/libcharon/encoding/payloads/certreq_payload.c @@ -111,8 +111,7 @@ METHOD(payload_t, verify, status_t, { if (this->encoding == ENC_X509_SIGNATURE) { - if (this->data.len < HASH_SIZE_SHA1 || - this->data.len % HASH_SIZE_SHA1) + if (this->data.len % HASH_SIZE_SHA1) { DBG1(DBG_ENC, "invalid X509 hash length (%d) in certreq", this->data.len); diff --git a/src/libcharon/encoding/payloads/cp_payload.h b/src/libcharon/encoding/payloads/cp_payload.h index 7dcf58f7e..afae6091a 100644 --- a/src/libcharon/encoding/payloads/cp_payload.h +++ b/src/libcharon/encoding/payloads/cp_payload.h @@ -63,7 +63,7 @@ struct cp_payload_t { payload_t payload_interface; /** - * Creates an iterator of stored configuration_attribute_t objects. + * Creates an enumerator of stored configuration_attribute_t objects. * * @return enumerator over configration_attribute_T */ diff --git a/src/libcharon/encoding/payloads/eap_payload.c b/src/libcharon/encoding/payloads/eap_payload.c index eafb668b6..cacaef222 100644 --- a/src/libcharon/encoding/payloads/eap_payload.c +++ b/src/libcharon/encoding/payloads/eap_payload.c @@ -284,6 +284,18 @@ eap_payload_t *eap_payload_create_data(chunk_t data) /* * Described in header */ +eap_payload_t *eap_payload_create_data_own(chunk_t data) +{ + eap_payload_t *this = eap_payload_create(); + + this->set_data(this, data); + free(data.ptr); + return this; +} + +/* + * Described in header + */ eap_payload_t *eap_payload_create_code(eap_code_t code, u_int8_t identifier) { chunk_t data; diff --git a/src/libcharon/encoding/payloads/eap_payload.h b/src/libcharon/encoding/payloads/eap_payload.h index 0bde4b15e..60d9c99d2 100644 --- a/src/libcharon/encoding/payloads/eap_payload.h +++ b/src/libcharon/encoding/payloads/eap_payload.h @@ -95,18 +95,27 @@ struct eap_payload_t { /** * Creates an empty eap_payload_t object. * - * @return eap_payload_t object + * @return eap_payload_t object */ eap_payload_t *eap_payload_create(void); /** * Creates an eap_payload_t object with data. * - * @return eap_payload_t object + * @param data data, gets cloned + * @return eap_payload_t object */ eap_payload_t *eap_payload_create_data(chunk_t data); /** + * Creates an eap_payload_t object with data, owning the data. + * + * @param data data on heap, gets owned and freed + * @return eap_payload_t object + */ +eap_payload_t *eap_payload_create_data_own(chunk_t data); + +/** * Creates an eap_payload_t object with a code. * * Could should be either EAP_SUCCESS/EAP_FAILURE, use diff --git a/src/libcharon/encoding/payloads/encryption_payload.c b/src/libcharon/encoding/payloads/encryption_payload.c index 3b23ea9fb..e7b8063b7 100644 --- a/src/libcharon/encoding/payloads/encryption_payload.c +++ b/src/libcharon/encoding/payloads/encryption_payload.c @@ -142,7 +142,7 @@ METHOD(payload_t, set_next_type, void, } /** - * Compute the lenght of the whole payload + * Compute the length of the whole payload */ static void compute_length(private_encryption_payload_t *this) { diff --git a/src/libcharon/encoding/payloads/endpoint_notify.c b/src/libcharon/encoding/payloads/endpoint_notify.c index faec1ea71..1ead0a052 100644 --- a/src/libcharon/encoding/payloads/endpoint_notify.c +++ b/src/libcharon/encoding/payloads/endpoint_notify.c @@ -76,6 +76,11 @@ ENUM(me_endpoint_type_names, HOST, RELAYED, ); /** + * Forward declaration + */ +static private_endpoint_notify_t *endpoint_notify_create(); + +/** * Helper functions to parse integer values */ static status_t parse_uint8(u_int8_t **cur, u_int8_t *top, u_int8_t *val) @@ -216,10 +221,8 @@ static chunk_t build_notification_data(private_endpoint_notify_t *this) return data; } -/** - * Implementation of endpoint_notify_t.build_notify - */ -static notify_payload_t *build_notify(private_endpoint_notify_t *this) +METHOD(endpoint_notify_t, build_notify, notify_payload_t*, + private_endpoint_notify_t *this) { chunk_t data; notify_payload_t *notify; @@ -233,64 +236,53 @@ static notify_payload_t *build_notify(private_endpoint_notify_t *this) return notify; } -/** - * Implementation of endpoint_notify_t.get_priority. - */ -static u_int32_t get_priority(private_endpoint_notify_t *this) + +METHOD(endpoint_notify_t, get_priority, u_int32_t, + private_endpoint_notify_t *this) { return this->priority; } -/** - * Implementation of endpoint_notify_t.set_priority. - */ -static void set_priority(private_endpoint_notify_t *this, u_int32_t priority) +METHOD(endpoint_notify_t, set_priority, void, + private_endpoint_notify_t *this, u_int32_t priority) { this->priority = priority; } -/** - * Implementation of endpoint_notify_t.get_type. - */ -static me_endpoint_type_t get_type(private_endpoint_notify_t *this) +METHOD(endpoint_notify_t, get_type, me_endpoint_type_t, + private_endpoint_notify_t *this) { return this->type; } -/** - * Implementation of endpoint_notify_t.get_family. - */ -static me_endpoint_family_t get_family(private_endpoint_notify_t *this) +METHOD(endpoint_notify_t, get_family, me_endpoint_family_t, + private_endpoint_notify_t *this) { return this->family; } -/** - * Implementation of endpoint_notify_t.get_host. - */ -static host_t *get_host(private_endpoint_notify_t *this) +METHOD(endpoint_notify_t, get_host, host_t*, + private_endpoint_notify_t *this) { return this->endpoint; } -/** - * Implementation of endpoint_notify_t.get_base. - */ -static host_t *get_base(private_endpoint_notify_t *this) +METHOD(endpoint_notify_t, get_base, host_t*, + private_endpoint_notify_t *this) { return (!this->base) ? this->endpoint : this->base; } -/** - * Implementation of endpoint_notify_t.clone. - */ -static endpoint_notify_t *_clone(private_endpoint_notify_t *this) +METHOD(endpoint_notify_t, clone_, endpoint_notify_t*, + private_endpoint_notify_t *this) { - private_endpoint_notify_t *clone = (private_endpoint_notify_t*)endpoint_notify_create(); + private_endpoint_notify_t *clone; + clone = endpoint_notify_create(); clone->priority = this->priority; clone->type = this->type; clone->family = this->family; + if (this->endpoint) { clone->endpoint = this->endpoint->clone(this->endpoint); @@ -304,52 +296,47 @@ static endpoint_notify_t *_clone(private_endpoint_notify_t *this) return &clone->public; } -/** - * Implementation of endpoint_notify_t.destroy. - */ -static status_t destroy(private_endpoint_notify_t *this) +METHOD(endpoint_notify_t, destroy, void, + private_endpoint_notify_t *this) { DESTROY_IF(this->endpoint); DESTROY_IF(this->base); free(this); - return SUCCESS; } -/* - * Described in header +/** + * Creates an empty endpoint notify */ -endpoint_notify_t *endpoint_notify_create() +static private_endpoint_notify_t *endpoint_notify_create() { - private_endpoint_notify_t *this = malloc_thing(private_endpoint_notify_t); - - /* public functions */ - this->public.get_priority = (u_int32_t (*) (endpoint_notify_t *)) get_priority; - this->public.set_priority = (void (*) (endpoint_notify_t *, u_int32_t)) set_priority; - this->public.get_type = (me_endpoint_type_t (*) (endpoint_notify_t *)) get_type; - this->public.get_family = (me_endpoint_family_t (*) (endpoint_notify_t *)) get_family; - this->public.get_host = (host_t *(*) (endpoint_notify_t *)) get_host; - this->public.get_base = (host_t *(*) (endpoint_notify_t *)) get_base; - this->public.build_notify = (notify_payload_t *(*) (endpoint_notify_t *)) build_notify; - this->public.clone = (endpoint_notify_t *(*) (endpoint_notify_t *)) _clone; - this->public.destroy = (void (*) (endpoint_notify_t *)) destroy; - - /* set default values of the fields */ - this->priority = 0; - this->family = NO_FAMILY; - this->type = NO_TYPE; - this->endpoint = NULL; - this->base = NULL; - - return &this->public; + private_endpoint_notify_t *this; + + INIT(this, + .public = { + .get_priority = _get_priority, + .set_priority = _set_priority, + .get_type = _get_type, + .get_family = _get_family, + .get_host = _get_host, + .get_base = _get_base, + .build_notify = _build_notify, + .clone = _clone_, + .destroy = _destroy, + }, + .family = NO_FAMILY, + .type = NO_TYPE, + ); + + return this; } /** * Described in header */ -endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type, host_t *host, host_t *base) +endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type, + host_t *host, host_t *base) { - private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create(); - + private_endpoint_notify_t *this = endpoint_notify_create(); this->type = type; switch(type) @@ -406,13 +393,17 @@ endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type, hos */ endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify) { + private_endpoint_notify_t *this; + chunk_t data; + if (notify->get_notify_type(notify) != ME_ENDPOINT) { return NULL; } - private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create(); - chunk_t data = notify->get_notification_data(notify); + this = endpoint_notify_create(); + data = notify->get_notification_data(notify); + if (parse_notification_data(this, data) != SUCCESS) { destroy(this); diff --git a/src/libcharon/encoding/payloads/endpoint_notify.h b/src/libcharon/encoding/payloads/endpoint_notify.h index 120eef49a..853aadf3d 100644 --- a/src/libcharon/encoding/payloads/endpoint_notify.h +++ b/src/libcharon/encoding/payloads/endpoint_notify.h @@ -125,7 +125,7 @@ struct endpoint_notify_t { /** * Generates a notification payload from this endpoint. * - * @return built notify_payload_t + * @return built notify_payload_t */ notify_payload_t *(*build_notify) (endpoint_notify_t *this); @@ -143,19 +143,12 @@ struct endpoint_notify_t { }; /** - * Creates an empty endpoint_notify_t object. - * - * @return created endpoint_notify_t object - */ -endpoint_notify_t *endpoint_notify_create(void); - - -/** * Creates an endpoint_notify_t object from a host. * * @param type the endpoint type * @param host host to base the notify on (gets cloned) - * @param base base of the endpoint, applies only to reflexive endpoints (gets cloned) + * @param base base of the endpoint, applies only to reflexive + * endpoints (gets cloned) * @return created endpoint_notify_t object */ endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type, @@ -166,7 +159,7 @@ endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type, * * @param notify the notify payload * @return - created endpoint_notify_t object - * - NULL if invalid payload + * - NULL if invalid payload */ endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify); diff --git a/src/libcharon/encoding/payloads/ike_header.c b/src/libcharon/encoding/payloads/ike_header.c index 80dcee0cb..24d22f3a1 100644 --- a/src/libcharon/encoding/payloads/ike_header.c +++ b/src/libcharon/encoding/payloads/ike_header.c @@ -101,17 +101,18 @@ struct private_ike_header_t { ENUM_BEGIN(exchange_type_names, EXCHANGE_TYPE_UNDEFINED, EXCHANGE_TYPE_UNDEFINED, "EXCHANGE_TYPE_UNDEFINED"); -ENUM_NEXT(exchange_type_names, IKE_SA_INIT, INFORMATIONAL, EXCHANGE_TYPE_UNDEFINED, +ENUM_NEXT(exchange_type_names, IKE_SA_INIT, IKE_SESSION_RESUME, EXCHANGE_TYPE_UNDEFINED, "IKE_SA_INIT", "IKE_AUTH", "CREATE_CHILD_SA", - "INFORMATIONAL"); + "INFORMATIONAL", + "IKE_SESSION_RESUME"); #ifdef ME -ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, INFORMATIONAL, +ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, IKE_SESSION_RESUME, "ME_CONNECT"); ENUM_END(exchange_type_names, ME_CONNECT); #else -ENUM_END(exchange_type_names, INFORMATIONAL); +ENUM_END(exchange_type_names, IKE_SESSION_RESUME); #endif /* ME */ /** diff --git a/src/libcharon/encoding/payloads/ike_header.h b/src/libcharon/encoding/payloads/ike_header.h index f52c852c5..5579a4961 100644 --- a/src/libcharon/encoding/payloads/ike_header.h +++ b/src/libcharon/encoding/payloads/ike_header.h @@ -80,6 +80,11 @@ enum exchange_type_t{ * INFORMATIONAL. */ INFORMATIONAL = 37, + + /** + * IKE_SESSION_RESUME (RFC 5723). + */ + IKE_SESSION_RESUME = 38, #ifdef ME /** * ME_CONNECT diff --git a/src/libcharon/encoding/payloads/notify_payload.c b/src/libcharon/encoding/payloads/notify_payload.c index 77f15ec6d..e03d1af67 100644 --- a/src/libcharon/encoding/payloads/notify_payload.c +++ b/src/libcharon/encoding/payloads/notify_payload.c @@ -56,7 +56,9 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTIC "CHILD_SA_NOT_FOUND"); ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND, "ME_CONNECT_FAILED"); -ENUM_NEXT(notify_type_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_CONNECT_FAILED, +ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED, + "MS_NOTIFY_STATUS"); +ENUM_NEXT(notify_type_names, INITIAL_CONTACT, PSK_CONFIRM, MS_NOTIFY_STATUS, "INITIAL_CONTACT", "SET_WINDOW_SIZE", "ADDITIONAL_TS_POSSIBLE", @@ -90,18 +92,28 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_CONNEC "LINK_ID", "USE_WESP_MODE", "ROHC_SUPPORTED", - "EAP_ONLY_AUTHENTICATION"); -ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION, + "EAP_ONLY_AUTHENTICATION", + "CHILDLESS_IKEV2_SUPPORTED", + "QUICK_CRASH_DETECTION", + "IKEV2_MESSAGE_ID_SYNC_SUPPORTED", + "IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED", + "IKEV2_MESSAGE_ID_SYNC", + "IPSEC_REPLAY_COUNTER_SYNC", + "SECURE PASSWORD_METHOD", + "PSK_PERSIST", + "PSK_CONFIRM"); +ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, PSK_CONFIRM, "USE_BEET_MODE"); -ENUM_NEXT(notify_type_names, ME_MEDIATION, ME_RESPONSE, USE_BEET_MODE, +ENUM_NEXT(notify_type_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE, "ME_MEDIATION", "ME_ENDPOINT", "ME_CALLBACK", "ME_CONNECTID", "ME_CONNECTKEY", "ME_CONNECTAUTH", - "ME_RESPONSE"); -ENUM_END(notify_type_names, ME_RESPONSE); + "ME_RESPONSE", + "RADIUS_ATTRIBUTE",); +ENUM_END(notify_type_names, RADIUS_ATTRIBUTE); ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD, @@ -135,11 +147,13 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUT "NO_CHILD_SA"); ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND, "ME_CONN_FAIL"); -ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_CONNECT_FAILED, +ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED, + "MS_STATUS"); +ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, PSK_CONFIRM, MS_NOTIFY_STATUS, "INIT_CONTACT", "SET_WINSIZE", "ADD_TS_POSS", - "IPCOMP_SUPP", + "IPCOMP_SUP", "NATD_S_IP", "NATD_D_IP", "COOKIE", @@ -169,18 +183,28 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_ "LINK_ID", "WESP_MODE", "ROHC_SUP", - "EAP_ONLY"); -ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION, + "EAP_ONLY", + "CHDLESS_SUP", + "CRASH_DET", + "MSG_ID_SYN_SUP", + "RPL_CTR_SYN_SUP", + "MSG_ID_SYN", + "RPL_CTR_SYN", + "SEC_PASSWD", + "PSK_PST", + "PSK_CFM"); +ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, PSK_CONFIRM, "BEET_MODE"); -ENUM_NEXT(notify_type_short_names, ME_MEDIATION, ME_RESPONSE, USE_BEET_MODE, +ENUM_NEXT(notify_type_short_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE, "ME_MED", "ME_EP", "ME_CB", "ME_CID", "ME_CKEY", "ME_CAUTH", - "ME_R"); -ENUM_END(notify_type_short_names, ME_RESPONSE); + "ME_R", + "RADIUS"); +ENUM_END(notify_type_short_names, RADIUS_ATTRIBUTE); typedef struct private_notify_payload_t private_notify_payload_t; diff --git a/src/libcharon/encoding/payloads/notify_payload.h b/src/libcharon/encoding/payloads/notify_payload.h index 8abc236e1..ced282700 100644 --- a/src/libcharon/encoding/payloads/notify_payload.h +++ b/src/libcharon/encoding/payloads/notify_payload.h @@ -71,6 +71,9 @@ enum notify_type_t { /* IKE-ME, private use */ ME_CONNECT_FAILED = 8192, + /* Windows error code */ + MS_NOTIFY_STATUS = 12345, + /* notify status messages */ INITIAL_CONTACT = 16384, SET_WINDOW_SIZE = 16385, @@ -115,7 +118,20 @@ enum notify_type_t { ROHC_SUPPORTED = 16416, /* EAP-only authentication, RFC 5998 */ EAP_ONLY_AUTHENTICATION = 16417, - + /* Childless initiation of IKEv2 SA, RFC 6023 */ + CHILDLESS_IKEV2_SUPPORTED = 16418, + /* Quick crash detection for IKE, RFC 6290 */ + QUICK_CRASH_DETECTION = 16419, + /* High availability of IKEv2/IPsec, RFC 6311 */ + IKEV2_MESSAGE_ID_SYNC_SUPPORTED = 16420, + IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED = 16421, + IKEV2_MESSAGE_ID_SYNC = 16422, + IPSEC_REPLAY_COUNTER_SYNC = 16423, + /* Secure password methods, RFC 6467 */ + SECURE_PASSWORD_METHOD = 16424, + /* PACE - draft-kuegler-ipsecme-pace-ikev2 */ + PSK_PERSIST = 16425, + PSK_CONFIRM = 16426, /* BEET mode, not even a draft yet. private use */ USE_BEET_MODE = 40961, /* IKE-ME, private use */ @@ -125,7 +141,9 @@ enum notify_type_t { ME_CONNECTID = 40965, ME_CONNECTKEY = 40966, ME_CONNECTAUTH = 40967, - ME_RESPONSE = 40968 + ME_RESPONSE = 40968, + /* RADIUS attribute received/to send to a AAA backend */ + RADIUS_ATTRIBUTE = 40969, }; /** diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c index d1e677db7..a2c0a4385 100644 --- a/src/libcharon/encoding/payloads/payload.c +++ b/src/libcharon/encoding/payloads/payload.c @@ -39,7 +39,8 @@ ENUM_BEGIN(payload_type_names, NO_PAYLOAD, NO_PAYLOAD, "NO_PAYLOAD"); -ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD, +ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, + GENERIC_SECURE_PASSWORD_METHOD, NO_PAYLOAD, "SECURITY_ASSOCIATION", "KEY_EXCHANGE", "ID_INITIATOR", @@ -55,9 +56,10 @@ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, N "TRAFFIC_SELECTOR_RESPONDER", "ENCRYPTED", "CONFIGURATION", - "EXTENSIBLE_AUTHENTICATION"); + "EXTENSIBLE_AUTHENTICATION", + "GENERIC_SECURE_PASSWORD_METHOD"); #ifdef ME -ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION, +ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, GENERIC_SECURE_PASSWORD_METHOD, "ID_PEER"); ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER, "HEADER", @@ -67,7 +69,8 @@ ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER, "TRAFFIC_SELECTOR_SUBSTRUCTURE", "CONFIGURATION_ATTRIBUTE"); #else -ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, EXTENSIBLE_AUTHENTICATION, +ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, + GENERIC_SECURE_PASSWORD_METHOD, "HEADER", "PROPOSAL_SUBSTRUCTURE", "TRANSFORM_SUBSTRUCTURE", @@ -80,7 +83,8 @@ ENUM_END(payload_type_names, CONFIGURATION_ATTRIBUTE); /* short forms of payload names */ ENUM_BEGIN(payload_type_short_names, NO_PAYLOAD, NO_PAYLOAD, "--"); -ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD, +ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, + GENERIC_SECURE_PASSWORD_METHOD, NO_PAYLOAD, "SA", "KE", "IDi", @@ -96,9 +100,11 @@ ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICAT "TSr", "E", "CP", - "EAP"); + "EAP", + "GSPM"); #ifdef ME -ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION, +ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, + GENERIC_SECURE_PASSWORD_METHOD, "IDp"); ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER, "HDR", @@ -108,7 +114,8 @@ ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER, "TSSUB", "CPATTR"); #else -ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, EXTENSIBLE_AUTHENTICATION, +ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, + GENERIC_SECURE_PASSWORD_METHOD, "HDR", "PROP", "TRANS", diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h index 0f407ff42..a9af29b5b 100644 --- a/src/libcharon/encoding/payloads/payload.h +++ b/src/libcharon/encoding/payloads/payload.h @@ -79,7 +79,7 @@ enum payload_type_t{ AUTHENTICATION = 39, /** - * Nonces, for initator and responder (Ni, Nr, N) + * Nonces, for initiator and responder (Ni, Nr, N) */ NONCE = 40, @@ -123,6 +123,11 @@ enum payload_type_t{ */ EXTENSIBLE_AUTHENTICATION = 48, + /** + * Generic Secure Password Method (GSPM). + */ + GENERIC_SECURE_PASSWORD_METHOD = 49, + #ifdef ME /** * Identification payload for peers has a value from diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c index f39c3b0e6..4753d574d 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.c +++ b/src/libcharon/encoding/payloads/proposal_substructure.c @@ -407,7 +407,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal( this = (private_proposal_substructure_t*)proposal_substructure_create(); - /* encryption algorithm is only availble in ESP */ + /* encryption algorithm is only available in ESP */ enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM); while (enumerator->enumerate(enumerator, &alg, &key_size)) { diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c index db20d052f..010f63cfd 100644 --- a/src/libcharon/encoding/payloads/sa_payload.c +++ b/src/libcharon/encoding/payloads/sa_payload.c @@ -106,7 +106,6 @@ METHOD(payload_t, verify, status_t, status_t status = SUCCESS; enumerator_t *enumerator; proposal_substructure_t *substruct; - bool first = TRUE; /* check proposal numbering */ enumerator = this->proposals->create_enumerator(this->proposals); @@ -115,16 +114,6 @@ METHOD(payload_t, verify, status_t, current_number = substruct->get_proposal_number(substruct); if (current_number < expected_number) { - if (current_number != expected_number + 1) - { - DBG1(DBG_ENC, "proposal number is %d, expected %d or %d", - current_number, expected_number, expected_number + 1); - status = FAILED; - break; - } - } - else if (current_number < expected_number) - { DBG1(DBG_ENC, "proposal number smaller than previous"); status = FAILED; break; @@ -136,7 +125,6 @@ METHOD(payload_t, verify, status_t, DBG1(DBG_ENC, "PROPOSAL_SUBSTRUCTURE verification failed"); break; } - first = FALSE; expected_number = current_number; } enumerator->destroy(enumerator); diff --git a/src/libcharon/encoding/payloads/transform_substructure.c b/src/libcharon/encoding/payloads/transform_substructure.c index 0428da726..3f04b3539 100644 --- a/src/libcharon/encoding/payloads/transform_substructure.c +++ b/src/libcharon/encoding/payloads/transform_substructure.c @@ -84,7 +84,7 @@ encoding_rule_t transform_substructure_encodings[] = { { U_INT_8, offsetof(private_transform_substructure_t, transform_type) }, /* 1 Reserved Byte */ { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) }, - /* tranform ID is a number of 8 bit */ + /* transform ID is a number of 8 bit */ { U_INT_16, offsetof(private_transform_substructure_t, transform_id) }, /* Attributes are stored in a transform attribute, offset points to a linked_list_t pointer */ diff --git a/src/libcharon/encoding/payloads/transform_substructure.h b/src/libcharon/encoding/payloads/transform_substructure.h index c961700a4..102dbb3d3 100644 --- a/src/libcharon/encoding/payloads/transform_substructure.h +++ b/src/libcharon/encoding/payloads/transform_substructure.h @@ -118,7 +118,7 @@ transform_substructure_t *transform_substructure_create(void); * * @param type type of transform to create * @param id transform id specifc for the transform type - * @param key_length key length for key lenght attribute, 0 to omit + * @param key_length key length for key length attribute, 0 to omit * @return transform_substructure_t object */ transform_substructure_t *transform_substructure_create_type( diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c index d9e39fe43..51fccb1ac 100644 --- a/src/libcharon/kernel/kernel_handler.c +++ b/src/libcharon/kernel/kernel_handler.c @@ -125,6 +125,8 @@ METHOD(kernel_listener_t, roam, bool, private_kernel_handler_t *this, bool address) { job_t *job; + DBG2(DBG_KNL, "creating roam job %s", address ? "due to address/link change" + : "due to route change"); job = (job_t*)roam_job_create(address); lib->processor->queue_job(lib->processor, job); return TRUE; diff --git a/src/libcharon/network/receiver.c b/src/libcharon/network/receiver.c index d8cebe192..cfb1408ef 100644 --- a/src/libcharon/network/receiver.c +++ b/src/libcharon/network/receiver.c @@ -30,6 +30,8 @@ /** lifetime of a cookie, in seconds */ #define COOKIE_LIFETIME 10 +/** time we wait before disabling cookies */ +#define COOKIE_CALMDOWN_DELAY 10 /** how many times to reuse the secret */ #define COOKIE_REUSE 10000 /** default value for private_receiver_t.cookie_threshold */ @@ -96,11 +98,26 @@ struct private_receiver_t { u_int32_t cookie_threshold; /** + * timestamp of last cookie requested + */ + time_t last_cookie; + + /** * how many half open IKE_SAs per peer before blocking */ u_int32_t block_threshold; /** + * Drop IKE_SA_INIT requests if processor job load exceeds this limit + */ + u_int init_limit_job_load; + + /** + * Drop IKE_SA_INIT requests if half open IKE_SA count exceeds this limit + */ + u_int init_limit_half_open; + + /** * Delay for receiving incoming packets, to simulate larger RTT */ int receive_delay; @@ -215,55 +232,146 @@ static bool cookie_verify(private_receiver_t *this, message_t *message, } /** - * check if cookies are required, and if so, a valid cookie is included + * Check if a valid cookie found */ -static bool cookie_required(private_receiver_t *this, message_t *message) +static bool check_cookie(private_receiver_t *this, message_t *message) { - bool failed = FALSE; - - if (charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager, - NULL) >= this->cookie_threshold) + packet_t *packet; + chunk_t data; + + /* check for a cookie. We don't use our parser here and do it + * quick and dirty for performance reasons. + * we assume the cookie is the first payload (which is a MUST), and + * the cookie's SPI length is zero. */ + packet = message->get_packet(message); + data = packet->get_data(packet); + if (data.len < + IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH + + sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher) || + *(data.ptr + 16) != NOTIFY || + *(u_int16_t*)(data.ptr + IKE_HEADER_LENGTH + 6) != htons(COOKIE)) { - /* check for a cookie. We don't use our parser here and do it - * quick and dirty for performance reasons. - * we assume the cookie is the first payload (which is a MUST), and - * the cookie's SPI length is zero. */ - packet_t *packet = message->get_packet(message); - chunk_t data = packet->get_data(packet); - if (data.len < - IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH + - sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher) || - *(data.ptr + 16) != NOTIFY || - *(u_int16_t*)(data.ptr + IKE_HEADER_LENGTH + 6) != htons(COOKIE)) - { - /* no cookie found */ - failed = TRUE; - } - else - { - data.ptr += IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH; - data.len = sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher); - if (!cookie_verify(this, message, data)) - { - DBG2(DBG_NET, "found cookie, but content invalid"); - failed = TRUE; - } - } + /* no cookie found */ + packet->destroy(packet); + return FALSE; + } + data.ptr += IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH; + data.len = sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher); + if (!cookie_verify(this, message, data)) + { + DBG2(DBG_NET, "found cookie, but content invalid"); packet->destroy(packet); + return FALSE; + } + return TRUE; +} + +/** + * Check if we currently require cookies + */ +static bool cookie_required(private_receiver_t *this, + u_int half_open, u_int32_t now) +{ + if (this->cookie_threshold && half_open >= this->cookie_threshold) + { + this->last_cookie = now; + return TRUE; + } + if (now < this->last_cookie + COOKIE_CALMDOWN_DELAY) + { + /* We don't disable cookies unless we haven't seen IKE_SA_INITs + * for COOKIE_CALMDOWN_DELAY seconds. This avoids jittering between + * cookie on / cookie off states, which is problematic. Consider the + * following: A legitimiate initiator sends a IKE_SA_INIT while we + * are under a DoS attack. If we toggle our cookie behavior, + * multiple retransmits of this IKE_SA_INIT might get answered with + * and without cookies. The initiator goes on and retries with + * a cookie, but it can't know if the completing IKE_SA_INIT response + * is to its IKE_SA_INIT request with or without cookies. This is + * problematic, as the cookie is part of AUTH payload data. + */ + this->last_cookie = now; + return TRUE; } - return failed; + return FALSE; } /** - * check if peer has to many half open IKE_SAs + * Check if we should drop IKE_SA_INIT because of cookie/overload checking */ -static bool peer_too_aggressive(private_receiver_t *this, message_t *message) +static bool drop_ike_sa_init(private_receiver_t *this, message_t *message) { - if (charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager, - message->get_source(message)) >= this->block_threshold) + u_int half_open; + u_int32_t now; + + now = time_monotonic(NULL); + half_open = charon->ike_sa_manager->get_half_open_count( + charon->ike_sa_manager, NULL); + + /* check for cookies */ + if (cookie_required(this, half_open, now) && !check_cookie(this, message)) + { + chunk_t cookie; + + cookie = cookie_build(this, message, now - this->secret_offset, + chunk_from_thing(this->secret)); + DBG2(DBG_NET, "received packet from: %#H to %#H", + message->get_source(message), + message->get_destination(message)); + DBG2(DBG_NET, "sending COOKIE notify to %H", + message->get_source(message)); + send_notify(message, COOKIE, cookie); + chunk_free(&cookie); + if (++this->secret_used > COOKIE_REUSE) + { + /* create new cookie */ + DBG1(DBG_NET, "generating new cookie secret after %d uses", + this->secret_used); + memcpy(this->secret_old, this->secret, SECRET_LENGTH); + this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret); + this->secret_switch = now; + this->secret_used = 0; + } + return TRUE; + } + + /* check if peer has too many IKE_SAs half open */ + if (this->block_threshold && + charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager, + message->get_source(message)) >= this->block_threshold) + { + DBG1(DBG_NET, "ignoring IKE_SA setup from %H, " + "peer too aggressive", message->get_source(message)); + return TRUE; + } + + /* check if global half open IKE_SA limit reached */ + if (this->init_limit_half_open && + half_open >= this->init_limit_half_open) { + DBG1(DBG_NET, "ignoring IKE_SA setup from %H, half open IKE_SA " + "count of %d exceeds limit of %d", message->get_source(message), + half_open, this->init_limit_half_open); return TRUE; } + + /* check if job load acceptable */ + if (this->init_limit_job_load) + { + u_int jobs = 0, i; + + for (i = 0; i < JOB_PRIO_MAX; i++) + { + jobs += lib->processor->get_job_load(lib->processor, i); + } + if (jobs > this->init_limit_job_load) + { + DBG1(DBG_NET, "ignoring IKE_SA setup from %H, job load of %d " + "exceeds limit of %d", message->get_source(message), + jobs, this->init_limit_job_load); + return TRUE; + } + } return FALSE; } @@ -314,39 +422,8 @@ static job_requeue_t receive_packets(private_receiver_t *this) if (message->get_request(message) && message->get_exchange_type(message) == IKE_SA_INIT) { - /* check for cookies */ - if (this->cookie_threshold && cookie_required(this, message)) - { - u_int32_t now = time_monotonic(NULL); - chunk_t cookie = cookie_build(this, message, now - this->secret_offset, - chunk_from_thing(this->secret)); - - DBG2(DBG_NET, "received packet from: %#H to %#H", - message->get_source(message), - message->get_destination(message)); - DBG2(DBG_NET, "sending COOKIE notify to %H", - message->get_source(message)); - send_notify(message, COOKIE, cookie); - chunk_free(&cookie); - if (++this->secret_used > COOKIE_REUSE) - { - /* create new cookie */ - DBG1(DBG_NET, "generating new cookie secret after %d uses", - this->secret_used); - memcpy(this->secret_old, this->secret, SECRET_LENGTH); - this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret); - this->secret_switch = now; - this->secret_used = 0; - } - message->destroy(message); - return JOB_REQUEUE_DIRECT; - } - - /* check if peer has not too many IKE_SAs half open */ - if (this->block_threshold && peer_too_aggressive(this, message)) + if (drop_ike_sa_init(this, message)) { - DBG1(DBG_NET, "ignoring IKE_SA setup from %H, " - "peer too aggressive", message->get_source(message)); message->destroy(message); return JOB_REQUEUE_DIRECT; } @@ -408,6 +485,10 @@ receiver_t *receiver_create() this->block_threshold = lib->settings->get_int(lib->settings, "charon.block_threshold", BLOCK_THRESHOLD_DEFAULT); } + this->init_limit_job_load = lib->settings->get_int(lib->settings, + "charon.init_limit_job_load", 0); + this->init_limit_half_open = lib->settings->get_int(lib->settings, + "charon.init_limit_half_open", 0); this->receive_delay = lib->settings->get_int(lib->settings, "charon.receive_delay", 0); this->receive_delay_type = lib->settings->get_int(lib->settings, @@ -435,8 +516,8 @@ receiver_t *receiver_create() this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret); memcpy(this->secret_old, this->secret, SECRET_LENGTH); - this->job = callback_job_create((callback_job_cb_t)receive_packets, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)receive_packets, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; diff --git a/src/libcharon/network/receiver.h b/src/libcharon/network/receiver.h index 690d8dbab..1d9d4871e 100644 --- a/src/libcharon/network/receiver.h +++ b/src/libcharon/network/receiver.h @@ -30,7 +30,7 @@ typedef struct receiver_t receiver_t; /** * Receives packets from the socket and adds them to the job queue. * - * The receiver starts a thread, wich reads on the blocking socket. A received + * The receiver starts a thread, which reads on the blocking socket. A received * packet is preparsed and a process_message_job is queued in the job queue. * * To endure DoS attacks, cookies are enabled when to many IKE_SAs are half @@ -38,7 +38,7 @@ typedef struct receiver_t receiver_t; * method in RFC4306. We do not include a nonce, because we think the advantage * we gain does not justify the overhead to parse the whole message. * Instead of VersionIdOfSecret, we include a timestamp. This allows us to - * find out wich key was used for cookie creation. Further, we can set a + * find out which key was used for cookie creation. Further, we can set a * lifetime for the cookie, which allows us to reuse the secret for a longer * time. * COOKIE = time | sha1( IPi | SPIi | time | secret ) diff --git a/src/libcharon/network/sender.c b/src/libcharon/network/sender.c index 4177fb3e1..4df930b15 100644 --- a/src/libcharon/network/sender.c +++ b/src/libcharon/network/sender.c @@ -183,8 +183,8 @@ sender_t * sender_create() .mutex = mutex_create(MUTEX_TYPE_DEFAULT), .got = condvar_create(CONDVAR_TYPE_DEFAULT), .sent = condvar_create(CONDVAR_TYPE_DEFAULT), - .job = callback_job_create((callback_job_cb_t)send_packets, - this, NULL, NULL), + .job = callback_job_create_with_prio((callback_job_cb_t)send_packets, + this, NULL, NULL, JOB_PRIO_CRITICAL), .send_delay = lib->settings->get_int(lib->settings, "charon.send_delay", 0), .send_delay_type = lib->settings->get_int(lib->settings, diff --git a/src/libcharon/network/socket.c b/src/libcharon/network/socket.c new file mode 100644 index 000000000..cdb14b4a0 --- /dev/null +++ b/src/libcharon/network/socket.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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. + */ + +#include "socket.h" + +#include <daemon.h> + +/** + * See header + */ +bool socket_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data) +{ + if (reg) + { + charon->socket->add_socket(charon->socket, (socket_constructor_t)data); + } + else + { + charon->socket->remove_socket(charon->socket, + (socket_constructor_t)data); + } + return TRUE; +} diff --git a/src/libcharon/network/socket.h b/src/libcharon/network/socket.h index 51b26920f..be875035b 100644 --- a/src/libcharon/network/socket.h +++ b/src/libcharon/network/socket.h @@ -29,6 +29,7 @@ typedef struct socket_t socket_t; #include <library.h> #include <network/packet.h> #include <utils/enumerator.h> +#include <plugins/plugin.h> /** * Constructor prototype for sockets. @@ -72,4 +73,18 @@ struct socket_t { void (*destroy) (socket_t *this); }; +/** + * Helper function to (un-)register socket interfaces from plugin features. + * + * This function is a plugin_feature_callback_t and can be used with the + * PLUGIN_CALLBACK macro to register an socket interface constructor. + * + * @param plugin plugin registering the socket interface + * @param feature associated plugin feature + * @param reg TRUE to register, FALSE to unregister + * @param data data passed to callback, a socket_constructor_t + */ +bool socket_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data); + #endif /** SOCKET_H_ @}*/ diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in index 57aab1db7..3139e20b0 100644 --- a/src/libcharon/plugins/addrblock/Makefile.in +++ b/src/libcharon/plugins/addrblock/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/android/Makefile.in b/src/libcharon/plugins/android/Makefile.in index 08248da12..50e5f638e 100644 --- a/src/libcharon/plugins/android/Makefile.in +++ b/src/libcharon/plugins/android/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/android/android_handler.c b/src/libcharon/plugins/android/android_handler.c index ec3ff7a51..a53962f16 100644 --- a/src/libcharon/plugins/android/android_handler.c +++ b/src/libcharon/plugins/android/android_handler.c @@ -1,6 +1,6 @@ /* + * Copyright (C) 2010-2011 Tobias Brunner * Copyright (C) 2010 Martin Willi - * Copyright (C) 2010 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -36,9 +36,20 @@ struct private_android_handler_t { * List of registered DNS servers */ linked_list_t *dns; + + /** + * Whether the VPN frontend is used + */ + bool frontend; }; /** + * Prefixes to be used when installing DNS servers + */ +#define DNS_PREFIX_DEFAULT "net" +#define DNS_PREFIX_FRONTEND "vpn" + +/** * Struct to store a pair of old and installed DNS servers */ typedef struct { @@ -70,12 +81,13 @@ bool filter_dns_pair(void *data, dns_pair_t **in, host_t **out) /** * Read DNS server property with a given index */ -host_t *get_dns_server(int index) +host_t *get_dns_server(private_android_handler_t *this, int index) { host_t *dns = NULL; - char key[10], value[PROPERTY_VALUE_MAX]; + char key[10], value[PROPERTY_VALUE_MAX], + *prefix = this->frontend ? DNS_PREFIX_FRONTEND : DNS_PREFIX_DEFAULT; - if (snprintf(key, sizeof(key), "vpn.dns%d", index) >= sizeof(key)) + if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key)) { return NULL; } @@ -90,11 +102,12 @@ host_t *get_dns_server(int index) /** * Set DNS server property with a given index */ -bool set_dns_server(int index, host_t *dns) +bool set_dns_server(private_android_handler_t *this, int index, host_t *dns) { - char key[10], value[PROPERTY_VALUE_MAX]; + char key[10], value[PROPERTY_VALUE_MAX], + *prefix = this->frontend ? DNS_PREFIX_FRONTEND : DNS_PREFIX_DEFAULT; - if (snprintf(key, sizeof(key), "vpn.dns%d", index) >= sizeof(key)) + if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key)) { return FALSE; } @@ -136,8 +149,8 @@ METHOD(attribute_handler_t, handle, bool, pair = malloc_thing(dns_pair_t); pair->dns = dns; index = this->dns->get_count(this->dns) + 1; - pair->old = get_dns_server(index); - set_dns_server(index, dns); + pair->old = get_dns_server(this, index); + set_dns_server(this, index, dns); this->dns->insert_last(this->dns, pair); return TRUE; } @@ -164,7 +177,7 @@ METHOD(attribute_handler_t, release, void, if (chunk_equals(pair->dns->get_address(pair->dns), data)) { this->dns->remove_at(this->dns, enumerator); - set_dns_server(index, pair->old); + set_dns_server(this, index, pair->old); destroy_dns_pair(pair); } } @@ -204,7 +217,7 @@ METHOD(android_handler_t, destroy, void, /** * See header */ -android_handler_t *android_handler_create() +android_handler_t *android_handler_create(bool frontend) { private_android_handler_t *this; @@ -218,6 +231,7 @@ android_handler_t *android_handler_create() .destroy = _destroy, }, .dns = linked_list_create(), + .frontend = frontend, ); return &this->public; diff --git a/src/libcharon/plugins/android/android_handler.h b/src/libcharon/plugins/android/android_handler.h index af620505b..0170958ee 100644 --- a/src/libcharon/plugins/android/android_handler.h +++ b/src/libcharon/plugins/android/android_handler.h @@ -1,6 +1,6 @@ /* + * Copyright (C) 2010-2011 Tobias Brunner * Copyright (C) 2010 Martin Willi - * Copyright (C) 2010 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -44,7 +44,9 @@ struct android_handler_t { /** * Create a android_handler instance. + * + * @param frontend TRUE if the VPN frontend is used */ -android_handler_t *android_handler_create(); +android_handler_t *android_handler_create(bool frontend); #endif /** ANDROID_HANDLER_H_ @}*/ diff --git a/src/libcharon/plugins/android/android_logger.c b/src/libcharon/plugins/android/android_logger.c index 43c56e656..f7624b2c7 100644 --- a/src/libcharon/plugins/android/android_logger.c +++ b/src/libcharon/plugins/android/android_logger.c @@ -47,18 +47,19 @@ METHOD(listener_t, log_, bool, { if (level <= this->level) { + int prio = level > 1 ? ANDROID_LOG_DEBUG : ANDROID_LOG_INFO; char sgroup[16], buffer[8192]; char *current = buffer, *next; snprintf(sgroup, sizeof(sgroup), "%N", debug_names, group); vsnprintf(buffer, sizeof(buffer), format, args); while (current) - { /* log each line seperately */ + { /* log each line separately */ next = strchr(current, '\n'); if (next) { *(next++) = '\0'; } - __android_log_print(ANDROID_LOG_INFO, "charon", "%.2d[%s] %s\n", + __android_log_print(prio, "charon", "%.2d[%s] %s\n", thread, sgroup, current); current = next; } diff --git a/src/libcharon/plugins/android/android_plugin.c b/src/libcharon/plugins/android/android_plugin.c index 54a7017a1..091f34a8e 100644 --- a/src/libcharon/plugins/android/android_plugin.c +++ b/src/libcharon/plugins/android/android_plugin.c @@ -92,21 +92,16 @@ plugin_t *android_plugin_create() }, }, .logger = android_logger_create(), - .handler = android_handler_create(), .creds = android_creds_create(), ); + this->service = android_service_create(this->creds); + this->handler = android_handler_create(this->service != NULL); + charon->bus->add_listener(charon->bus, &this->logger->listener); lib->credmgr->add_set(lib->credmgr, &this->creds->set); hydra->attributes->add_handler(hydra->attributes, &this->handler->handler); - this->service = android_service_create(this->creds); - if (!this->service) - { - destroy(this); - return NULL; - } - return &this->public.plugin; } diff --git a/src/libcharon/plugins/certexpire/Makefile.am b/src/libcharon/plugins/certexpire/Makefile.am new file mode 100644 index 000000000..9aa0daad3 --- /dev/null +++ b/src/libcharon/plugins/certexpire/Makefile.am @@ -0,0 +1,19 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = -rdynamic \ + -DIPSEC_PIDDIR=\"${piddir}\" + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-certexpire.la +else +plugin_LTLIBRARIES = libstrongswan-certexpire.la +endif + +libstrongswan_certexpire_la_SOURCES = certexpire_plugin.h certexpire_plugin.c \ + certexpire_listener.h certexpire_listener.c \ + certexpire_export.h certexpire_export.c \ + certexpire_cron.h certexpire_cron.c + +libstrongswan_certexpire_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in new file mode 100644 index 000000000..929cce20c --- /dev/null +++ b/src/libcharon/plugins/certexpire/Makefile.in @@ -0,0 +1,621 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libcharon/plugins/certexpire +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +libstrongswan_certexpire_la_LIBADD = +am_libstrongswan_certexpire_la_OBJECTS = certexpire_plugin.lo \ + certexpire_listener.lo certexpire_export.lo certexpire_cron.lo +libstrongswan_certexpire_la_OBJECTS = \ + $(am_libstrongswan_certexpire_la_OBJECTS) +libstrongswan_certexpire_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_certexpire_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_certexpire_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_certexpire_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstrongswan_certexpire_la_SOURCES) +DIST_SOURCES = $(libstrongswan_certexpire_la_SOURCES) +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@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +default_pkcs11 = @default_pkcs11@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +oldincludedir = @oldincludedir@ +openac_plugins = @openac_plugins@ +p_plugins = @p_plugins@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pluto_plugins = @pluto_plugins@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = -rdynamic \ + -DIPSEC_PIDDIR=\"${piddir}\" + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-certexpire.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-certexpire.la +libstrongswan_certexpire_la_SOURCES = certexpire_plugin.h certexpire_plugin.c \ + certexpire_listener.h certexpire_listener.c \ + certexpire_export.h certexpire_export.c \ + certexpire_cron.h certexpire_cron.c + +libstrongswan_certexpire_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/certexpire/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/certexpire/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libstrongswan-certexpire.la: $(libstrongswan_certexpire_la_OBJECTS) $(libstrongswan_certexpire_la_DEPENDENCIES) + $(libstrongswan_certexpire_la_LINK) $(am_libstrongswan_certexpire_la_rpath) $(libstrongswan_certexpire_la_OBJECTS) $(libstrongswan_certexpire_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certexpire_cron.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certexpire_export.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certexpire_listener.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certexpire_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libcharon/plugins/certexpire/certexpire_cron.c b/src/libcharon/plugins/certexpire/certexpire_cron.c new file mode 100644 index 000000000..e8cd4bfd8 --- /dev/null +++ b/src/libcharon/plugins/certexpire/certexpire_cron.c @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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. + */ + +#include "certexpire_cron.h" + +#include <time.h> + +#include <debug.h> +#include <processing/jobs/callback_job.h> + +typedef struct private_certexpire_cron_t private_certexpire_cron_t; + +/** + * Private data of an certexpire_cron_t object. + */ +struct private_certexpire_cron_t { + + /** + * Public certexpire_cron_t interface. + */ + certexpire_cron_t public; + + /** + * time when to run export job + */ + struct { + bool m[60]; + bool h[24]; + bool d[32]; + bool my[13]; + bool dw[8]; + } cron; + + /** + * Callback function to execute + */ + certexpire_cron_job_t job; + + /** + * Data to pass to callback + */ + void *data; +}; + +/** + * Check if we should execute the export job + */ +static job_requeue_t check_cron(private_certexpire_cron_t *this) +{ + struct tm tm; + time_t t; + + t = time(NULL); + localtime_r(&t, &tm); + + /* recheck every minute at second 0 */ + lib->scheduler->schedule_job(lib->scheduler, + (job_t*)callback_job_create_with_prio((callback_job_cb_t)check_cron, + this, NULL, NULL, JOB_PRIO_CRITICAL), 60 - tm.tm_sec); + + /* skip this minute if we had a large negative time shift */ + if (tm.tm_sec <= 30) + { + if (this->cron.m[tm.tm_min] && + this->cron.h[tm.tm_hour] && + this->cron.d[tm.tm_mday] && + this->cron.my[tm.tm_mon + 1] && + (this->cron.dw[tm.tm_wday] || + (this->cron.dw[7] && tm.tm_wday == 0))) + { + this->job(this->data); + } + } + return JOB_REQUEUE_NONE; +} + +/** + * Parse a cron range component into boolean fields + */ +static void parse_ranges(bool *fields, char *label, int mi, int ma, char *range) +{ + enumerator_t *enumerator; + int from, to, i; + + if (streq(range, "*")) + { + for (i = mi; i <= ma; i++) + { + fields[i] = TRUE; + } + } + else + { + enumerator = enumerator_create_token(range, ",", ""); + while (enumerator->enumerate(enumerator, &range)) + { + switch (sscanf(range, "%d-%d", &from, &to)) + { + case 1: /* single value */ + if (from >= mi && from <= ma) + { + fields[from] = TRUE; + } + else + { + DBG1(DBG_CFG, "ignoring cron %s %d, out of range", + label, from); + } + break; + case 2: /* range */ + if (from < mi) + { + DBG1(DBG_CFG, "cron %s out of range, shortening start " + "from %d to %d", label, from, mi); + from = mi; + } + if (to > ma) + { + DBG1(DBG_CFG, "cron %s out of range, shortening end " + "from %d to %d", label, to, ma); + to = ma; + } + for (i = from; i <= to; i++) + { + fields[i] = TRUE; + } + break; + default: + break; + } + } + enumerator->destroy(enumerator); + } + DBG3(DBG_CFG, "cron job with enabled %ss:", label); + for (i = mi; i <= ma; i++) + { + if (fields[i]) + { + DBG3(DBG_CFG, " %d", i); + } + } +} + +/** + * Start cron processing, if configured + */ +static void start_cron(private_certexpire_cron_t *this, char *cron) +{ + enumerator_t *enumerator; + int i = 0; + + enumerator = enumerator_create_token(cron, " ", " "); + for (i = 0; i < 5; i++) + { + if (!enumerator->enumerate(enumerator, &cron)) + { + DBG1(DBG_CFG, "cron misses a field, using '*'"); + cron = "*"; + } + switch (i) + { + case 0: + parse_ranges(this->cron.m, "minute", 0, 59, cron); + break; + case 1: + parse_ranges(this->cron.h, "hour", 0, 23, cron); + break; + case 2: + parse_ranges(this->cron.d, "day", 1, 31, cron); + break; + case 3: + parse_ranges(this->cron.my, "month", 1, 12, cron); + break; + case 4: + parse_ranges(this->cron.dw, "weekday", 0, 7, cron); + break; + default: + break; + } + } + if (enumerator->enumerate(enumerator, &cron)) + { + DBG1(DBG_CFG, "ignoring extra fields in cron"); + } + enumerator->destroy(enumerator); + + check_cron(this); +} + +METHOD(certexpire_cron_t, destroy, void, + private_certexpire_cron_t *this) +{ + free(this); +} + +/** + * See header + */ +certexpire_cron_t *certexpire_cron_create(char *cron, certexpire_cron_job_t job, + void *data) +{ + private_certexpire_cron_t *this; + + INIT(this, + .public = { + .destroy = _destroy, + }, + .job = job, + .data = data, + ); + + start_cron(this, cron); + + return &this->public; +} diff --git a/src/libcharon/plugins/certexpire/certexpire_cron.h b/src/libcharon/plugins/certexpire/certexpire_cron.h new file mode 100644 index 000000000..0d6623d7f --- /dev/null +++ b/src/libcharon/plugins/certexpire/certexpire_cron.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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 certexpire_cron certexpire_cron + * @{ @ingroup certexpire + */ + +#ifndef CERTEXPIRE_CRON_H_ +#define CERTEXPIRE_CRON_H_ + +typedef struct certexpire_cron_t certexpire_cron_t; + +/** + * Callback function invoked by cron. + * + * @param data user specified callback data + */ +typedef void (*certexpire_cron_job_t)(void *data); + +/** + * Cron style job scheduling. + */ +struct certexpire_cron_t { + + /** + * Destroy a certexpire_cron_t. + * + * It currently is not possible to savely cancel a cron job. Make sure + * any scheduled jobs have been canceled before cleaning up. + */ + void (*destroy)(certexpire_cron_t *this); +}; + +/** + * Create a certexpire_cron instance. + * + * The cron string takes numeric arguments only, but supports ranges (1-5) + * and selections (1,3,5), or a combination, space separated: + * minute hour day month weekday + * minute, 0-59 + * hour, 0-23 + * day, 1-31 + * month, 1-12 + * weekday, 0-7 (0 == 7 == sunday) + * man crontab(5) for details. + * + * @param cron cron style scheduling string + * @param job callback function to invoke + * @param data user data to pass to job + */ +certexpire_cron_t *certexpire_cron_create(char *cron, certexpire_cron_job_t job, + void *data); + +#endif /** CERTEXPIRE_CRON_H_ @}*/ diff --git a/src/libcharon/plugins/certexpire/certexpire_export.c b/src/libcharon/plugins/certexpire/certexpire_export.c new file mode 100644 index 000000000..c73b0beda --- /dev/null +++ b/src/libcharon/plugins/certexpire/certexpire_export.c @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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. + */ + +#include "certexpire_export.h" + +#include "certexpire_cron.h" + +#include <time.h> +#include <limits.h> +#include <errno.h> + +#include <debug.h> +#include <utils/hashtable.h> +#include <threading/mutex.h> +#include <credentials/certificates/x509.h> + +typedef struct private_certexpire_export_t private_certexpire_export_t; + +/** + * Private data of an certexpire_export_t object. + */ +struct private_certexpire_export_t { + + /** + * Public certexpire_export_t interface. + */ + certexpire_export_t public; + + /** + * hashtable caching local trustchains, mapping entry_t => entry_t + */ + hashtable_t *local; + + /** + * hashtable caching remote trustchains, mapping entry_t => entry_t + */ + hashtable_t *remote; + + /** + * Mutex to lock hashtables + */ + mutex_t *mutex; + + /** + * Cronjob for export + */ + certexpire_cron_t *cron; + + /** + * strftime() format to generate local CSV file + */ + char *local_path; + + /** + * strftime() format to generate remote CSV file + */ + char *remote_path; + + /** + * stftime() format of the exported expiration date + */ + char *format; + + /** + * CSV field separator + */ + char *separator; + + /** + * TRUE to use fixed field count, CA at end + */ + bool fixed_fields; + + /** + * String to use in empty fields, if using fixed_fields + */ + char *empty_string; +}; + +/** + * Maximum number of expiration dates we store (for subject + IM CAs + CA) + */ +#define MAX_TRUSTCHAIN_LENGTH 7 + +/** + * Hashtable entry + */ +typedef struct { + /** certificate subject as subjectAltName or CN of a DN */ + char id[128]; + /** list of expiration dates, 0 if no certificate */ + time_t expire[MAX_TRUSTCHAIN_LENGTH]; +} entry_t; + +/** + * Hashtable hash function + */ +static u_int hash(entry_t *key) +{ + return chunk_hash(chunk_create(key->id, strlen(key->id))); +} + +/** + * Hashtable equals function + */ +static bool equals(entry_t *a, entry_t *b) +{ + return streq(a->id, b->id); +} + +/** + * Export a single trustchain to a path + */ +static void export_csv(private_certexpire_export_t *this, char *path, + hashtable_t *chains) +{ + enumerator_t *enumerator; + char buf[PATH_MAX]; + entry_t *entry; + FILE *file; + struct tm tm; + time_t t; + int i; + + t = time(NULL); + localtime_r(&t, &tm); + + strftime(buf, sizeof(buf), path, &tm); + file = fopen(buf, "a"); + if (file) + { + DBG1(DBG_CFG, "exporting expiration dates of %d trustchain%s to '%s'", + chains->get_count(chains), + chains->get_count(chains) == 1 ? "" : "s", buf); + this->mutex->lock(this->mutex); + enumerator = chains->create_enumerator(chains); + while (enumerator->enumerate(enumerator, NULL, &entry)) + { + fprintf(file, "%s%s", entry->id, this->separator); + for (i = 0; i < MAX_TRUSTCHAIN_LENGTH; i++) + { + if (entry->expire[i]) + { + localtime_r(&entry->expire[i], &tm); + strftime(buf, sizeof(buf), this->format, &tm); + fprintf(file, "%s", buf); + } + if (i == MAX_TRUSTCHAIN_LENGTH - 1) + { + fprintf(file, "\n"); + } + else if (entry->expire[i]) + { + fprintf(file, "%s", this->separator); + } + else if (this->fixed_fields) + { + fprintf(file, "%s%s", this->empty_string, this->separator); + } + } + chains->remove_at(chains, enumerator); + free(entry); + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + fclose(file); + } + else + { + DBG1(DBG_CFG, "opening CSV file '%s' failed: %s", buf, strerror(errno)); + } +} + +/** + * Export cached trustchain expiration dates to CSV files + */ +static void cron_export(private_certexpire_export_t *this) +{ + if (this->local_path) + { + export_csv(this, this->local_path, this->local); + } + if (this->remote_path) + { + export_csv(this, this->remote_path, this->remote); + } +} + +METHOD(certexpire_export_t, add, void, + private_certexpire_export_t *this, linked_list_t *trustchain, bool local) +{ + enumerator_t *enumerator; + certificate_t *cert; + int count; + + /* don't store expiration dates if no path configured */ + if (local) + { + if (!this->local_path) + { + return; + } + } + else + { + if (!this->remote_path) + { + return; + } + } + + count = min(trustchain->get_count(trustchain), MAX_TRUSTCHAIN_LENGTH) - 1; + + enumerator = trustchain->create_enumerator(trustchain); + /* get subject cert */ + if (enumerator->enumerate(enumerator, &cert)) + { + identification_t *id; + entry_t *entry; + int i; + + INIT(entry); + + /* prefer FQDN subjectAltName... */ + if (cert->get_type(cert) == CERT_X509) + { + x509_t *x509 = (x509_t*)cert; + enumerator_t *sans; + + sans = x509->create_subjectAltName_enumerator(x509); + while (sans->enumerate(sans, &id)) + { + if (id->get_type(id) == ID_FQDN) + { + snprintf(entry->id, sizeof(entry->id), "%Y", id); + break; + } + } + sans->destroy(sans); + } + /* fallback to CN of DN */ + if (!entry->id[0]) + { + enumerator_t *parts; + id_part_t part; + chunk_t data; + + id = cert->get_subject(cert); + parts = id->create_part_enumerator(id); + while (parts->enumerate(parts, &part, &data)) + { + if (part == ID_PART_RDN_CN) + { + snprintf(entry->id, sizeof(entry->id), "%.*s", + (int)data.len, data.ptr); + break; + } + } + parts->destroy(parts); + } + /* no usable identity? skip */ + if (!entry->id[0]) + { + enumerator->destroy(enumerator); + free(entry); + return; + } + + /* get intermediate CA expiration dates */ + cert->get_validity(cert, NULL, NULL, &entry->expire[0]); + for (i = 1; i < count && enumerator->enumerate(enumerator, &cert); i++) + { + cert->get_validity(cert, NULL, NULL, &entry->expire[i]); + } + /* get CA expiration date, as last array entry */ + if (enumerator->enumerate(enumerator, &cert)) + { + cert->get_validity(cert, NULL, NULL, + &entry->expire[MAX_TRUSTCHAIN_LENGTH - 1]); + } + this->mutex->lock(this->mutex); + if (local) + { + entry = this->local->put(this->local, entry, entry); + } + else + { + entry = this->remote->put(this->remote, entry, entry); + } + this->mutex->unlock(this->mutex); + if (entry) + { + free(entry); + } + if (!this->cron) + { /* export directly if no cron job defined */ + if (local) + { + export_csv(this, this->local_path, this->local); + } + else + { + export_csv(this, this->remote_path, this->remote); + } + } + } + enumerator->destroy(enumerator); +} + +METHOD(certexpire_export_t, destroy, void, + private_certexpire_export_t *this) +{ + entry_t *key, *value; + enumerator_t *enumerator; + + enumerator = this->local->create_enumerator(this->local); + while (enumerator->enumerate(enumerator, &key, &value)) + { + free(value); + } + enumerator->destroy(enumerator); + enumerator = this->remote->create_enumerator(this->remote); + while (enumerator->enumerate(enumerator, &key, &value)) + { + free(value); + } + enumerator->destroy(enumerator); + + this->local->destroy(this->local); + this->remote->destroy(this->remote); + DESTROY_IF(this->cron); + this->mutex->destroy(this->mutex); + free(this); +} + +/** + * See header + */ +certexpire_export_t *certexpire_export_create() +{ + private_certexpire_export_t *this; + char *cron; + + INIT(this, + .public = { + .add = _add, + .destroy = _destroy, + }, + .local = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 4), + .remote = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 32), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .local_path = lib->settings->get_str(lib->settings, + "charon.plugins.certexpire.csv.local", NULL), + .remote_path = lib->settings->get_str(lib->settings, + "charon.plugins.certexpire.csv.remote", NULL), + .separator = lib->settings->get_str(lib->settings, + "charon.plugins.certexpire.csv.separator", ","), + .format = lib->settings->get_str(lib->settings, + "charon.plugins.certexpire.csv.format", "%d:%m:%Y"), + .fixed_fields = lib->settings->get_bool(lib->settings, + "charon.plugins.certexpire.csv.fixed_fields", TRUE), + .empty_string = lib->settings->get_str(lib->settings, + "charon.plugins.certexpire.csv.empty_string", ""), + ); + + cron = lib->settings->get_str(lib->settings, + "charon.plugins.certexpire.csv.cron", NULL); + if (cron) + { + this->cron = certexpire_cron_create(cron, + (certexpire_cron_job_t)cron_export, this); + } + return &this->public; +} diff --git a/src/libcharon/plugins/certexpire/certexpire_export.h b/src/libcharon/plugins/certexpire/certexpire_export.h new file mode 100644 index 000000000..64281d0bd --- /dev/null +++ b/src/libcharon/plugins/certexpire/certexpire_export.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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 certexpire_export certexpire_export + * @{ @ingroup certexpire + */ + +#ifndef CERTEXPIRE_EXPORT_H_ +#define CERTEXPIRE_EXPORT_H_ + +typedef struct certexpire_export_t certexpire_export_t; + +#include <utils/linked_list.h> + +/** + * Caches and exports trustchain information to CSV files. + */ +struct certexpire_export_t { + + /** + * Add trustchain to cache for export. + * + * @param trustchain trustchain, sorted list of certificate_t + * @param local TRUE for own chain, FALSE for remote chain + */ + void (*add)(certexpire_export_t *this, linked_list_t *trustchain, bool local); + + /** + * Destroy a certexpire_export_t. + */ + void (*destroy)(certexpire_export_t *this); +}; + +/** + * Create a certexpire_export instance. + */ +certexpire_export_t *certexpire_export_create(); + +#endif /** CERTEXPIRE_EXPORT_H_ @}*/ diff --git a/src/libcharon/plugins/certexpire/certexpire_listener.c b/src/libcharon/plugins/certexpire/certexpire_listener.c new file mode 100644 index 000000000..4c9c6ff3b --- /dev/null +++ b/src/libcharon/plugins/certexpire/certexpire_listener.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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. + */ + +#include "certexpire_listener.h" + +#include <daemon.h> + +typedef struct private_certexpire_listener_t private_certexpire_listener_t; + +/** + * Private data of an certexpire_listener_t object. + */ +struct private_certexpire_listener_t { + + /** + * Public certexpire_listener_t interface. + */ + certexpire_listener_t public; + + /** + * Export facility + */ + certexpire_export_t *export; +}; + +METHOD(listener_t, authorize, bool, + private_certexpire_listener_t *this, ike_sa_t *ike_sa, + bool final, bool *success) +{ + enumerator_t *rounds, *enumerator; + certificate_t *cert, *ca = NULL; + linked_list_t *trustchain; + auth_cfg_t *auth; + auth_rule_t rule; + + /* Check all rounds in final hook, as local authentication data are + * not completely available after round-invocation. */ + if (!final) + { + return TRUE; + } + + /* collect local certificates */ + trustchain = linked_list_create(); + rounds = ike_sa->create_auth_cfg_enumerator(ike_sa, TRUE); + while (rounds->enumerate(rounds, &auth)) + { + cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); + if (cert) + { + trustchain->insert_last(trustchain, cert); + + enumerator = auth->create_enumerator(auth); + while (enumerator->enumerate(enumerator, &rule, &cert)) + { + if (rule == AUTH_RULE_IM_CERT) + { + trustchain->insert_last(trustchain, cert); + } + if (rule == AUTH_RULE_CA_CERT) + { + /* the last CA cert is the one used in the trustchain. + * Previous CA certificates have been received as cert + * requests. */ + ca = cert; + } + } + enumerator->destroy(enumerator); + if (ca) + { + trustchain->insert_last(trustchain, ca); + } + } + } + rounds->destroy(rounds); + this->export->add(this->export, trustchain, TRUE); + trustchain->destroy(trustchain); + + /* collect remote certificates */ + trustchain = linked_list_create(); + rounds = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE); + while (rounds->enumerate(rounds, &auth)) + { + cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); + if (cert) + { + trustchain->insert_last(trustchain, cert); + + enumerator = auth->create_enumerator(auth); + while (enumerator->enumerate(enumerator, &rule, &cert)) + { + if (rule == AUTH_RULE_IM_CERT) + { + trustchain->insert_last(trustchain, cert); + } + } + enumerator->destroy(enumerator); + + cert = auth->get(auth, AUTH_RULE_CA_CERT); + if (cert) + { + trustchain->insert_last(trustchain, cert); + } + } + } + rounds->destroy(rounds); + this->export->add(this->export, trustchain, FALSE); + trustchain->destroy(trustchain); + return TRUE; +} + +METHOD(certexpire_listener_t, destroy, void, + private_certexpire_listener_t *this) +{ + free(this); +} + +/** + * See header + */ +certexpire_listener_t *certexpire_listener_create(certexpire_export_t *export) +{ + private_certexpire_listener_t *this; + + INIT(this, + .public = { + .listener = { + .authorize = _authorize, + }, + .destroy = _destroy, + }, + .export = export, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/certexpire/certexpire_listener.h b/src/libcharon/plugins/certexpire/certexpire_listener.h new file mode 100644 index 000000000..8601ff585 --- /dev/null +++ b/src/libcharon/plugins/certexpire/certexpire_listener.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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 certexpire_listener certexpire_listener + * @{ @ingroup certexpire + */ + +#ifndef CERTEXPIRE_LISTENER_H_ +#define CERTEXPIRE_LISTENER_H_ + +#include <bus/listeners/listener.h> + +#include "certexpire_export.h" + +typedef struct certexpire_listener_t certexpire_listener_t; + +/** + * Listener collecting certificate expire information after authentication. + */ +struct certexpire_listener_t { + + /** + * Implements listener_t interface. + */ + listener_t listener; + + /** + * Destroy a certexpire_listener_t. + */ + void (*destroy)(certexpire_listener_t *this); +}; + +/** + * Create a certexpire_listener instance. + * + * @param export facility exporting collected trustchains + * @return listener instance + */ +certexpire_listener_t *certexpire_listener_create(certexpire_export_t *export); + +#endif /** CERTEXPIRE_LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/certexpire/certexpire_plugin.c b/src/libcharon/plugins/certexpire/certexpire_plugin.c new file mode 100644 index 000000000..2b4c0b68b --- /dev/null +++ b/src/libcharon/plugins/certexpire/certexpire_plugin.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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. + */ + +#include "certexpire_plugin.h" + +#include "certexpire_listener.h" +#include "certexpire_export.h" + +#include <daemon.h> + +typedef struct private_certexpire_plugin_t private_certexpire_plugin_t; + +/** + * Private data of certexpire plugin + */ +struct private_certexpire_plugin_t { + + /** + * Implements plugin interface + */ + certexpire_plugin_t public; + + /** + * Listener collecting expire information + */ + certexpire_listener_t *listener; + + /** + * Cache and export trustchain expire information + */ + certexpire_export_t *export; +}; + +METHOD(plugin_t, get_name, char*, + private_certexpire_plugin_t *this) +{ + return "certexpire"; +} + +METHOD(plugin_t, destroy, void, + private_certexpire_plugin_t *this) +{ + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); + this->export->destroy(this->export); + free(this); +} + +/** + * Plugin constructor + */ +plugin_t *certexpire_plugin_create() +{ + private_certexpire_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .reload = (void*)return_false, + .destroy = _destroy, + }, + }, + .export = certexpire_export_create(), + ); + this->listener = certexpire_listener_create(this->export), + charon->bus->add_listener(charon->bus, &this->listener->listener); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/certexpire/certexpire_plugin.h b/src/libcharon/plugins/certexpire/certexpire_plugin.h new file mode 100644 index 000000000..bcb5606f5 --- /dev/null +++ b/src/libcharon/plugins/certexpire/certexpire_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * 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 certexpire certexpire + * @ingroup cplugins + * + * @defgroup certexpire_plugin certexpire_plugin + * @{ @ingroup certexpire + */ + +#ifndef CERTEXPIRE_PLUGIN_H_ +#define CERTEXPIRE_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct certexpire_plugin_t certexpire_plugin_t; + +/** + * Plugin exporting expiration dates of used certificates to CSV files. + */ +struct certexpire_plugin_t { + + /** + * Implements plugin interface. + */ + plugin_t plugin; +}; + +#endif /** CERTEXPIRE_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in index a3104e4c0..df4420b04 100644 --- a/src/libcharon/plugins/coupling/Makefile.in +++ b/src/libcharon/plugins/coupling/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in index 7853659df..089afd39d 100644 --- a/src/libcharon/plugins/dhcp/Makefile.in +++ b/src/libcharon/plugins/dhcp/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c index c98d50554..5d98e5b8d 100644 --- a/src/libcharon/plugins/dhcp/dhcp_socket.c +++ b/src/libcharon/plugins/dhcp/dhcp_socket.c @@ -760,8 +760,8 @@ dhcp_socket_t *dhcp_socket_create() return NULL; } - this->job = callback_job_create((callback_job_cb_t)receive_dhcp, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)receive_dhcp, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in index 8cffa2f10..87984a182 100644 --- a/src/libcharon/plugins/duplicheck/Makefile.in +++ b/src/libcharon/plugins/duplicheck/Makefile.in @@ -202,6 +202,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -210,6 +213,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -226,11 +230,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -274,6 +280,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/duplicheck/duplicheck_notify.c b/src/libcharon/plugins/duplicheck/duplicheck_notify.c index 4e7618235..b86f1ef3d 100644 --- a/src/libcharon/plugins/duplicheck/duplicheck_notify.c +++ b/src/libcharon/plugins/duplicheck/duplicheck_notify.c @@ -203,8 +203,8 @@ duplicheck_notify_t *duplicheck_notify_create() destroy(this); return NULL; } - this->job = callback_job_create((callback_job_cb_t)receive, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)receive, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; diff --git a/src/libcharon/plugins/duplicheck/duplicheck_plugin.c b/src/libcharon/plugins/duplicheck/duplicheck_plugin.c index 5bc1a14af..df28e7f12 100644 --- a/src/libcharon/plugins/duplicheck/duplicheck_plugin.c +++ b/src/libcharon/plugins/duplicheck/duplicheck_plugin.c @@ -66,7 +66,7 @@ plugin_t *duplicheck_plugin_create() private_duplicheck_plugin_t *this; if (!lib->settings->get_bool(lib->settings, - "charon.plugins.duplicheck.enabled", TRUE)) + "charon.plugins.duplicheck.enable", TRUE)) { return NULL; } diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in index 666e22957..e7a3d780a 100644 --- a/src/libcharon/plugins/eap_aka/Makefile.in +++ b/src/libcharon/plugins/eap_aka/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/eap_aka/eap_aka_peer.c b/src/libcharon/plugins/eap_aka/eap_aka_peer.c index df0c4c5b4..8c392405e 100644 --- a/src/libcharon/plugins/eap_aka/eap_aka_peer.c +++ b/src/libcharon/plugins/eap_aka/eap_aka_peer.c @@ -20,6 +20,7 @@ #include <simaka_message.h> #include <simaka_crypto.h> +#include <simaka_manager.h> typedef struct private_eap_aka_peer_t private_eap_aka_peer_t; @@ -34,6 +35,11 @@ struct private_eap_aka_peer_t { eap_aka_peer_t public; /** + * AKA backend manager + */ + simaka_manager_t *mgr; + + /** * EAP-AKA crypto helper */ simaka_crypto_t *crypto; @@ -91,7 +97,7 @@ static eap_payload_t* create_client_error(private_eap_aka_peer_t *this) encoded = htons(AKA_UNABLE_TO_PROCESS); message->add_attribute(message, AT_CLIENT_ERROR_CODE, chunk_create((char*)&encoded, sizeof(encoded))); - out = message->generate(message, chunk_empty); + out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); return out; } @@ -140,7 +146,7 @@ static status_t process_identity(private_eap_aka_peer_t *this, switch (id_req) { case AT_ANY_ID_REQ: - this->reauth = charon->sim->card_get_reauth(charon->sim, + this->reauth = this->mgr->card_get_reauth(this->mgr, this->permanent, this->mk, &this->counter); if (this->reauth) { @@ -149,8 +155,8 @@ static status_t process_identity(private_eap_aka_peer_t *this, } /* FALL */ case AT_FULLAUTH_ID_REQ: - this->pseudonym = charon->sim->card_get_pseudonym(charon->sim, - this->permanent); + this->pseudonym = this->mgr->card_get_pseudonym(this->mgr, + this->permanent); if (this->pseudonym) { id = this->pseudonym->get_encoding(this->pseudonym); @@ -169,7 +175,7 @@ static status_t process_identity(private_eap_aka_peer_t *this, { message->add_attribute(message, AT_IDENTITY, id); } - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); return NEED_MORE; @@ -220,10 +226,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this, return NEED_MORE; } - status = charon->sim->card_get_quintuplet(charon->sim, this->permanent, + status = this->mgr->card_get_quintuplet(this->mgr, this->permanent, rand.ptr, autn.ptr, ck, ik, res, &res_len); if (status == INVALID_STATE && - charon->sim->card_resync(charon->sim, this->permanent, rand.ptr, auts)) + this->mgr->card_resync(this->mgr, this->permanent, rand.ptr, auts)) { DBG1(DBG_IKE, "received SQN invalid, sending %N", simaka_subtype_names, AKA_SYNCHRONIZATION_FAILURE); @@ -231,7 +237,8 @@ static status_t process_challenge(private_eap_aka_peer_t *this, AKA_SYNCHRONIZATION_FAILURE, this->crypto); message->add_attribute(message, AT_AUTS, chunk_create(auts, AKA_AUTS_LEN)); - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, + chunk_empty)); message->destroy(message); return NEED_MORE; } @@ -241,7 +248,8 @@ static status_t process_challenge(private_eap_aka_peer_t *this, this->permanent, simaka_subtype_names, AKA_AUTHENTICATION_REJECT); message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA, AKA_AUTHENTICATION_REJECT, this->crypto); - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, + chunk_empty)); message->destroy(message); return NEED_MORE; } @@ -274,13 +282,13 @@ static status_t process_challenge(private_eap_aka_peer_t *this, case AT_NEXT_REAUTH_ID: this->counter = 0; id = identification_create_from_data(data); - charon->sim->card_set_reauth(charon->sim, this->permanent, id, - this->mk, this->counter); + this->mgr->card_set_reauth(this->mgr, this->permanent, id, + this->mk, this->counter); id->destroy(id); break; case AT_NEXT_PSEUDONYM: id = identification_create_from_data(data); - charon->sim->card_set_pseudonym(charon->sim, this->permanent, id); + this->mgr->card_set_pseudonym(this->mgr, this->permanent, id); id->destroy(id); break; default: @@ -292,7 +300,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this, message = simaka_message_create(FALSE, this->identifier, EAP_AKA, AKA_CHALLENGE, this->crypto); message->add_attribute(message, AT_RES, chunk_create(res, res_len)); - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); return NEED_MORE; } @@ -389,13 +397,13 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this, identification_t *reauth; reauth = identification_create_from_data(data); - charon->sim->card_set_reauth(charon->sim, this->permanent, reauth, - this->mk, this->counter); + this->mgr->card_set_reauth(this->mgr, this->permanent, reauth, + this->mk, this->counter); reauth->destroy(reauth); } } message->add_attribute(message, AT_COUNTER, counter); - *out = message->generate(message, nonce); + *out = eap_payload_create_data_own(message->generate(message, nonce)); message->destroy(message); return NEED_MORE; } @@ -446,7 +454,8 @@ static status_t process_notification(private_eap_aka_peer_t *this, { /* empty notification reply */ message = simaka_message_create(FALSE, this->identifier, EAP_AKA, AKA_NOTIFICATION, this->crypto); - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, + chunk_empty)); message->destroy(message); } else @@ -466,7 +475,7 @@ METHOD(eap_method_t, process, status_t, /* store received EAP message identifier */ this->identifier = in->get_identifier(in); - message = simaka_message_create_from_payload(in, this->crypto); + message = simaka_message_create_from_payload(in->get_data(in), this->crypto); if (!message) { *out = create_client_error(this); @@ -578,7 +587,8 @@ eap_aka_peer_t *eap_aka_peer_create(identification_t *server, .destroy = _destroy, }, }, - .crypto = simaka_crypto_create(), + .crypto = simaka_crypto_create(EAP_AKA), + .mgr = lib->get(lib, "aka-manager"), ); if (!this->crypto) diff --git a/src/libcharon/plugins/eap_aka/eap_aka_peer.h b/src/libcharon/plugins/eap_aka/eap_aka_peer.h index 65a210406..974ba2721 100644 --- a/src/libcharon/plugins/eap_aka/eap_aka_peer.h +++ b/src/libcharon/plugins/eap_aka/eap_aka_peer.h @@ -26,7 +26,7 @@ typedef struct eap_aka_peer_t eap_aka_peer_t; #include <sa/authenticators/eap/eap_method.h> /** - * Implementation of the eap_method_t interface using EAP-AKA as a client. + * EAP-AKA peer implementation. */ struct eap_aka_peer_t { diff --git a/src/libcharon/plugins/eap_aka/eap_aka_plugin.c b/src/libcharon/plugins/eap_aka/eap_aka_plugin.c index 394a14b59..83805d727 100644 --- a/src/libcharon/plugins/eap_aka/eap_aka_plugin.c +++ b/src/libcharon/plugins/eap_aka/eap_aka_plugin.c @@ -19,20 +19,61 @@ #include "eap_aka_server.h" #include <daemon.h> +#include <simaka_manager.h> + +typedef struct private_eap_aka_plugin_t private_eap_aka_plugin_t; + +/** + * Private data of an eap_sim_plugin_t object. + */ +struct private_eap_aka_plugin_t { + + /** + * Public interface. + */ + eap_aka_plugin_t public; + + /** + * EAP-AKA backend manager + */ + simaka_manager_t *mgr; +}; METHOD(plugin_t, get_name, char*, - eap_aka_plugin_t *this) + private_eap_aka_plugin_t *this) { return "eap-aka"; } +METHOD(plugin_t, get_features, int, + private_eap_aka_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_PROVIDE(CUSTOM, "aka-manager"), + PLUGIN_CALLBACK(eap_method_register, eap_aka_server_create), + PLUGIN_PROVIDE(EAP_SERVER, EAP_AKA), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(PRF, PRF_FIPS_SHA1_160), + PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA1_128), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_CALLBACK(eap_method_register, eap_aka_peer_create), + PLUGIN_PROVIDE(EAP_PEER, EAP_AKA), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(PRF, PRF_FIPS_SHA1_160), + PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA1_128), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, - eap_aka_plugin_t *this) + private_eap_aka_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_aka_server_create); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_aka_peer_create); + lib->set(lib, "aka-manager", NULL); + this->mgr->destroy(this->mgr); free(this); } @@ -41,21 +82,19 @@ METHOD(plugin_t, destroy, void, */ plugin_t *eap_aka_plugin_create() { - eap_aka_plugin_t *this; + private_eap_aka_plugin_t *this; INIT(this, - .plugin = { - .get_name = _get_name, - .reload = (void*)return_false, - .destroy = _destroy, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, }, + .mgr = simaka_manager_create(), ); + lib->set(lib, "aka-manager", this->mgr); - charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_SERVER, - (eap_constructor_t)eap_aka_server_create); - charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_PEER, - (eap_constructor_t)eap_aka_peer_create); - - return &this->plugin; + return &this->public.plugin; } - diff --git a/src/libcharon/plugins/eap_aka/eap_aka_plugin.h b/src/libcharon/plugins/eap_aka/eap_aka_plugin.h index d011904b3..8d4fbadfa 100644 --- a/src/libcharon/plugins/eap_aka/eap_aka_plugin.h +++ b/src/libcharon/plugins/eap_aka/eap_aka_plugin.h @@ -33,6 +33,11 @@ typedef struct eap_aka_plugin_t eap_aka_plugin_t; * * EAP-AKA uses 3rd generation mobile phone standard authentication * mechanism for authentication, as defined RFC4187. + * + * This plugin implements the protocol level of EAP-AKA and uses simaka_card_t + * and simaka_provider_t backends to provide triplets. It registers a + * simaka_manager_t on the library as "aka-manager", other plugins can use it + * to provide the required backends. */ struct eap_aka_plugin_t { diff --git a/src/libcharon/plugins/eap_aka/eap_aka_server.c b/src/libcharon/plugins/eap_aka/eap_aka_server.c index bf0020ad8..d8e85ceef 100644 --- a/src/libcharon/plugins/eap_aka/eap_aka_server.c +++ b/src/libcharon/plugins/eap_aka/eap_aka_server.c @@ -20,6 +20,7 @@ #include <simaka_message.h> #include <simaka_crypto.h> +#include <simaka_manager.h> /** length of the AT_NONCE_S value */ #define NONCE_LEN 16 @@ -37,6 +38,11 @@ struct private_eap_aka_server_t { eap_aka_server_t public; /** + * AKA backend manager + */ + simaka_manager_t *mgr; + + /** * EAP-AKA crypto helper */ simaka_crypto_t *crypto; @@ -133,7 +139,7 @@ static status_t identity(private_eap_aka_server_t *this, eap_payload_t **out) { message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty); } - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); this->pending = AKA_IDENTITY; @@ -152,7 +158,7 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out) chunk_t data, mk; identification_t *id; - if (!charon->sim->provider_get_quintuplet(charon->sim, this->permanent, + if (!this->mgr->provider_get_quintuplet(this->mgr, this->permanent, rand, xres, &xres_len, ck, ik, autn)) { if (this->use_pseudonym) @@ -183,24 +189,21 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out) AKA_CHALLENGE, this->crypto); message->add_attribute(message, AT_RAND, this->rand); message->add_attribute(message, AT_AUTN, chunk_create(autn, AKA_AUTN_LEN)); - id = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk.ptr); + id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr); if (id) { message->add_attribute(message, AT_NEXT_REAUTH_ID, id->get_encoding(id)); id->destroy(id); } - else + id = this->mgr->provider_gen_pseudonym(this->mgr, this->permanent); + if (id) { - id = charon->sim->provider_gen_pseudonym(charon->sim, this->permanent); - if (id) - { - message->add_attribute(message, AT_NEXT_PSEUDONYM, - id->get_encoding(id)); - id->destroy(id); - } + message->add_attribute(message, AT_NEXT_PSEUDONYM, + id->get_encoding(id)); + id->destroy(id); } - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); free(mk.ptr); @@ -237,14 +240,14 @@ static status_t reauthenticate(private_eap_aka_server_t *this, AKA_REAUTHENTICATION, this->crypto); message->add_attribute(message, AT_COUNTER, this->counter); message->add_attribute(message, AT_NONCE_S, this->nonce); - next = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk); + next = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk); if (next) { message->add_attribute(message, AT_NEXT_REAUTH_ID, next->get_encoding(next)); next->destroy(next); } - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); this->pending = SIM_REAUTHENTICATION; @@ -310,8 +313,7 @@ static status_t process_identity(private_eap_aka_server_t *this, char mk[HASH_SIZE_SHA1]; u_int16_t counter; - permanent = charon->sim->provider_is_reauth(charon->sim, id, - mk, &counter); + permanent = this->mgr->provider_is_reauth(this->mgr, id, mk, &counter); if (permanent) { this->permanent->destroy(this->permanent); @@ -325,7 +327,7 @@ static status_t process_identity(private_eap_aka_server_t *this, } if (this->use_pseudonym) { - permanent = charon->sim->provider_is_pseudonym(charon->sim, id); + permanent = this->mgr->provider_is_pseudonym(this->mgr, id); if (permanent) { this->permanent->destroy(this->permanent); @@ -506,8 +508,8 @@ static status_t process_synchronize(private_eap_aka_server_t *this, return FAILED; } - if (!charon->sim->provider_resync(charon->sim, this->permanent, - this->rand.ptr, auts.ptr)) + if (!this->mgr->provider_resync(this->mgr, this->permanent, + this->rand.ptr, auts.ptr)) { DBG1(DBG_IKE, "no AKA provider found supporting " "resynchronization for '%Y'", this->permanent); @@ -564,7 +566,7 @@ METHOD(eap_method_t, process, status_t, simaka_message_t *message; status_t status; - message = simaka_message_create_from_payload(in, this->crypto); + message = simaka_message_create_from_payload(in->get_data(in), this->crypto); if (!message) { return FAILED; @@ -676,7 +678,8 @@ eap_aka_server_t *eap_aka_server_create(identification_t *server, .destroy = _destroy, }, }, - .crypto = simaka_crypto_create(), + .crypto = simaka_crypto_create(EAP_AKA), + .mgr = lib->get(lib, "aka-manager"), ); if (!this->crypto) diff --git a/src/libcharon/plugins/eap_aka/eap_aka_server.h b/src/libcharon/plugins/eap_aka/eap_aka_server.h index d48fc4c34..5ab1c4dfd 100644 --- a/src/libcharon/plugins/eap_aka/eap_aka_server.h +++ b/src/libcharon/plugins/eap_aka/eap_aka_server.h @@ -26,7 +26,7 @@ typedef struct eap_aka_server_t eap_aka_server_t; #include <sa/authenticators/eap/eap_method.h> /** - * Implementation of the eap_method_t interface using EAP-AKA as server. + * EAP-AKA server implementation. */ struct eap_aka_server_t { diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am index 598799e2a..b4d6dc1d2 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am +++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am @@ -1,13 +1,17 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic +libstrongswan_eap_aka_3gpp2_la_LDFLAGS = -module -avoid-version +libstrongswan_eap_aka_3gpp2_la_LIBADD = -lgmp + if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-aka-3gpp2.la else plugin_LTLIBRARIES = libstrongswan-eap-aka-3gpp2.la +libstrongswan_eap_aka_3gpp2_la_LIBADD += $(top_builddir)/src/libsimaka/libsimaka.la endif libstrongswan_eap_aka_3gpp2_la_SOURCES = \ @@ -15,6 +19,3 @@ libstrongswan_eap_aka_3gpp2_la_SOURCES = \ eap_aka_3gpp2_card.h eap_aka_3gpp2_card.c \ eap_aka_3gpp2_provider.h eap_aka_3gpp2_provider.c \ eap_aka_3gpp2_functions.h eap_aka_3gpp2_functions.c - -libstrongswan_eap_aka_3gpp2_la_LDFLAGS = -module -avoid-version -libstrongswan_eap_aka_3gpp2_la_LIBADD = -lgmp diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in index 1fe86a2bb..b0890fb39 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in +++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in @@ -34,6 +34,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libsimaka/libsimaka.la subdir = src/libcharon/plugins/eap_aka_3gpp2 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -74,7 +75,7 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_eap_aka_3gpp2_la_DEPENDENCIES = +libstrongswan_eap_aka_3gpp2_la_DEPENDENCIES = $(am__append_1) am_libstrongswan_eap_aka_3gpp2_la_OBJECTS = eap_aka_3gpp2_plugin.lo \ eap_aka_3gpp2_card.lo eap_aka_3gpp2_provider.lo \ eap_aka_3gpp2_functions.lo @@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -204,6 +208,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -220,11 +225,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -279,9 +287,11 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic +libstrongswan_eap_aka_3gpp2_la_LDFLAGS = -module -avoid-version +libstrongswan_eap_aka_3gpp2_la_LIBADD = -lgmp $(am__append_1) @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-aka-3gpp2.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-aka-3gpp2.la libstrongswan_eap_aka_3gpp2_la_SOURCES = \ @@ -290,8 +300,6 @@ libstrongswan_eap_aka_3gpp2_la_SOURCES = \ eap_aka_3gpp2_provider.h eap_aka_3gpp2_provider.c \ eap_aka_3gpp2_functions.h eap_aka_3gpp2_functions.c -libstrongswan_eap_aka_3gpp2_la_LDFLAGS = -module -avoid-version -libstrongswan_eap_aka_3gpp2_la_LIBADD = -lgmp all: all-am .SUFFIXES: diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c index 5c0fe38ad..cec06fbd7 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c +++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c @@ -51,14 +51,10 @@ struct private_eap_aka_3gpp2_card_t { bool eap_aka_3gpp2_get_k(identification_t *id, char k[AKA_K_LEN]); void eap_aka_3gpp2_get_sqn(char sqn[AKA_SQN_LEN], int offset); -/** - * Implementation of sim_card_t.get_quintuplet - */ -static status_t get_quintuplet(private_eap_aka_3gpp2_card_t *this, - identification_t *id, char rand[AKA_RAND_LEN], - char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], - char ik[AKA_IK_LEN], char res[AKA_RES_MAX], - int *res_len) +METHOD(simaka_card_t, get_quintuplet, status_t, + private_eap_aka_3gpp2_card_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], + char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len) { char *amf, *mac; char k[AKA_K_LEN], ak[AKA_AK_LEN], sqn[AKA_SQN_LEN], xmac[AKA_MAC_LEN]; @@ -112,11 +108,9 @@ static status_t get_quintuplet(private_eap_aka_3gpp2_card_t *this, return SUCCESS; } -/** - * Implementation of sim_card_t.resync - */ -static bool resync(private_eap_aka_3gpp2_card_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) +METHOD(simaka_card_t, resync, bool, + private_eap_aka_3gpp2_card_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) { char amf[AKA_AMF_LEN], k[AKA_K_LEN], aks[AKA_AK_LEN], macs[AKA_MAC_LEN]; @@ -138,10 +132,8 @@ static bool resync(private_eap_aka_3gpp2_card_t *this, identification_t *id, return TRUE; } -/** - * Implementation of eap_aka_3gpp2_card_t.destroy. - */ -static void destroy(private_eap_aka_3gpp2_card_t *this) +METHOD(eap_aka_3gpp2_card_t, destroy, void, + private_eap_aka_3gpp2_card_t *this) { free(this); } @@ -151,25 +143,30 @@ static void destroy(private_eap_aka_3gpp2_card_t *this) */ eap_aka_3gpp2_card_t *eap_aka_3gpp2_card_create(eap_aka_3gpp2_functions_t *f) { - private_eap_aka_3gpp2_card_t *this = malloc_thing(private_eap_aka_3gpp2_card_t); - - this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))get_quintuplet; - this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync; - this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *id))return_null; - this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop; - this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null; - this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))nop; - this->public.destroy = (void(*)(eap_aka_3gpp2_card_t*))destroy; - - this->f = f; - this->seq_check = lib->settings->get_bool(lib->settings, + private_eap_aka_3gpp2_card_t *this; + + INIT(this, + .public = { + .card = { + .get_triplet = (void*)return_false, + .get_quintuplet = _get_quintuplet, + .resync = _resync, + .get_pseudonym = (void*)return_null, + .set_pseudonym = (void*)nop, + .get_reauth = (void*)return_null, + .set_reauth = (void*)nop, + }, + .destroy = _destroy, + }, + .f = f, + .seq_check = lib->settings->get_bool(lib->settings, "charon.plugins.eap-aka-3gpp2.seq_check", #ifdef SEQ_CHECK /* handle legacy compile time configuration as default */ - TRUE); + TRUE), #else /* !SEQ_CHECK */ - FALSE); + FALSE), #endif /* SEQ_CHECK */ + ); eap_aka_3gpp2_get_sqn(this->sqn, 0); diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h index b95bc52af..eb6b1f75f 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h +++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h @@ -23,7 +23,7 @@ #include "eap_aka_3gpp2_functions.h" -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_card.h> typedef struct eap_aka_3gpp2_card_t eap_aka_3gpp2_card_t; @@ -33,9 +33,9 @@ typedef struct eap_aka_3gpp2_card_t eap_aka_3gpp2_card_t; struct eap_aka_3gpp2_card_t { /** - * Implements sim_card_t interface + * Implements simaka_card_t interface */ - sim_card_t card; + simaka_card_t card; /** * Destroy a eap_aka_3gpp2_card_t. diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c index 1d3d246d1..d000bebbb 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c +++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c @@ -284,9 +284,10 @@ static void f5x(prf_t *prf, u_char f, u_char k[AKA_K_LEN], /** * Calculate MAC from RAND, SQN, AMF using K */ -static void f1(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], - u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN]) +METHOD(eap_aka_3gpp2_functions_t, f1, void, + private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], + u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], + u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN]) { f1x(this->prf, F1, k, rand, sqn, amf, mac); DBG3(DBG_IKE, "MAC %b", mac, AKA_MAC_LEN); @@ -295,9 +296,10 @@ static void f1(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], /** * Calculate MACS from RAND, SQN, AMF using K */ -static void f1star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], - u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN]) +METHOD(eap_aka_3gpp2_functions_t, f1star, void, + private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], + u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], + u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN]) { f1x(this->prf, F1STAR, k, rand, sqn, amf, macs); DBG3(DBG_IKE, "MACS %b", macs, AKA_MAC_LEN); @@ -306,8 +308,9 @@ static void f1star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], /** * Calculate RES from RAND using K */ -static void f2(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX]) +METHOD(eap_aka_3gpp2_functions_t, f2, void, + private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], + u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX]) { fx(this->prf, F2, k, rand, res); DBG3(DBG_IKE, "RES %b", res, AKA_RES_MAX); @@ -316,8 +319,9 @@ static void f2(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], /** * Calculate CK from RAND using K */ -static void f3(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN]) +METHOD(eap_aka_3gpp2_functions_t, f3, void, + private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], + u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN]) { fx(this->prf, F3, k, rand, ck); DBG3(DBG_IKE, "CK %b", ck, AKA_CK_LEN); @@ -326,8 +330,9 @@ static void f3(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], /** * Calculate IK from RAND using K */ -static void f4(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN]) +METHOD(eap_aka_3gpp2_functions_t, f4, void, + private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], + u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN]) { fx(this->prf, F4, k, rand, ik); DBG3(DBG_IKE, "IK %b", ik, AKA_IK_LEN); @@ -336,8 +341,9 @@ static void f4(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], /** * Calculate AK from a RAND using K */ -static void f5(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN]) +METHOD(eap_aka_3gpp2_functions_t, f5, void, + private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], + u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN]) { f5x(this->prf, F5, k, rand, ak); DBG3(DBG_IKE, "AK %b", ak, AKA_AK_LEN); @@ -346,18 +352,16 @@ static void f5(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], /** * Calculate AKS from a RAND using K */ -static void f5star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN]) +METHOD(eap_aka_3gpp2_functions_t, f5star, void, + private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], + u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN]) { f5x(this->prf, F5STAR, k, rand, aks); DBG3(DBG_IKE, "AKS %b", aks, AKA_AK_LEN); } - -/** - * Implementation of eap_aka_3gpp2_functions_t.destroy. - */ -static void destroy(private_eap_aka_3gpp2_functions_t *this) +METHOD(eap_aka_3gpp2_functions_t, destroy, void, + private_eap_aka_3gpp2_functions_t *this) { this->prf->destroy(this->prf); free(this); @@ -370,18 +374,19 @@ eap_aka_3gpp2_functions_t *eap_aka_3gpp2_functions_create() { private_eap_aka_3gpp2_functions_t *this; - this = malloc_thing(private_eap_aka_3gpp2_functions_t); - - this->public.f1 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN]))f1; - this->public.f1star = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN]))f1star; - this->public.f2 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX]))f2; - this->public.f3 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN]))f3; - this->public.f4 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN]))f4; - this->public.f5 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN]))f5; - this->public.f5star = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN]))f5star; - this->public.destroy = (void(*)(eap_aka_3gpp2_functions_t*))destroy; - - this->prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1); + INIT(this, + .public = { + .f1 = _f1, + .f1star = _f1star, + .f2 = _f2, + .f3 = _f3, + .f4 = _f4, + .f5 = _f5, + .f5star = _f5star, + .destroy = _destroy, + }, + .prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1), + ); if (!this->prf) { DBG1(DBG_CFG, "%N not supported, unable to use 3GPP2 algorithm", diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h index 95c6da6a9..855efec3e 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h +++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h @@ -21,7 +21,7 @@ #ifndef EAP_AKA_3GPP2_FUNCTIONS_H_ #define EAP_AKA_3GPP2_FUNCTIONS_H_ -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_manager.h> #define AKA_SQN_LEN 6 #define AKA_K_LEN 16 diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c index ef5f62e34..d7d0d0507 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c +++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c @@ -54,14 +54,71 @@ METHOD(plugin_t, get_name, char*, return "eap-aka-3gpp2"; } -METHOD(plugin_t, destroy, void, - private_eap_aka_3gpp2_t *this) +/** + * Try to instanciate 3gpp2 functions and card/provider backends + */ +static bool register_functions(private_eap_aka_3gpp2_t *this, + plugin_feature_t *feature, bool reg, void *data) { - charon->sim->remove_card(charon->sim, &this->card->card); - charon->sim->remove_provider(charon->sim, &this->provider->provider); + if (reg) + { + this->functions = eap_aka_3gpp2_functions_create(); + if (!this->functions) + { + return FALSE; + } + this->card = eap_aka_3gpp2_card_create(this->functions); + this->provider = eap_aka_3gpp2_provider_create(this->functions); + return TRUE; + } this->card->destroy(this->card); this->provider->destroy(this->provider); this->functions->destroy(this->functions); + this->card = NULL; + this->provider = NULL; + this->functions = NULL; + return TRUE; +} + +/** + * Callback providing our card to register + */ +static simaka_card_t* get_card(private_eap_aka_3gpp2_t *this) +{ + return &this->card->card; +} + +/** + * Callback providing our provider to register + */ +static simaka_provider_t* get_provider(private_eap_aka_3gpp2_t *this) +{ + return &this->provider->provider; +} + +METHOD(plugin_t, get_features, int, + private_eap_aka_3gpp2_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((void*)register_functions, NULL), + PLUGIN_PROVIDE(CUSTOM, "eap-aka-3gpp2-functions"), + PLUGIN_DEPENDS(PRF, PRF_KEYED_SHA1), + PLUGIN_CALLBACK(simaka_manager_register, get_card), + PLUGIN_PROVIDE(CUSTOM, "aka-card"), + PLUGIN_DEPENDS(CUSTOM, "aka-manager"), + PLUGIN_DEPENDS(CUSTOM, "eap-aka-3gpp2-functions"), + PLUGIN_CALLBACK(simaka_manager_register, get_provider), + PLUGIN_PROVIDE(CUSTOM, "aka-provider"), + PLUGIN_DEPENDS(CUSTOM, "aka-manager"), + PLUGIN_DEPENDS(CUSTOM, "eap-aka-3gpp2-functions"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_eap_aka_3gpp2_t *this) +{ free(this); } @@ -76,24 +133,12 @@ plugin_t *eap_aka_3gpp2_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, - .functions = eap_aka_3gpp2_functions_create(), ); - if (!this->functions) - { - free(this); - return NULL; - } - this->card = eap_aka_3gpp2_card_create(this->functions); - this->provider = eap_aka_3gpp2_provider_create(this->functions); - - charon->sim->add_card(charon->sim, &this->card->card); - charon->sim->add_provider(charon->sim, &this->provider->provider); - return &this->public.plugin; } diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c index a9767ad91..b2b43da2a 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c +++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c @@ -80,14 +80,10 @@ void eap_aka_3gpp2_get_sqn(char sqn[AKA_SQN_LEN], int offset) memcpy(sqn + 4, &time.tv_usec, 2); } -/** - * Implementation of usim_provider_t.get_quintuplet - */ -static bool get_quintuplet(private_eap_aka_3gpp2_provider_t *this, - identification_t *id, char rand[AKA_RAND_LEN], - char xres[AKA_RES_MAX], int *xres_len, - char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char autn[AKA_AUTN_LEN]) +METHOD(simaka_provider_t, get_quintuplet, bool, + private_eap_aka_3gpp2_provider_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, + char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]) { rng_t *rng; char mac[AKA_MAC_LEN], ak[AKA_AK_LEN], k[AKA_K_LEN]; @@ -131,12 +127,9 @@ static bool get_quintuplet(private_eap_aka_3gpp2_provider_t *this, return TRUE; } -/** - * Implementation of usim_provider_t.resync - */ -static bool resync(private_eap_aka_3gpp2_provider_t *this, - identification_t *id, char rand[AKA_RAND_LEN], - char auts[AKA_AUTS_LEN]) +METHOD(simaka_provider_t, resync, bool, + private_eap_aka_3gpp2_provider_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) { char *sqn, *macs; char aks[AKA_AK_LEN], k[AKA_K_LEN], amf[AKA_AMF_LEN], xmacs[AKA_MAC_LEN]; @@ -169,10 +162,8 @@ static bool resync(private_eap_aka_3gpp2_provider_t *this, return TRUE; } -/** - * Implementation of eap_aka_3gpp2_provider_t.destroy. - */ -static void destroy(private_eap_aka_3gpp2_provider_t *this) +METHOD(eap_aka_3gpp2_provider_t, destroy, void, + private_eap_aka_3gpp2_provider_t *this) { free(this); } @@ -183,18 +174,23 @@ static void destroy(private_eap_aka_3gpp2_provider_t *this) eap_aka_3gpp2_provider_t *eap_aka_3gpp2_provider_create( eap_aka_3gpp2_functions_t *f) { - private_eap_aka_3gpp2_provider_t *this = malloc_thing(private_eap_aka_3gpp2_provider_t); - - this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))get_quintuplet; - this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync; - this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; - this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; - this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null; - this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null; - this->public.destroy = (void(*)(eap_aka_3gpp2_provider_t*))destroy; - - this->f = f; + private_eap_aka_3gpp2_provider_t *this; + + INIT(this, + .public = { + .provider = { + .get_triplet = (void*)return_false, + .get_quintuplet = _get_quintuplet, + .resync = _resync, + .is_pseudonym = (void*)return_null, + .gen_pseudonym = (void*)return_null, + .is_reauth = (void*)return_null, + .gen_reauth = (void*)return_null, + }, + .destroy = _destroy, + }, + .f = f, + ); /* use an offset to accept clock skew between client/server without resync */ eap_aka_3gpp2_get_sqn(this->sqn, 180); diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h index 22ac0a96e..0e1af8554 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h +++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h @@ -23,7 +23,7 @@ #include "eap_aka_3gpp2_functions.h" -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_provider.h> typedef struct eap_aka_3gpp2_provider_t eap_aka_3gpp2_provider_t; @@ -33,9 +33,9 @@ typedef struct eap_aka_3gpp2_provider_t eap_aka_3gpp2_provider_t; struct eap_aka_3gpp2_provider_t { /** - * Implements sim_provider_t interface. + * Implements simaka_provider_t interface. */ - sim_provider_t provider; + simaka_provider_t provider; /** * Destroy a eap_aka_3gpp2_provider_t. diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in index 4f555a982..b3f989e38 100644 --- a/src/libcharon/plugins/eap_gtc/Makefile.in +++ b/src/libcharon/plugins/eap_gtc/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c b/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c index c40ce60eb..bd70b757a 100644 --- a/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c +++ b/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c @@ -28,13 +28,22 @@ METHOD(plugin_t, get_name, char*, return "eap-gtc"; } +METHOD(plugin_t, get_features, int, + eap_gtc_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_gtc_create_server), + PLUGIN_PROVIDE(EAP_SERVER, EAP_GTC), + PLUGIN_CALLBACK(eap_method_register, eap_gtc_create_peer), + PLUGIN_PROVIDE(EAP_PEER, EAP_GTC), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, eap_gtc_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_gtc_create_server); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_gtc_create_peer); free(this); } @@ -48,7 +57,7 @@ plugin_t *eap_gtc_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in index 9dc4602ff..b348b5fb5 100644 --- a/src/libcharon/plugins/eap_identity/Makefile.in +++ b/src/libcharon/plugins/eap_identity/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c index 3297416b2..b09e51568 100644 --- a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c +++ b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c @@ -24,13 +24,22 @@ METHOD(plugin_t, get_name, char*, return "eap-identity"; } +METHOD(plugin_t, get_features, int, + eap_identity_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_identity_create_server), + PLUGIN_PROVIDE(EAP_SERVER, EAP_IDENTITY), + PLUGIN_CALLBACK(eap_method_register, eap_identity_create_peer), + PLUGIN_PROVIDE(EAP_PEER, EAP_IDENTITY), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, eap_identity_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_identity_create_server); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_identity_create_peer); free(this); } @@ -44,16 +53,11 @@ plugin_t *eap_identity_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->eap->add_method(charon->eap, EAP_IDENTITY, 0, EAP_SERVER, - (eap_constructor_t)eap_identity_create_server); - charon->eap->add_method(charon->eap, EAP_IDENTITY, 0, EAP_PEER, - (eap_constructor_t)eap_identity_create_peer); - return &this->plugin; } diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in index e828fbc3e..209753b2d 100644 --- a/src/libcharon/plugins/eap_md5/Makefile.in +++ b/src/libcharon/plugins/eap_md5/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c index fe5ae51bf..d045e02bf 100644 --- a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c +++ b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c @@ -24,13 +24,26 @@ METHOD(plugin_t, get_name, char*, return "eap-md5"; } +METHOD(plugin_t, get_features, int, + eap_md5_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_md5_create_server), + PLUGIN_PROVIDE(EAP_SERVER, EAP_MD5), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_CALLBACK(eap_method_register, eap_md5_create_peer), + PLUGIN_PROVIDE(EAP_PEER, EAP_MD5), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, eap_md5_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_md5_create_server); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_md5_create_peer); free(this); } @@ -44,16 +57,11 @@ plugin_t *eap_md5_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->eap->add_method(charon->eap, EAP_MD5, 0, EAP_SERVER, - (eap_constructor_t)eap_md5_create_server); - charon->eap->add_method(charon->eap, EAP_MD5, 0, EAP_PEER, - (eap_constructor_t)eap_md5_create_peer); - return &this->plugin; } diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in index 4986fdce3..6d3d7f8db 100644 --- a/src/libcharon/plugins/eap_mschapv2/Makefile.in +++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c index 1dd94f6fb..9dfc69205 100644 --- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c +++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c @@ -814,7 +814,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this, eap_mschapv2_header_t *eap; chunk_t data; char *message, *token, *msg = NULL; - int message_len, error = 0, retriable; + int message_len, error = 0; chunk_t challenge = chunk_empty; data = in->get_data(in); @@ -842,8 +842,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this, } else if (strneq(token, "R=", 2)) { - token += 2; - retriable = atoi(token); + /* ignore retriable */ } else if (strneq(token, "C=", 2)) { @@ -860,9 +859,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this, } else if (strneq(token, "V=", 2)) { - int version; - token += 2; - version = atoi(token); + /* ignore version */ } else if (strneq(token, "M=", 2)) { diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c index e809b14b6..6fd96708a 100644 --- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c +++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c @@ -25,13 +25,30 @@ METHOD(plugin_t, get_name, char*, return "eap-mschapv2"; } +METHOD(plugin_t, get_features, int, + eap_mschapv2_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_mschapv2_create_server), + PLUGIN_PROVIDE(EAP_SERVER, EAP_MSCHAPV2), + PLUGIN_DEPENDS(CRYPTER, ENCR_DES_ECB, 8), + PLUGIN_DEPENDS(HASHER, HASH_MD4), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_CALLBACK(eap_method_register, eap_mschapv2_create_peer), + PLUGIN_PROVIDE(EAP_PEER, EAP_MSCHAPV2), + PLUGIN_DEPENDS(CRYPTER, ENCR_DES_ECB, 8), + PLUGIN_DEPENDS(HASHER, HASH_MD4), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, eap_mschapv2_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_mschapv2_create_server); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_mschapv2_create_peer); free(this); } @@ -45,16 +62,11 @@ plugin_t *eap_mschapv2_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->eap->add_method(charon->eap, EAP_MSCHAPV2, 0, EAP_SERVER, - (eap_constructor_t)eap_mschapv2_create_server); - charon->eap->add_method(charon->eap, EAP_MSCHAPV2, 0, EAP_PEER, - (eap_constructor_t)eap_mschapv2_create_peer); - return &this->plugin; } diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in index 0ed4a3dcf..4f860e175 100644 --- a/src/libcharon/plugins/eap_peap/Makefile.in +++ b/src/libcharon/plugins/eap_peap/Makefile.in @@ -196,6 +196,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -204,6 +207,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -220,11 +224,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -268,6 +274,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/eap_peap/eap_peap.c b/src/libcharon/plugins/eap_peap/eap_peap.c index 5bae0fa9b..bd426bba7 100644 --- a/src/libcharon/plugins/eap_peap/eap_peap.c +++ b/src/libcharon/plugins/eap_peap/eap_peap.c @@ -166,7 +166,8 @@ static eap_peap_t *eap_peap_create(private_eap_peap_t * this, "charon.plugins.eap-peap.max_message_count", MAX_MESSAGE_COUNT); include_length = lib->settings->get_bool(lib->settings, "charon.plugins.eap-peap.include_length", FALSE); - tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_PEAP, application); + tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_PEAP, + application, NULL); this->tls_eap = tls_eap_create(EAP_PEAP, tls, frag_size, max_msg_count, include_length); if (!this->tls_eap) diff --git a/src/libcharon/plugins/eap_peap/eap_peap_avp.c b/src/libcharon/plugins/eap_peap/eap_peap_avp.c index 06e5222d9..10f6ec11c 100644 --- a/src/libcharon/plugins/eap_peap/eap_peap_avp.c +++ b/src/libcharon/plugins/eap_peap/eap_peap_avp.c @@ -25,6 +25,8 @@ static const chunk_t MS_AVP_Success = chunk_from_chars( 0x80, 0x03, 0x00, 0x02, 0x00, 0x01); static const chunk_t MS_AVP_Failure = chunk_from_chars( 0x80, 0x03, 0x00, 0x02, 0x00, 0x02); +static const chunk_t MS_SoH_Request = chunk_from_chars( + 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x21, 0x00, 0x02, 0x00, 0x00); typedef struct private_eap_peap_avp_t private_eap_peap_avp_t; @@ -45,7 +47,7 @@ struct private_eap_peap_avp_t { }; METHOD(eap_peap_avp_t, build, void, - private_eap_peap_avp_t *this, tls_writer_t *writer, chunk_t data) + private_eap_peap_avp_t *this, bio_writer_t *writer, chunk_t data) { u_int8_t code; eap_packet_t *pkt; @@ -62,6 +64,19 @@ METHOD(eap_peap_avp_t, build, void, writer->write_uint8(writer, EAP_MSTLV); avp_data = (pkt->code == EAP_SUCCESS) ? MS_AVP_Success : MS_AVP_Failure; } + /** + * Still trying to form a correct MS SoH Request + * + else if (pkt->type == EAP_MSCHAPV2) + { + code = (this->is_server) ? EAP_REQUEST : EAP_RESPONSE; + writer->write_uint8(writer, code); + writer->write_uint8(writer, pkt->identifier); + writer->write_uint16(writer, 16); + writer->write_uint8(writer, EAP_EXPANDED); + avp_data = MS_SoH_Request; + } + */ else { avp_data = chunk_skip(data, 4); @@ -70,7 +85,7 @@ METHOD(eap_peap_avp_t, build, void, } METHOD(eap_peap_avp_t, process, status_t, - private_eap_peap_avp_t* this, tls_reader_t *reader, chunk_t *data, + private_eap_peap_avp_t* this, bio_reader_t *reader, chunk_t *data, u_int8_t identifier) { u_int8_t code; diff --git a/src/libcharon/plugins/eap_peap/eap_peap_avp.h b/src/libcharon/plugins/eap_peap/eap_peap_avp.h index db22f0f8f..98c5f1912 100644 --- a/src/libcharon/plugins/eap_peap/eap_peap_avp.h +++ b/src/libcharon/plugins/eap_peap/eap_peap_avp.h @@ -25,8 +25,8 @@ typedef struct eap_peap_avp_t eap_peap_avp_t; #include <library.h> -#include <tls_reader.h> -#include <tls_writer.h> +#include <bio/bio_reader.h> +#include <bio/bio_writer.h> /** * EAP-PEAP Attribute-Value Pair (AVP) handler. @@ -44,7 +44,7 @@ struct eap_peap_avp_t { * - FAILED if AVP processing failed * - NEED_MORE if another invocation of process/build needed */ - status_t (*process)(eap_peap_avp_t *this, tls_reader_t *reader, + status_t (*process)(eap_peap_avp_t *this, bio_reader_t *reader, chunk_t *data, u_int8_t identifier); /** @@ -53,7 +53,7 @@ struct eap_peap_avp_t { * @param writer TLS data buffer to write to * @param data EAP Message to send */ - void (*build)(eap_peap_avp_t *this, tls_writer_t *writer, chunk_t data); + void (*build)(eap_peap_avp_t *this, bio_writer_t *writer, chunk_t data); /** * Destroy a eap_peap_application_t. diff --git a/src/libcharon/plugins/eap_peap/eap_peap_peer.c b/src/libcharon/plugins/eap_peap/eap_peap_peer.c index ca2af4fee..72e201fb6 100644 --- a/src/libcharon/plugins/eap_peap/eap_peap_peer.c +++ b/src/libcharon/plugins/eap_peap/eap_peap_peer.c @@ -63,7 +63,7 @@ struct private_eap_peap_peer_t { }; METHOD(tls_application_t, process, status_t, - private_eap_peap_peer_t *this, tls_reader_t *reader) + private_eap_peap_peer_t *this, bio_reader_t *reader) { chunk_t data = chunk_empty; status_t status; @@ -185,7 +185,7 @@ METHOD(tls_application_t, process, status_t, } METHOD(tls_application_t, build, status_t, - private_eap_peap_peer_t *this, tls_writer_t *writer) + private_eap_peap_peer_t *this, bio_writer_t *writer) { chunk_t data; eap_code_t code; diff --git a/src/libcharon/plugins/eap_peap/eap_peap_plugin.c b/src/libcharon/plugins/eap_peap/eap_peap_plugin.c index bac5f2d3e..e8deee9e1 100644 --- a/src/libcharon/plugins/eap_peap/eap_peap_plugin.c +++ b/src/libcharon/plugins/eap_peap/eap_peap_plugin.c @@ -25,13 +25,31 @@ METHOD(plugin_t, get_name, char*, return "eap-peap"; } +METHOD(plugin_t, get_features, int, + eap_peap_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_peap_create_server), + PLUGIN_PROVIDE(EAP_SERVER, EAP_PEAP), + PLUGIN_DEPENDS(EAP_SERVER, EAP_IDENTITY), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_CALLBACK(eap_method_register, eap_peap_create_peer), + PLUGIN_PROVIDE(EAP_PEER, EAP_PEAP), + PLUGIN_DEPENDS(EAP_PEER, EAP_IDENTITY), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, eap_peap_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_peap_create_server); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_peap_create_peer); free(this); } @@ -45,15 +63,10 @@ plugin_t *eap_peap_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->eap->add_method(charon->eap, EAP_PEAP, 0, EAP_SERVER, - (eap_constructor_t)eap_peap_create_server); - charon->eap->add_method(charon->eap, EAP_PEAP, 0, EAP_PEER, - (eap_constructor_t)eap_peap_create_peer); - return &this->plugin; } diff --git a/src/libcharon/plugins/eap_peap/eap_peap_server.c b/src/libcharon/plugins/eap_peap/eap_peap_server.c index 3fabc3575..4acdd9f07 100644 --- a/src/libcharon/plugins/eap_peap/eap_peap_server.c +++ b/src/libcharon/plugins/eap_peap/eap_peap_server.c @@ -158,7 +158,7 @@ static status_t start_phase2_tnc(private_eap_peap_server_t *this) } METHOD(tls_application_t, process, status_t, - private_eap_peap_server_t *this, tls_reader_t *reader) + private_eap_peap_server_t *this, bio_reader_t *reader) { chunk_t data = chunk_empty; status_t status; @@ -330,7 +330,7 @@ METHOD(tls_application_t, process, status_t, } METHOD(tls_application_t, build, status_t, - private_eap_peap_server_t *this, tls_writer_t *writer) + private_eap_peap_server_t *this, bio_writer_t *writer) { chunk_t data; eap_code_t code; diff --git a/src/libcharon/plugins/eap_radius/Makefile.am b/src/libcharon/plugins/eap_radius/Makefile.am index afc50bced..181497ab5 100644 --- a/src/libcharon/plugins/eap_radius/Makefile.am +++ b/src/libcharon/plugins/eap_radius/Makefile.am @@ -1,21 +1,21 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libradius AM_CFLAGS = -rdynamic if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-radius.la else +libstrongswan_eap_radius_la_LIBADD = $(top_builddir)/src/libradius/libradius.la plugin_LTLIBRARIES = libstrongswan-eap-radius.la endif libstrongswan_eap_radius_la_SOURCES = \ eap_radius_plugin.h eap_radius_plugin.c \ eap_radius.h eap_radius.c \ - radius_server.h radius_server.c \ - radius_socket.h radius_socket.c \ - radius_client.h radius_client.c \ - radius_message.h radius_message.c + eap_radius_accounting.h eap_radius_accounting.c \ + eap_radius_dae.h eap_radius_dae.c \ + eap_radius_forward.h eap_radius_forward.c libstrongswan_eap_radius_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in index 740c64055..0bef44042 100644 --- a/src/libcharon/plugins/eap_radius/Makefile.in +++ b/src/libcharon/plugins/eap_radius/Makefile.in @@ -74,10 +74,11 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_eap_radius_la_LIBADD = +@MONOLITHIC_FALSE@libstrongswan_eap_radius_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libradius/libradius.la am_libstrongswan_eap_radius_la_OBJECTS = eap_radius_plugin.lo \ - eap_radius.lo radius_server.lo radius_socket.lo \ - radius_client.lo radius_message.lo + eap_radius.lo eap_radius_accounting.lo eap_radius_dae.lo \ + eap_radius_forward.lo libstrongswan_eap_radius_la_OBJECTS = \ $(am_libstrongswan_eap_radius_la_OBJECTS) libstrongswan_eap_radius_la_LINK = $(LIBTOOL) --tag=CC \ @@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -204,6 +208,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -220,11 +225,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -279,18 +287,18 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libradius AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-radius.la +@MONOLITHIC_FALSE@libstrongswan_eap_radius_la_LIBADD = $(top_builddir)/src/libradius/libradius.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-radius.la libstrongswan_eap_radius_la_SOURCES = \ eap_radius_plugin.h eap_radius_plugin.c \ eap_radius.h eap_radius.c \ - radius_server.h radius_server.c \ - radius_socket.h radius_socket.c \ - radius_client.h radius_client.c \ - radius_message.h radius_message.c + eap_radius_accounting.h eap_radius_accounting.c \ + eap_radius_dae.h eap_radius_dae.c \ + eap_radius_forward.h eap_radius_forward.c libstrongswan_eap_radius_la_LDFLAGS = -module -avoid-version all: all-am @@ -377,11 +385,10 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_accounting.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_dae.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_forward.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_plugin.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_client.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_message.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_server.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_socket.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c index dfe0e2e09..c0a3703b6 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius.c +++ b/src/libcharon/plugins/eap_radius/eap_radius.c @@ -14,14 +14,14 @@ */ #include "eap_radius.h" +#include "eap_radius_plugin.h" +#include "eap_radius_forward.h" -#include "radius_message.h" -#include "radius_client.h" +#include <radius_message.h> +#include <radius_client.h> #include <daemon.h> -#define TUNNEL_TYPE_ESP 9 - typedef struct private_eap_radius_t private_eap_radius_t; /** @@ -162,7 +162,7 @@ METHOD(eap_method_t, initiate, status_t, status_t status = FAILED; chunk_t username; - request = radius_message_create_request(); + request = radius_message_create(RMC_ACCESS_REQUEST); 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); @@ -175,16 +175,22 @@ METHOD(eap_method_t, initiate, status_t, { add_eap_identity(this, request); } + eap_radius_forward_from_ike(request); response = this->client->request(this->client, request); if (response) { + eap_radius_forward_to_ike(response); if (radius2ike(this, response, out)) { status = NEED_MORE; } response->destroy(response); } + else + { + charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING); + } request->destroy(request); return status; } @@ -253,7 +259,7 @@ static void process_filter_id(private_eap_radius_t *this, radius_message_t *msg) tunnel_type = untoh32(data.ptr); DBG1(DBG_IKE, "received RADIUS attribute Tunnel-Type: " "tag = %u, value = %u", tunnel_tag, tunnel_type); - is_esp_tunnel = (tunnel_type == TUNNEL_TYPE_ESP); + is_esp_tunnel = (tunnel_type == RADIUS_TUNNEL_TYPE_ESP); break; case RAT_FILTER_ID: filter_id = data; @@ -282,6 +288,31 @@ static void process_filter_id(private_eap_radius_t *this, radius_message_t *msg) } } +/** + * Handle Session-Timeout attribte + */ +static void process_timeout(private_eap_radius_t *this, radius_message_t *msg) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + chunk_t data; + int type; + + enumerator = msg->create_enumerator(msg); + while (enumerator->enumerate(enumerator, &type, &data)) + { + if (type == RAT_SESSION_TIMEOUT && data.len == 4) + { + ike_sa = charon->bus->get_sa(charon->bus); + if (ike_sa) + { + ike_sa->set_auth_lifetime(ike_sa, untoh32(data.ptr)); + } + } + } + enumerator->destroy(enumerator); +} + METHOD(eap_method_t, process, status_t, private_eap_radius_t *this, eap_payload_t *in, eap_payload_t **out) { @@ -289,22 +320,25 @@ METHOD(eap_method_t, process, status_t, status_t status = FAILED; chunk_t data; - request = radius_message_create_request(); + request = radius_message_create(RMC_ACCESS_REQUEST); request->add(request, RAT_USER_NAME, this->peer->get_encoding(this->peer)); data = in->get_data(in); DBG3(DBG_IKE, "%N payload %B", eap_type_names, this->type, &data); - - /* fragment data suitable for RADIUS (not more than 253 bytes) */ - while (data.len > 253) + + /* fragment data suitable for RADIUS */ + while (data.len > MAX_RADIUS_ATTRIBUTE_SIZE) { - request->add(request, RAT_EAP_MESSAGE, chunk_create(data.ptr, 253)); - data = chunk_skip(data, 253); + request->add(request, RAT_EAP_MESSAGE, + chunk_create(data.ptr,MAX_RADIUS_ATTRIBUTE_SIZE)); + data = chunk_skip(data, MAX_RADIUS_ATTRIBUTE_SIZE); } request->add(request, RAT_EAP_MESSAGE, data); + eap_radius_forward_from_ike(request); response = this->client->request(this->client, request); if (response) { + eap_radius_forward_to_ike(response); switch (response->get_code(response)) { case RMC_ACCESS_CHALLENGE: @@ -324,6 +358,7 @@ METHOD(eap_method_t, process, status_t, { process_filter_id(this, response); } + process_timeout(this, response); DBG1(DBG_IKE, "RADIUS authentication of '%Y' successful", this->peer); status = SUCCESS; @@ -427,7 +462,7 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer "charon.plugins.eap-radius.filter_id", FALSE), ); - this->client = radius_client_create(); + this->client = eap_radius_create_client(); if (!this->client) { free(this); diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c new file mode 100644 index 000000000..45be22704 --- /dev/null +++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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. + */ + +#include "eap_radius_accounting.h" +#include "eap_radius_plugin.h" + +#include <time.h> + +#include <radius_message.h> +#include <radius_client.h> +#include <daemon.h> +#include <utils/hashtable.h> +#include <threading/mutex.h> + +typedef struct private_eap_radius_accounting_t private_eap_radius_accounting_t; + +/** + * Private data of an eap_radius_accounting_t object. + */ +struct private_eap_radius_accounting_t { + + /** + * Public eap_radius_accounting_t interface. + */ + eap_radius_accounting_t public; + + /** + * Hashtable with sessions, IKE_SA unique id => entry_t + */ + hashtable_t *sessions; + + /** + * Mutex to lock sessions + */ + mutex_t *mutex; + + /** + * Session ID prefix + */ + u_int32_t prefix; +}; + +/** + * Hashtable entry with usage stats + */ +typedef struct { + /** RADIUS accounting session ID */ + char sid[16]; + /** number of octets sent */ + u_int64_t sent; + /** number of octets received */ + u_int64_t received; + /** session creation time */ + time_t created; +} entry_t; + +/** + * Accounting message status types + */ +typedef enum { + ACCT_STATUS_START = 1, + ACCT_STATUS_STOP = 2, + ACCT_STATUS_INTERIM_UPDATE = 3, + ACCT_STATUS_ACCOUNTING_ON = 7, + ACCT_STATUS_ACCOUNTING_OFF = 8, +} radius_acct_status_t; + +/** + * Hashtable hash function + */ +static u_int hash(uintptr_t key) +{ + return key; +} + +/** + * Hashtable equals function + */ +static bool equals(uintptr_t a, uintptr_t b) +{ + return a == b; +} + +/** + * Update usage counter when a CHILD_SA rekeys/goes down + */ +static void update_usage(private_eap_radius_accounting_t *this, + ike_sa_t *ike_sa, child_sa_t *child_sa) +{ + u_int64_t sent, received; + entry_t *entry; + + child_sa->get_usestats(child_sa, FALSE, NULL, &sent); + child_sa->get_usestats(child_sa, TRUE, NULL, &received); + + this->mutex->lock(this->mutex); + entry = this->sessions->get(this->sessions, + (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa)); + if (entry) + { + entry->sent += sent; + entry->received += received; + } + this->mutex->unlock(this->mutex); +} + +/** + * Send a RADIUS message, wait for response + */ +static bool send_message(private_eap_radius_accounting_t *this, + radius_message_t *request) +{ + radius_message_t *response; + radius_client_t *client; + bool ack = FALSE; + + client = eap_radius_create_client(); + if (client) + { + response = client->request(client, request); + if (response) + { + ack = response->get_code(response) == RMC_ACCOUNTING_RESPONSE; + response->destroy(response); + } + else + { + charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING); + } + client->destroy(client); + } + return ack; +} + +/** + * Add common IKE_SA parameters to RADIUS account message + */ +static void add_ike_sa_parameters(radius_message_t *message, ike_sa_t *ike_sa) +{ + host_t *vip; + char buf[64]; + chunk_t data; + + snprintf(buf, sizeof(buf), "%Y", ike_sa->get_other_eap_id(ike_sa)); + message->add(message, RAT_USER_NAME, chunk_create(buf, strlen(buf))); + snprintf(buf, sizeof(buf), "%#H", ike_sa->get_other_host(ike_sa)); + message->add(message, RAT_CALLING_STATION_ID, chunk_create(buf, strlen(buf))); + vip = ike_sa->get_virtual_ip(ike_sa, FALSE); + if (vip && vip->get_family(vip) == AF_INET) + { + message->add(message, RAT_FRAMED_IP_ADDRESS, vip->get_address(vip)); + } + if (vip && vip->get_family(vip) == AF_INET6) + { + /* we currently assign /128 prefixes, only (reserved, length) */ + data = chunk_from_chars(0, 128); + data = chunk_cata("cc", data, vip->get_address(vip)); + message->add(message, RAT_FRAMED_IPV6_PREFIX, data); + } +} + +/** + * Send an accounting start message + */ +static void send_start(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa) +{ + radius_message_t *message; + entry_t *entry; + u_int32_t id, value; + + id = ike_sa->get_unique_id(ike_sa); + INIT(entry, + .created = time_monotonic(NULL), + ); + snprintf(entry->sid, sizeof(entry->sid), "%u-%u", this->prefix, id); + + message = radius_message_create(RMC_ACCOUNTING_REQUEST); + value = htonl(ACCT_STATUS_START); + message->add(message, RAT_ACCT_STATUS_TYPE, chunk_from_thing(value)); + message->add(message, RAT_ACCT_SESSION_ID, + chunk_create(entry->sid, strlen(entry->sid))); + add_ike_sa_parameters(message, ike_sa); + if (send_message(this, message)) + { + this->mutex->lock(this->mutex); + entry = this->sessions->put(this->sessions, (void*)(uintptr_t)id, entry); + this->mutex->unlock(this->mutex); + free(entry); + } + message->destroy(message); +} + +/** + * Send an account stop message + */ +static void send_stop(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa) +{ + radius_message_t *message; + entry_t *entry; + u_int32_t id, value; + + id = ike_sa->get_unique_id(ike_sa); + this->mutex->lock(this->mutex); + entry = this->sessions->remove(this->sessions, (void*)(uintptr_t)id); + this->mutex->unlock(this->mutex); + if (entry) + { + message = radius_message_create(RMC_ACCOUNTING_REQUEST); + value = htonl(ACCT_STATUS_STOP); + message->add(message, RAT_ACCT_STATUS_TYPE, chunk_from_thing(value)); + message->add(message, RAT_ACCT_SESSION_ID, + chunk_create(entry->sid, strlen(entry->sid))); + add_ike_sa_parameters(message, ike_sa); + value = htonl(entry->sent); + message->add(message, RAT_ACCT_OUTPUT_OCTETS, chunk_from_thing(value)); + value = htonl(entry->sent >> 32); + if (value) + { + message->add(message, RAT_ACCT_OUTPUT_GIGAWORDS, + chunk_from_thing(value)); + } + value = htonl(entry->received); + message->add(message, RAT_ACCT_INPUT_OCTETS, chunk_from_thing(value)); + value = htonl(entry->received >> 32); + if (value) + { + message->add(message, RAT_ACCT_INPUT_GIGAWORDS, + chunk_from_thing(value)); + } + value = htonl(time_monotonic(NULL) - entry->created); + message->add(message, RAT_ACCT_SESSION_TIME, chunk_from_thing(value)); + + send_message(this, message); + message->destroy(message); + free(entry); + } +} + +METHOD(listener_t, ike_updown, bool, + private_eap_radius_accounting_t *this, ike_sa_t *ike_sa, bool up) +{ + if (!up) + { + enumerator_t *enumerator; + child_sa_t *child_sa; + + /* update usage for all children just before sending stop */ + enumerator = ike_sa->create_child_sa_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, &child_sa)) + { + update_usage(this, ike_sa, child_sa); + } + enumerator->destroy(enumerator); + + send_stop(this, ike_sa); + } + return TRUE; +} + +METHOD(listener_t, message_hook, bool, + private_eap_radius_accounting_t *this, ike_sa_t *ike_sa, + message_t *message, bool incoming) +{ + /* start accounting here, virtual IP now is set */ + if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && + message->get_exchange_type(message) == IKE_AUTH && + !incoming && !message->get_request(message)) + { + send_start(this, ike_sa); + } + return TRUE; +} + +METHOD(listener_t, child_rekey, bool, + private_eap_radius_accounting_t *this, ike_sa_t *ike_sa, + child_sa_t *old, child_sa_t *new) +{ + update_usage(this, ike_sa, old); + + return TRUE; +} + +METHOD(listener_t, child_updown, bool, + private_eap_radius_accounting_t *this, ike_sa_t *ike_sa, + child_sa_t *child_sa, bool up) +{ + if (!up && ike_sa->get_state(ike_sa) == IKE_ESTABLISHED) + { + update_usage(this, ike_sa, child_sa); + } + return TRUE; +} + +METHOD(eap_radius_accounting_t, destroy, void, + private_eap_radius_accounting_t *this) +{ + this->mutex->destroy(this->mutex); + this->sessions->destroy(this->sessions); + free(this); +} + +/** + * See header + */ +eap_radius_accounting_t *eap_radius_accounting_create() +{ + private_eap_radius_accounting_t *this; + + INIT(this, + .public = { + .listener = { + .ike_updown = _ike_updown, + .message = _message_hook, + .child_updown = _child_updown, + .child_rekey = _child_rekey, + }, + .destroy = _destroy, + }, + /* use system time as Session ID prefix */ + .prefix = (u_int32_t)time(NULL), + .sessions = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 32), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.h b/src/libcharon/plugins/eap_radius/eap_radius_accounting.h new file mode 100644 index 000000000..811a5bb90 --- /dev/null +++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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 eap_radius_accounting eap_radius_accounting + * @{ @ingroup eap_radius + */ + +#ifndef EAP_RADIUS_ACCOUNTING_H_ +#define EAP_RADIUS_ACCOUNTING_H_ + +#include <bus/listeners/listener.h> + +typedef struct eap_radius_accounting_t eap_radius_accounting_t; + +/** + * RADIUS accounting for IKE/IPsec. + */ +struct eap_radius_accounting_t { + + /** + * Implements listener_t. + */ + listener_t listener; + + /** + * Destroy a eap_radius_accounting_t. + */ + void (*destroy)(eap_radius_accounting_t *this); +}; + +/** + * Create a eap_radius_accounting instance. + */ +eap_radius_accounting_t *eap_radius_accounting_create(); + +#endif /** EAP_RADIUS_ACCOUNTING_H_ @}*/ diff --git a/src/libcharon/plugins/eap_radius/eap_radius_dae.c b/src/libcharon/plugins/eap_radius/eap_radius_dae.c new file mode 100644 index 000000000..e84fe5b9c --- /dev/null +++ b/src/libcharon/plugins/eap_radius/eap_radius_dae.c @@ -0,0 +1,543 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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. + */ + +#include "eap_radius_dae.h" + +#include <radius_message.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <unistd.h> +#include <errno.h> + +#include <daemon.h> +#include <threading/thread.h> +#include <processing/jobs/callback_job.h> +#include <processing/jobs/delete_ike_sa_job.h> + +#define RADIUS_DAE_PORT 3799 + +typedef struct private_eap_radius_dae_t private_eap_radius_dae_t; + +/** + * Private data of an eap_radius_dae_t object. + */ +struct private_eap_radius_dae_t { + + /** + * Public eap_radius_dae_t interface. + */ + eap_radius_dae_t public; + + /** + * RADIUS session state + */ + eap_radius_accounting_t *accounting; + + /** + * Socket to listen on authorization extension port + */ + int fd; + + /** + * Listen job + */ + callback_job_t *job; + + /** + * RADIUS shared secret for DAE exchanges + */ + chunk_t secret; + + /** + * MD5 hasher + */ + hasher_t *hasher; + + /** + * HMAC MD5 signer, with secret set + */ + signer_t *signer; + + /** + * List of responses for retransmission, as entry_t + */ + linked_list_t *responses; +}; + +/** + * Entry to store responses for retransmit + */ +typedef struct { + /** stored response */ + radius_message_t *response; + /** client that sent the request */ + host_t *client; +} entry_t; + +/** + * Clean up an entry + */ +static void entry_destroy(entry_t *entry) +{ + entry->response->destroy(entry->response); + entry->client->destroy(entry->client); + free(entry); +} + +/** + * Save/Replace response for retransmission + */ +static void save_retransmit(private_eap_radius_dae_t *this, + radius_message_t *response, host_t *client) +{ + enumerator_t *enumerator; + entry_t *entry; + bool found = FALSE; + + enumerator = this->responses->create_enumerator(this->responses); + while (enumerator->enumerate(enumerator, &entry)) + { + if (client->equals(client, entry->client)) + { + entry->response->destroy(entry->response); + entry->response = response; + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + if (!found) + { + INIT(entry, + .response = response, + .client = client->clone(client), + ); + this->responses->insert_first(this->responses, entry); + } +} + +/** + * Send a RADIUS message to client + */ +static void send_message(private_eap_radius_dae_t *this, + radius_message_t *message, host_t *client) +{ + chunk_t data; + + data = message->get_encoding(message); + if (sendto(this->fd, data.ptr, data.len, 0, client->get_sockaddr(client), + *client->get_sockaddr_len(client)) != data.len) + { + DBG1(DBG_CFG, "sending RADIUS DAE response failed: %s", strerror(errno)); + } +} + +/** + * Check if we request is a retransmit, retransmit stored response + */ +static bool send_retransmit(private_eap_radius_dae_t *this, + radius_message_t *request, host_t *client) +{ + enumerator_t *enumerator; + entry_t *entry; + bool found = FALSE; + + enumerator = this->responses->create_enumerator(this->responses); + while (enumerator->enumerate(enumerator, &entry)) + { + if (client->equals(client, entry->client) && + request->get_identifier(request) == + entry->response->get_identifier(entry->response)) + { + DBG1(DBG_CFG, "received retransmit of RADIUS %N, retransmitting %N " + "to %H", radius_message_code_names, request->get_code(request), + radius_message_code_names, + entry->response->get_code(entry->response), client); + send_message(this, entry->response, client); + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + return found; +} + +/** + * Send an ACK/NAK response for a request + */ +static void send_response(private_eap_radius_dae_t *this, + radius_message_t *request, radius_message_code_t code, + host_t *client) +{ + radius_message_t *response; + + response = radius_message_create(code); + response->set_identifier(response, request->get_identifier(request)); + response->sign(response, request->get_authenticator(request), + this->secret, this->hasher, this->signer, NULL, FALSE); + + send_message(this, response, client); + save_retransmit(this, response, client); +} + +/** + * Add all IKE_SAs matching to user to a list + */ +static void add_matching_ike_sas(linked_list_t *list, identification_t *user) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + ike_sa_id_t *id; + + enumerator = charon->ike_sa_manager->create_enumerator( + charon->ike_sa_manager, FALSE); + while (enumerator->enumerate(enumerator, &ike_sa)) + { + if (user->matches(user, ike_sa->get_other_eap_id(ike_sa))) + { + id = ike_sa->get_id(ike_sa); + list->insert_last(list, id->clone(id)); + } + } + enumerator->destroy(enumerator); +} + +/** + * Get list of IKE_SAs matching a Disconnect/CoA request + */ +static linked_list_t *get_matching_ike_sas(private_eap_radius_dae_t *this, + radius_message_t *request, host_t *client) +{ + enumerator_t *enumerator; + identification_t *user; + linked_list_t *ids; + chunk_t data; + int type; + + ids = linked_list_create(); + + enumerator = request->create_enumerator(request); + while (enumerator->enumerate(enumerator, &type, &data)) + { + if (type == RAT_USER_NAME && data.len) + { + user = identification_create_from_data(data); + DBG1(DBG_CFG, "received RADIUS DAE %N for %Y from %H", + radius_message_code_names, request->get_code(request), + user, client); + add_matching_ike_sas(ids, user); + user->destroy(user); + } + } + enumerator->destroy(enumerator); + + return ids; +} + +/** + * Process a DAE disconnect request, send response + */ +static void process_disconnect(private_eap_radius_dae_t *this, + radius_message_t *request, host_t *client) +{ + enumerator_t *enumerator; + linked_list_t *ids; + ike_sa_id_t *id; + + ids = get_matching_ike_sas(this, request, client); + + if (ids->get_count(ids)) + { + DBG1(DBG_CFG, "closing %d IKE_SA%s matching %N, sending %N", + ids->get_count(ids), ids->get_count(ids) > 1 ? "s" : "", + radius_message_code_names, RMC_DISCONNECT_REQUEST, + radius_message_code_names, RMC_DISCONNECT_ACK); + + enumerator = ids->create_enumerator(ids); + while (enumerator->enumerate(enumerator, &id)) + { + lib->processor->queue_job(lib->processor, (job_t*) + delete_ike_sa_job_create(id, TRUE)); + } + enumerator->destroy(enumerator); + + send_response(this, request, RMC_DISCONNECT_ACK, client); + } + else + { + DBG1(DBG_CFG, "no IKE_SA matches %N, sending %N", + radius_message_code_names, RMC_DISCONNECT_REQUEST, + radius_message_code_names, RMC_DISCONNECT_NAK); + send_response(this, request, RMC_DISCONNECT_NAK, client); + } + ids->destroy_offset(ids, offsetof(ike_sa_id_t, destroy)); +} + +/** + * Apply a new lifetime to an IKE_SA + */ +static void apply_lifetime(private_eap_radius_dae_t *this, ike_sa_id_t *id, + u_int32_t lifetime) +{ + ike_sa_t *ike_sa; + + ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id); + if (ike_sa) + { + if (ike_sa->set_auth_lifetime(ike_sa, lifetime) == DESTROY_ME) + { + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, + ike_sa); + } + else + { + charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + } + } +} + +/** + * Process a DAE CoA request, send response + */ +static void process_coa(private_eap_radius_dae_t *this, + radius_message_t *request, host_t *client) +{ + enumerator_t *enumerator; + linked_list_t *ids; + ike_sa_id_t *id; + chunk_t data; + int type; + u_int32_t lifetime = 0; + bool lifetime_seen = FALSE; + + ids = get_matching_ike_sas(this, request, client); + + if (ids->get_count(ids)) + { + enumerator = request->create_enumerator(request); + while (enumerator->enumerate(enumerator, &type, &data)) + { + if (type == RAT_SESSION_TIMEOUT && data.len == 4) + { + lifetime = untoh32(data.ptr); + lifetime_seen = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + if (lifetime_seen) + { + DBG1(DBG_CFG, "applying %us lifetime to %d IKE_SA%s matching %N, " + "sending %N", lifetime, ids->get_count(ids), + ids->get_count(ids) > 1 ? "s" : "", + radius_message_code_names, RMC_COA_REQUEST, + radius_message_code_names, RMC_COA_ACK); + + enumerator = ids->create_enumerator(ids); + while (enumerator->enumerate(enumerator, &id)) + { + apply_lifetime(this, id, lifetime); + } + enumerator->destroy(enumerator); + send_response(this, request, RMC_COA_ACK, client); + } + else + { + DBG1(DBG_CFG, "no Session-Timeout attribute found in %N, sending %N", + radius_message_code_names, RMC_COA_REQUEST, + radius_message_code_names, RMC_COA_NAK); + send_response(this, request, RMC_COA_NAK, client); + } + } + else + { + DBG1(DBG_CFG, "no IKE_SA matches %N, sending %N", + radius_message_code_names, RMC_COA_REQUEST, + radius_message_code_names, RMC_COA_NAK); + send_response(this, request, RMC_COA_NAK, client); + } + ids->destroy_offset(ids, offsetof(ike_sa_id_t, destroy)); +} + +/** + * Receive RADIUS DAE requests + */ +static job_requeue_t receive(private_eap_radius_dae_t *this) +{ + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + radius_message_t *request; + char buf[2048]; + ssize_t len; + bool oldstate; + host_t *client; + + oldstate = thread_cancelability(TRUE); + len = recvfrom(this->fd, buf, sizeof(buf), 0, + (struct sockaddr*)&addr, &addr_len); + thread_cancelability(oldstate); + + if (len > 0) + { + request = radius_message_parse(chunk_create(buf, len)); + if (request) + { + client = host_create_from_sockaddr((struct sockaddr*)&addr); + if (client) + { + if (!send_retransmit(this, request, client)) + { + if (request->verify(request, NULL, this->secret, + this->hasher, this->signer)) + { + switch (request->get_code(request)) + { + case RMC_DISCONNECT_REQUEST: + process_disconnect(this, request, client); + break; + case RMC_COA_REQUEST: + process_coa(this, request, client); + break; + default: + DBG1(DBG_CFG, "ignoring unsupported RADIUS DAE " + "%N message from %H", + radius_message_code_names, + request->get_code(request), client); + break; + } + } + } + client->destroy(client); + } + request->destroy(request); + } + else + { + DBG1(DBG_NET, "ignoring invalid RADIUS DAE request"); + } + } + else + { + DBG1(DBG_NET, "receiving RADIUS DAE request failed: %s", strerror(errno)); + } + return JOB_REQUEUE_DIRECT; +} + +/** + * Open DAE socket + */ +static bool open_socket(private_eap_radius_dae_t *this) +{ + host_t *host; + + this->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (this->fd == -1) + { + DBG1(DBG_CFG, "unable to open RADIUS DAE socket: %s", strerror(errno)); + return FALSE; + } + + host = host_create_from_string( + lib->settings->get_str(lib->settings, + "charon.plugins.eap-radius.dae.listen", "0.0.0.0"), + lib->settings->get_int(lib->settings, + "charon.plugins.eap-radius.dae.port", RADIUS_DAE_PORT)); + if (!host) + { + DBG1(DBG_CFG, "invalid RADIUS DAE listen address"); + return FALSE; + } + + if (bind(this->fd, host->get_sockaddr(host), + *host->get_sockaddr_len(host)) == -1) + { + DBG1(DBG_CFG, "unable to bind RADIUS DAE socket: %s", strerror(errno)); + host->destroy(host); + return FALSE; + } + host->destroy(host); + return TRUE; +} + +METHOD(eap_radius_dae_t, destroy, void, + private_eap_radius_dae_t *this) +{ + if (this->job) + { + this->job->cancel(this->job); + } + if (this->fd != -1) + { + close(this->fd); + } + DESTROY_IF(this->signer); + DESTROY_IF(this->hasher); + this->responses->destroy_function(this->responses, (void*)entry_destroy); + free(this); +} + +/** + * See header + */ +eap_radius_dae_t *eap_radius_dae_create(eap_radius_accounting_t *accounting) +{ + private_eap_radius_dae_t *this; + + INIT(this, + .public = { + .destroy = _destroy, + }, + .accounting = accounting, + .fd = -1, + .secret = { + .ptr = lib->settings->get_str(lib->settings, + "charon.plugins.eap-radius.dae.secret", NULL), + }, + .hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5), + .signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128), + .responses = linked_list_create(), + ); + + if (!this->hasher || !this->signer) + { + destroy(this); + return NULL; + } + if (!this->secret.ptr) + { + DBG1(DBG_CFG, "missing RADIUS DAE secret, disabled"); + destroy(this); + return NULL; + } + this->secret.len = strlen(this->secret.ptr); + this->signer->set_key(this->signer, this->secret); + + if (!open_socket(this)) + { + destroy(this); + return NULL; + } + + this->job = callback_job_create_with_prio((callback_job_cb_t)receive, + this, NULL, NULL, JOB_PRIO_CRITICAL); + lib->processor->queue_job(lib->processor, (job_t*)this->job); + + return &this->public; +} diff --git a/src/libcharon/plugins/eap_radius/eap_radius_dae.h b/src/libcharon/plugins/eap_radius/eap_radius_dae.h new file mode 100644 index 000000000..759eadb49 --- /dev/null +++ b/src/libcharon/plugins/eap_radius/eap_radius_dae.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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 eap_radius_dae eap_radius_dae + * @{ @ingroup eap_radius + */ + +#ifndef EAP_RADIUS_DAE_H_ +#define EAP_RADIUS_DAE_H_ + +#include "eap_radius_accounting.h" + +typedef struct eap_radius_dae_t eap_radius_dae_t; + +/** + * Dynamic Authorization Extensions (RFC 5176) for EAP-RADIUS. + */ +struct eap_radius_dae_t { + + /** + * Destroy a eap_radius_dae_t. + */ + void (*destroy)(eap_radius_dae_t *this); +}; + +/** + * Create a eap_radius_dae instance. + */ +eap_radius_dae_t *eap_radius_dae_create(eap_radius_accounting_t *accounting); + +#endif /** EAP_RADIUS_DAE_H_ @}*/ diff --git a/src/libcharon/plugins/eap_radius/eap_radius_forward.c b/src/libcharon/plugins/eap_radius/eap_radius_forward.c new file mode 100644 index 000000000..cb4ca74e3 --- /dev/null +++ b/src/libcharon/plugins/eap_radius/eap_radius_forward.c @@ -0,0 +1,458 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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. + */ + +#include "eap_radius_forward.h" + +#include <daemon.h> +#include <utils/linked_list.h> +#include <utils/hashtable.h> +#include <threading/mutex.h> + +typedef struct private_eap_radius_forward_t private_eap_radius_forward_t; + +/** + * Private data of an eap_radius_forward_t object. + */ +struct private_eap_radius_forward_t { + + /** + * Public eap_radius_forward_t interface. + */ + eap_radius_forward_t public; + + /** + * List of attribute types to copy from IKE, as attr_t + */ + linked_list_t *from_attr; + + /** + * List of attribute types to copy to IKE, as attr_t + */ + linked_list_t *to_attr; + + /** + * Queued to forward from IKE, unique_id => linked_list_t of chunk_t + */ + hashtable_t *from; + + /** + * Queued to forward to IKE, unique_id => linked_list_t of chunk_t + */ + hashtable_t *to; + + /** + * Mutex to lock concurrent access to hashtables + */ + mutex_t *mutex; +}; + +/** + * RADIUS attribute selector + */ +typedef struct { + /** vendor ID, 0 for standard attributes */ + u_int32_t vendor; + /** attribute type */ + u_int8_t type; +} attr_t; + +/** + * Single instance of this + */ +static private_eap_radius_forward_t *singleton = NULL; + +/** + * Hashtable hash function + */ +static u_int hash(uintptr_t key) +{ + return key; +} + +/** + * Hashtable equals function + */ +static bool equals(uintptr_t a, uintptr_t b) +{ + return a == b; +} + +/** + * Free a queue entry + */ +static void free_attribute(chunk_t *chunk) +{ + free(chunk->ptr); + free(chunk); +} + +/** + * Lookup/create an attribute queue from a table + */ +static linked_list_t *lookup_queue(private_eap_radius_forward_t *this, + hashtable_t *table) +{ + linked_list_t *queue = NULL; + ike_sa_t *ike_sa; + uintptr_t id; + + ike_sa = charon->bus->get_sa(charon->bus); + if (ike_sa && ike_sa->supports_extension(ike_sa, EXT_STRONGSWAN)) + { + id = ike_sa->get_unique_id(ike_sa); + this->mutex->lock(this->mutex); + queue = table->get(table, (void*)id); + if (!queue) + { + queue = linked_list_create(); + table->put(table, (void*)id, queue); + } + this->mutex->unlock(this->mutex); + } + return queue; +} + +/** + * Remove attribute queue from table + */ +static void remove_queue(private_eap_radius_forward_t *this, + hashtable_t *table, ike_sa_t *ike_sa) +{ + linked_list_t *queue; + + this->mutex->lock(this->mutex); + queue = table->remove(table, (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa)); + this->mutex->unlock(this->mutex); + if (queue) + { + queue->destroy_function(queue, (void*)free_attribute); + } +} + +/** + * Check if RADIUS attribute is contained in selector + */ +static bool is_attribute_selected(linked_list_t *selector, + radius_attribute_type_t type, chunk_t data) +{ + enumerator_t *enumerator; + u_int32_t vendor = 0; + attr_t *sel; + bool found = FALSE; + + if (type == RAT_VENDOR_SPECIFIC) + { + if (data.len < 4) + { + return FALSE; + } + vendor = untoh32(data.ptr); + } + enumerator = selector->create_enumerator(selector); + while (!found && enumerator->enumerate(enumerator, &sel)) + { + if (sel->vendor == vendor) + { + if (vendor) + { + if (sel->type == 0) + { /* any of that vendor is fine */ + found = TRUE; + } + else if (data.len > 4 && data.ptr[4] == sel->type) + { /* vendor specific type field, as defined in RFC 2865 */ + found = TRUE; + } + } + else + { + if (sel->type == type) + { + found = TRUE; + } + } + } + } + enumerator->destroy(enumerator); + + return found; +} + +/** + * Copy RADIUS attributes from queue to a RADIUS message + */ +static void queue2radius(linked_list_t *queue, radius_message_t *message) +{ + chunk_t *data; + + while (queue->remove_last(queue, (void**)&data) == SUCCESS) + { + if (data->len >= 2) + { + message->add(message, data->ptr[0], chunk_skip(*data, 2)); + } + free_attribute(data); + } +} + +/** + * Copy RADIUS attributes from a RADIUS message to the queue + */ +static void radius2queue(radius_message_t *message, linked_list_t *queue, + linked_list_t *selector) +{ + enumerator_t *enumerator; + int type; + chunk_t data, hdr, *ptr; + + enumerator = message->create_enumerator(message); + while (enumerator->enumerate(enumerator, &type, &data)) + { + if (is_attribute_selected(selector, type, data)) + { + hdr = chunk_alloc(2); + hdr.ptr[0] = type; + hdr.ptr[1] = data.len + 2; + + INIT(ptr); + *ptr = chunk_cat("mc", hdr, data); + queue->insert_last(queue, ptr); + } + } + enumerator->destroy(enumerator); +} + +/** + * Copy RADIUS attribute nofifies from IKE message to queue + */ +static void ike2queue(message_t *message, linked_list_t *queue, + linked_list_t *selector) +{ + enumerator_t *enumerator; + payload_t *payload; + notify_payload_t *notify; + chunk_t data, *ptr; + + enumerator = message->create_payload_enumerator(message); + while (enumerator->enumerate(enumerator, &payload)) + { + if (payload->get_type(payload) == NOTIFY) + { + notify = (notify_payload_t*)payload; + if (notify->get_notify_type(notify) == RADIUS_ATTRIBUTE) + { + data = notify->get_notification_data(notify); + if (data.len >= 2 && is_attribute_selected(selector, + data.ptr[0], chunk_skip(data, 2))) + { + INIT(ptr); + *ptr = chunk_clone(data); + queue->insert_last(queue, ptr); + } + } + } + } + enumerator->destroy(enumerator); +} + +/** + * Copy RADUIS attributes from queue to IKE message notifies + */ +static void queue2ike(linked_list_t *queue, message_t *message) +{ + chunk_t *data; + + while (queue->remove_last(queue, (void**)&data) == SUCCESS) + { + message->add_notify(message, FALSE, RADIUS_ATTRIBUTE, *data); + free_attribute(data); + } +} + +/** + * See header. + */ +void eap_radius_forward_from_ike(radius_message_t *request) +{ + private_eap_radius_forward_t *this = singleton; + linked_list_t *queue; + + if (this) + { + queue = lookup_queue(this, this->from); + if (queue) + { + queue2radius(queue, request); + } + } +} + +/** + * See header. + */ +void eap_radius_forward_to_ike(radius_message_t *response) +{ + private_eap_radius_forward_t *this = singleton; + linked_list_t *queue; + + if (this) + { + queue = lookup_queue(this, this->to); + if (queue) + { + radius2queue(response, queue, this->to_attr); + } + } +} + +METHOD(listener_t, message, bool, + private_eap_radius_forward_t *this, + ike_sa_t *ike_sa, message_t *message, bool incoming) +{ + linked_list_t *queue; + + if (message->get_exchange_type(message) == IKE_AUTH) + { + if (incoming) + { + queue = lookup_queue(this, this->from); + if (queue) + { + ike2queue(message, queue, this->from_attr); + } + } + else + { + queue = lookup_queue(this, this->to); + if (queue) + { + queue2ike(queue, message); + } + } + } + return TRUE; +} + +METHOD(listener_t, ike_updown, bool, + private_eap_radius_forward_t *this, ike_sa_t *ike_sa, bool up) +{ + /* up or down, we don't need the state anymore */ + remove_queue(this, this->from, ike_sa); + remove_queue(this, this->to, ike_sa); + return TRUE; +} + +/** + * Parse a selector string to a list of attr_t selectors + */ +static linked_list_t* parse_selector(char *selector) +{ + enumerator_t *enumerator; + linked_list_t *list; + char *token, *pos; + + list = linked_list_create(); + enumerator = enumerator_create_token(selector, ",", " "); + while (enumerator->enumerate(enumerator, &token)) + { + int type, vendor = 0; + attr_t *attr; + + pos = strchr(token, ':'); + if (pos) + { + *(pos++) = 0; + vendor = atoi(token); + token = pos; + } + type = enum_from_name(radius_attribute_type_names, token); + if (type == -1) + { + type = atoi(token); + } + if (vendor == 0 && type == 0) + { + DBG1(DBG_CFG, "ignoring unknown RADIUS attribute type '%s'", token); + } + else + { + INIT(attr, + .type = type, + .vendor = vendor, + ); + list->insert_last(list, attr); + if (!vendor) + { + DBG1(DBG_IKE, "forwarding RADIUS attribute %N", + radius_attribute_type_names, type); + } + else + { + DBG1(DBG_IKE, "forwarding RADIUS VSA %d-%d", vendor, type); + } + } + } + enumerator->destroy(enumerator); + return list; +} + +METHOD(eap_radius_forward_t, destroy, void, + private_eap_radius_forward_t *this) +{ + this->from_attr->destroy_function(this->from_attr, free); + this->to_attr->destroy_function(this->to_attr, free); + this->from->destroy(this->from); + this->to->destroy(this->to); + this->mutex->destroy(this->mutex); + free(this); + singleton = NULL; +} + +/** + * See header + */ +eap_radius_forward_t *eap_radius_forward_create() +{ + private_eap_radius_forward_t *this; + + INIT(this, + .public = { + .listener = { + .message = _message, + .ike_updown = _ike_updown, + }, + .destroy = _destroy, + }, + .from_attr = parse_selector(lib->settings->get_str(lib->settings, + "charon.plugins.eap-radius.forward.ike_to_radius", "")), + .to_attr = parse_selector(lib->settings->get_str(lib->settings, + "charon.plugins.eap-radius.forward.radius_to_ike", "")), + .from = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 8), + .to = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 8), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + ); + + if (this->from_attr->get_count(this->from_attr) == 0 && + this->to_attr->get_count(this->to_attr) == 0) + { + destroy(this); + return NULL; + } + + singleton = this; + return &this->public; +} diff --git a/src/libcharon/plugins/eap_radius/eap_radius_forward.h b/src/libcharon/plugins/eap_radius/eap_radius_forward.h new file mode 100644 index 000000000..2c1dbf7a8 --- /dev/null +++ b/src/libcharon/plugins/eap_radius/eap_radius_forward.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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 eap_radius_forward eap_radius_forward + * @{ @ingroup eap_radius + */ + +#ifndef EAP_RADIUS_FORWARD_H_ +#define EAP_RADIUS_FORWARD_H_ + +#include <radius_message.h> + +#include <bus/listeners/listener.h> + +typedef struct eap_radius_forward_t eap_radius_forward_t; + +/** + * Forward RADIUS attributes in Notifies between client and AAA backend. + */ +struct eap_radius_forward_t { + + /** + * Implements a listener. + */ + listener_t listener; + + /** + * Destroy a eap_radius_forward_t. + */ + void (*destroy)(eap_radius_forward_t *this); +}; + +/** + * Create a eap_radius_forward instance. + */ +eap_radius_forward_t *eap_radius_forward_create(); + +/** + * Forward RADIUS attributes from IKE notifies to a RADIUS request. + * + * @param request RADIUS request message to add attributes to + */ +void eap_radius_forward_from_ike(radius_message_t *request); + +/** + * Forward RADIUS attributes from a RADIUS response to IKE notifies. + * + * @param response RADIUS respose to read notifies from + */ +void eap_radius_forward_to_ike(radius_message_t *response); + +#endif /** EAP_RADIUS_FORWARD_H_ @}*/ diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c index c218bd48b..8ee0ab81a 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c @@ -16,16 +16,25 @@ #include "eap_radius_plugin.h" #include "eap_radius.h" -#include "radius_client.h" -#include "radius_server.h" +#include "eap_radius_accounting.h" +#include "eap_radius_dae.h" +#include "eap_radius_forward.h" + +#include <radius_client.h> +#include <radius_config.h> #include <daemon.h> #include <threading/rwlock.h> /** - * Default RADIUS server port, when not configured + * Default RADIUS server port for authentication */ -#define RADIUS_PORT 1812 +#define AUTH_PORT 1812 + +/** + * Default RADIUS server port for accounting + */ +#define ACCT_PORT 1813 typedef struct private_eap_radius_plugin_t private_eap_radius_plugin_t; @@ -40,14 +49,29 @@ struct private_eap_radius_plugin_t { eap_radius_plugin_t public; /** - * List of RADIUS servers + * List of RADIUS server configurations */ - linked_list_t *servers; + linked_list_t *configs; /** - * Lock for server list + * Lock for configs list */ rwlock_t *lock; + + /** + * RADIUS sessions for accounting + */ + eap_radius_accounting_t *accounting; + + /** + * Dynamic authorization extensions + */ + eap_radius_dae_t *dae; + + /** + * RADIUS <-> IKE attribute forwarding + */ + eap_radius_forward_t *forward; }; /** @@ -58,12 +82,12 @@ static private_eap_radius_plugin_t *instance = NULL; /** * Load RADIUS servers from configuration */ -static void load_servers(private_eap_radius_plugin_t *this) +static void load_configs(private_eap_radius_plugin_t *this) { enumerator_t *enumerator; - radius_server_t *server; + radius_config_t *config; char *nas_identifier, *secret, *address, *section; - int port, sockets, preference; + int auth_port, acct_port, sockets, preference; address = lib->settings->get_str(lib->settings, "charon.plugins.eap-radius.server", NULL); @@ -78,18 +102,18 @@ static void load_servers(private_eap_radius_plugin_t *this) } nas_identifier = lib->settings->get_str(lib->settings, "charon.plugins.eap-radius.nas_identifier", "strongSwan"); - port = lib->settings->get_int(lib->settings, - "charon.plugins.eap-radius.port", RADIUS_PORT); + auth_port = lib->settings->get_int(lib->settings, + "charon.plugins.eap-radius.port", AUTH_PORT); sockets = lib->settings->get_int(lib->settings, "charon.plugins.eap-radius.sockets", 1); - server = radius_server_create(address, address, port, nas_identifier, - secret, sockets, 0); - if (!server) + config = radius_config_create(address, address, auth_port, ACCT_PORT, + nas_identifier, secret, sockets, 0); + if (!config) { DBG1(DBG_CFG, "no RADUIS server defined"); return; } - this->servers->insert_last(this->servers, server); + this->configs->insert_last(this->configs, config); return; } @@ -114,26 +138,32 @@ static void load_servers(private_eap_radius_plugin_t *this) nas_identifier = lib->settings->get_str(lib->settings, "charon.plugins.eap-radius.servers.%s.nas_identifier", "strongSwan", section); - port = lib->settings->get_int(lib->settings, - "charon.plugins.eap-radius.servers.%s.port", RADIUS_PORT, section); + auth_port = lib->settings->get_int(lib->settings, + "charon.plugins.eap-radius.servers.%s.auth_port", + lib->settings->get_int(lib->settings, + "charon.plugins.eap-radius.servers.%s.port", + AUTH_PORT, section), + section); + acct_port = lib->settings->get_int(lib->settings, + "charon.plugins.eap-radius.servers.%s.acct_port", ACCT_PORT, section); sockets = lib->settings->get_int(lib->settings, "charon.plugins.eap-radius.servers.%s.sockets", 1, section); preference = lib->settings->get_int(lib->settings, "charon.plugins.eap-radius.servers.%s.preference", 0, section); - server = radius_server_create(section, address, port, nas_identifier, - secret, sockets, preference); - if (!server) + config = radius_config_create(section, address, auth_port, acct_port, + nas_identifier, secret, sockets, preference); + if (!config) { DBG1(DBG_CFG, "loading RADIUS server '%s' failed, skipped", section); continue; } - this->servers->insert_last(this->servers, server); + this->configs->insert_last(this->configs, config); } enumerator->destroy(enumerator); DBG1(DBG_CFG, "loaded %d RADIUS server configuration%s", - this->servers->get_count(this->servers), - this->servers->get_count(this->servers) == 1 ? "" : "s"); + this->configs->get_count(this->configs), + this->configs->get_count(this->configs) == 1 ? "" : "s"); } METHOD(plugin_t, get_name, char*, @@ -142,14 +172,28 @@ METHOD(plugin_t, get_name, char*, return "eap-radius"; } +METHOD(plugin_t, get_features, int, + eap_radius_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_radius_create), + PLUGIN_PROVIDE(EAP_SERVER, EAP_RADIUS), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_MD5_128), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, reload, bool, private_eap_radius_plugin_t *this) { this->lock->write_lock(this->lock); - this->servers->destroy_offset(this->servers, - offsetof(radius_server_t, destroy)); - this->servers = linked_list_create(); - load_servers(this); + this->configs->destroy_offset(this->configs, + offsetof(radius_config_t, destroy)); + this->configs = linked_list_create(); + load_configs(this); this->lock->unlock(this->lock); return TRUE; } @@ -157,10 +201,17 @@ METHOD(plugin_t, reload, bool, METHOD(plugin_t, destroy, void, private_eap_radius_plugin_t *this) { - charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create); - this->servers->destroy_offset(this->servers, - offsetof(radius_server_t, destroy)); + if (this->forward) + { + charon->bus->remove_listener(charon->bus, &this->forward->listener); + this->forward->destroy(this->forward); + } + DESTROY_IF(this->dae); + this->configs->destroy_offset(this->configs, + offsetof(radius_config_t, destroy)); this->lock->destroy(this->lock); + charon->bus->remove_listener(charon->bus, &this->accounting->listener); + this->accounting->destroy(this->accounting); free(this); instance = NULL; } @@ -176,36 +227,78 @@ plugin_t *eap_radius_plugin_create() .public = { .plugin = { .get_name = _get_name, + .get_features = _get_features, .reload = _reload, .destroy = _destroy, }, }, - .servers = linked_list_create(), + .configs = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .accounting = eap_radius_accounting_create(), + .forward = eap_radius_forward_create(), ); - load_servers(this); - - charon->eap->add_method(charon->eap, EAP_RADIUS, 0, - EAP_SERVER, (eap_constructor_t)eap_radius_create); - + load_configs(this); instance = this; + if (lib->settings->get_bool(lib->settings, + "charon.plugins.eap-radius.accounting", FALSE)) + { + charon->bus->add_listener(charon->bus, &this->accounting->listener); + } + if (lib->settings->get_bool(lib->settings, + "charon.plugins.eap-radius.dae.enable", FALSE)) + { + this->dae = eap_radius_dae_create(this->accounting); + } + if (this->forward) + { + charon->bus->add_listener(charon->bus, &this->forward->listener); + } + return &this->public.plugin; } /** * See header */ -enumerator_t *eap_radius_create_server_enumerator() +radius_client_t *eap_radius_create_client() { if (instance) { + enumerator_t *enumerator; + radius_config_t *config, *selected = NULL; + int current, best = -1; + instance->lock->read_lock(instance->lock); - return enumerator_create_cleaner( - instance->servers->create_enumerator(instance->servers), - (void*)instance->lock->unlock, instance->lock); + enumerator = instance->configs->create_enumerator(instance->configs); + while (enumerator->enumerate(enumerator, &config)) + { + current = config->get_preference(config); + if (current > best || + /* for two with equal preference, 50-50 chance */ + (current == best && random() % 2 == 0)) + { + DBG2(DBG_CFG, "RADIUS server '%s' is candidate: %d", + config->get_name(config), current); + best = current; + DESTROY_IF(selected); + selected = config->get_ref(config); + } + else + { + DBG2(DBG_CFG, "RADIUS server '%s' skipped: %d", + config->get_name(config), current); + } + } + enumerator->destroy(enumerator); + instance->lock->unlock(instance->lock); + + if (selected) + { + return radius_client_create(selected); + } } - return enumerator_create_empty(); + return NULL; } diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.h b/src/libcharon/plugins/eap_radius/eap_radius_plugin.h index cb724364a..1570bd566 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.h +++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.h @@ -25,7 +25,8 @@ #define EAP_RADIUS_PLUGIN_H_ #include <plugins/plugin.h> -#include <utils/enumerator.h> + +#include <radius_client.h> typedef struct eap_radius_plugin_t eap_radius_plugin_t; @@ -44,10 +45,10 @@ struct eap_radius_plugin_t { }; /** - * Create an enumerator over all loaded RADIUS servers. + * Get a RADIUS client instance to connect to servers. * - * @return enumerator over radius_server_t + * @return RADIUS client */ -enumerator_t *eap_radius_create_server_enumerator(); +radius_client_t *eap_radius_create_client(); #endif /** EAP_RADIUS_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/eap_radius/radius_client.c b/src/libcharon/plugins/eap_radius/radius_client.c deleted file mode 100644 index 245308e59..000000000 --- a/src/libcharon/plugins/eap_radius/radius_client.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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. - */ - -#include "radius_client.h" - -#include "eap_radius_plugin.h" -#include "radius_server.h" - -#include <unistd.h> -#include <errno.h> - -#include <daemon.h> -#include <utils/host.h> -#include <utils/linked_list.h> -#include <threading/condvar.h> -#include <threading/mutex.h> - -typedef struct private_radius_client_t private_radius_client_t; - -/** - * Private data of an radius_client_t object. - */ -struct private_radius_client_t { - - /** - * Public radius_client_t interface. - */ - radius_client_t public; - - /** - * Selected RADIUS server - */ - radius_server_t *server; - - /** - * RADIUS servers State attribute - */ - chunk_t state; - - /** - * EAP MSK, from MPPE keys - */ - chunk_t msk; -}; - -/** - * Save the state attribute to include in further request - */ -static void save_state(private_radius_client_t *this, radius_message_t *msg) -{ - enumerator_t *enumerator; - int type; - chunk_t data; - - enumerator = msg->create_enumerator(msg); - while (enumerator->enumerate(enumerator, &type, &data)) - { - if (type == RAT_STATE) - { - free(this->state.ptr); - this->state = chunk_clone(data); - enumerator->destroy(enumerator); - return; - } - } - enumerator->destroy(enumerator); - /* no state attribute found, remove state */ - chunk_free(&this->state); -} - -METHOD(radius_client_t, request, radius_message_t*, - private_radius_client_t *this, radius_message_t *req) -{ - char virtual[] = {0x00,0x00,0x00,0x05}; - radius_socket_t *socket; - radius_message_t *res; - - /* we add the "Virtual" NAS-Port-Type, as we SHOULD include one */ - req->add(req, RAT_NAS_PORT_TYPE, chunk_create(virtual, sizeof(virtual))); - /* add our NAS-Identifier */ - req->add(req, RAT_NAS_IDENTIFIER, - this->server->get_nas_identifier(this->server)); - /* add State attribute, if server sent one */ - if (this->state.ptr) - { - req->add(req, RAT_STATE, this->state); - } - socket = this->server->get_socket(this->server); - DBG1(DBG_CFG, "sending RADIUS %N to server '%s'", radius_message_code_names, - req->get_code(req), this->server->get_name(this->server)); - res = socket->request(socket, req); - if (res) - { - DBG1(DBG_CFG, "received RADIUS %N from server '%s'", - radius_message_code_names, res->get_code(res), - this->server->get_name(this->server)); - save_state(this, res); - if (res->get_code(res) == RMC_ACCESS_ACCEPT) - { - chunk_clear(&this->msk); - this->msk = socket->decrypt_msk(socket, req, res); - } - this->server->put_socket(this->server, socket, TRUE); - return res; - } - this->server->put_socket(this->server, socket, FALSE); - charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING); - return NULL; -} - -METHOD(radius_client_t, get_msk, chunk_t, - private_radius_client_t *this) -{ - return this->msk; -} - -METHOD(radius_client_t, destroy, void, - private_radius_client_t *this) -{ - this->server->destroy(this->server); - chunk_clear(&this->msk); - free(this->state.ptr); - free(this); -} - -/** - * See header - */ -radius_client_t *radius_client_create() -{ - private_radius_client_t *this; - enumerator_t *enumerator; - radius_server_t *server; - int current, best = -1; - - INIT(this, - .public = { - .request = _request, - .get_msk = _get_msk, - .destroy = _destroy, - }, - ); - - enumerator = eap_radius_create_server_enumerator(); - while (enumerator->enumerate(enumerator, &server)) - { - current = server->get_preference(server); - if (current > best || - /* for two with equal preference, 50-50 chance */ - (current == best && random() % 2 == 0)) - { - DBG2(DBG_CFG, "RADIUS server '%s' is candidate: %d", - server->get_name(server), current); - best = current; - DESTROY_IF(this->server); - this->server = server->get_ref(server); - } - else - { - DBG2(DBG_CFG, "RADIUS server '%s' skipped: %d", - server->get_name(server), current); - } - } - enumerator->destroy(enumerator); - - if (!this->server) - { - free(this); - return NULL; - } - - return &this->public; -} - diff --git a/src/libcharon/plugins/eap_radius/radius_client.h b/src/libcharon/plugins/eap_radius/radius_client.h deleted file mode 100644 index e4f3a7222..000000000 --- a/src/libcharon/plugins/eap_radius/radius_client.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 radius_client radius_client - * @{ @ingroup eap_radius - */ - -#ifndef RADIUS_CLIENT_H_ -#define RADIUS_CLIENT_H_ - -#include "radius_message.h" - -typedef struct radius_client_t radius_client_t; - -/** - * RADIUS client functionality. - * - * To communicate with a RADIUS server, create a client and send messages over - * it. The client allocates a socket from the best RADIUS server abailable. - */ -struct radius_client_t { - - /** - * Send a RADIUS request and wait for the response. - * - * The client fills in NAS-Identifier nad NAS-Port-Type - * - * @param msg RADIUS request message to send - * @return response, NULL if timed out/verification failed - */ - radius_message_t* (*request)(radius_client_t *this, radius_message_t *msg); - - /** - * Get the EAP MSK after successful RADIUS authentication. - * - * @return MSK, allocated - */ - chunk_t (*get_msk)(radius_client_t *this); - - /** - * Destroy the client, release the socket. - */ - void (*destroy)(radius_client_t *this); -}; - -/** - * Create a RADIUS client. - * - * @return radius_client_t object - */ -radius_client_t *radius_client_create(); - -#endif /** RADIUS_CLIENT_H_ @}*/ diff --git a/src/libcharon/plugins/eap_radius/radius_message.c b/src/libcharon/plugins/eap_radius/radius_message.c deleted file mode 100644 index 23a29b772..000000000 --- a/src/libcharon/plugins/eap_radius/radius_message.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - * 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. - */ - -#include "radius_message.h" - -#include <daemon.h> -#include <crypto/hashers/hasher.h> - -typedef struct private_radius_message_t private_radius_message_t; -typedef struct rmsg_t rmsg_t; -typedef struct rattr_t rattr_t; - -/** - * RADIUS message header - */ -struct rmsg_t { - /** message code, radius_message_code_t */ - u_int8_t code; - /** message identifier */ - u_int8_t identifier; - /** length of Code, Identifier, Length, Authenticator and Attributes */ - u_int16_t length; - /** message authenticator, MD5 hash */ - u_int8_t authenticator[HASH_SIZE_MD5]; - /** variable list of packed attributes */ - u_int8_t attributes[]; -} __attribute__((packed)); - -/** - * RADIUS message attribute. - */ -struct rattr_t { - /** attribute type, radius_attribute_type_t */ - u_int8_t type; - /** length of the attriubte, including the Type, Length and Value fields */ - u_int8_t length; - /** variable length attribute value */ - u_int8_t value[]; -} __attribute__((packed)); - -/** - * Private data of an radius_message_t object. - */ -struct private_radius_message_t { - - /** - * Public radius_message_t interface. - */ - radius_message_t public; - - /** - * message data, allocated - */ - rmsg_t *msg; -}; - -ENUM_BEGIN(radius_message_code_names, RMC_ACCESS_REQUEST, RMC_ACCOUNTING_RESPONSE, - "Access-Request", - "Access-Accept", - "Access-Reject", - "Accounting-Request", - "Accounting-Response"); -ENUM_NEXT(radius_message_code_names, RMC_ACCESS_CHALLENGE, RMC_ACCESS_CHALLENGE, RMC_ACCOUNTING_RESPONSE, - "Access-Challenge"); -ENUM_END(radius_message_code_names, RMC_ACCESS_CHALLENGE); - -ENUM(radius_attribute_type_names, RAT_USER_NAME, RAT_MIP6_HOME_LINK_PREFIX, - "User-Name", - "User-Password", - "CHAP-Password", - "NAS-IP-Address", - "NAS-Port", - "Service-Type", - "Framed-Protocol", - "Framed-IP-Address", - "Framed-IP-Netmask", - "Framed-Routing", - "Filter-Id", - "Framed-MTU", - "Framed-Compression", - "Login-IP-Host", - "Login-Service", - "Login-TCP-Port", - "Unassigned", - "Reply-Message", - "Callback-Number", - "Callback-Id", - "Unassigned", - "Framed-Route", - "Framed-IPX-Network", - "State", - "Class", - "Vendor-Specific", - "Session-Timeout", - "Idle-Timeout", - "Termination-Action", - "Called-Station-Id", - "Calling-Station-Id", - "NAS-Identifier", - "Proxy-State", - "Login-LAT-Service", - "Login-LAT-Node", - "Login-LAT-Group", - "Framed-AppleTalk-Link", - "Framed-AppleTalk-Network", - "Framed-AppleTalk-Zone", - "Acct-Status-Type", - "Acct-Delay-Time", - "Acct-Input-Octets", - "Acct-Output-Octets", - "Acct-Session-Id", - "Acct-Authentic", - "Acct-Session-Time", - "Acct-Input-Packets", - "Acct-Output-Packets", - "Acct-Terminate-Cause", - "Acct-Multi-Session-Id", - "Acct-Link-Count", - "Acct-Input-Gigawords", - "Acct-Output-Gigawords", - "Unassigned", - "Event-Timestamp", - "Egress-VLANID", - "Ingress-Filters", - "Egress-VLAN-Name", - "User-Priority-Table", - "CHAP-Challenge", - "NAS-Port-Type", - "Port-Limit", - "Login-LAT-Port", - "Tunnel-Type", - "Tunnel-Medium-Type", - "Tunnel-Client-Endpoint", - "Tunnel-Server-Endpoint", - "Acct-Tunnel-Connection", - "Tunnel-Password", - "ARAP-Password", - "ARAP-Features", - "ARAP-Zone-Access", - "ARAP-Security", - "ARAP-Security-Data", - "Password-Retry", - "Prompt", - "Connect-Info", - "Configuration-Token", - "EAP-Message", - "Message-Authenticator", - "Tunnel-Private-Group-ID", - "Tunnel-Assignment-ID", - "Tunnel-Preference", - "ARAP-Challenge-Response", - "Acct-Interim-Interval", - "Acct-Tunnel-Packets-Lost", - "NAS-Port-Id", - "Framed-Pool", - "CUI", - "Tunnel-Client-Auth-ID", - "Tunnel-Server-Auth-ID", - "NAS-Filter-Rule", - "Unassigned", - "Originating-Line-Info", - "NAS-IPv6-Address", - "Framed-Interface-Id", - "Framed-IPv6-Prefix", - "Login-IPv6-Host", - "Framed-IPv6-Route", - "Framed-IPv6-Pool", - "Error-Cause", - "EAP-Key-Name", - "Digest-Response", - "Digest-Realm", - "Digest-Nonce", - "Digest-Response-Auth", - "Digest-Nextnonce", - "Digest-Method", - "Digest-URI", - "Digest-Qop", - "Digest-Algorithm", - "Digest-Entity-Body-Hash", - "Digest-CNonce", - "Digest-Nonce-Count", - "Digest-Username", - "Digest-Opaque", - "Digest-Auth-Param", - "Digest-AKA-Auts", - "Digest-Domain", - "Digest-Stale", - "Digest-HA1", - "SIP-AOR", - "Delegated-IPv6-Prefix", - "MIP6-Feature-Vector", - "MIP6-Home-Link-Prefix"); - -/** - * Attribute enumerator implementation - */ -typedef struct { - /** implements enumerator interface */ - enumerator_t public; - /** currently pointing attribute */ - rattr_t *next; - /** bytes left */ - int left; -} attribute_enumerator_t; - -METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, int *type, chunk_t *data) -{ - if (this->left == 0) - { - return FALSE; - } - if (this->left < sizeof(rattr_t) || - this->left < this->next->length) - { - DBG1(DBG_IKE, "RADIUS message truncated"); - return FALSE; - } - *type = this->next->type; - data->ptr = this->next->value; - data->len = this->next->length - sizeof(rattr_t); - this->left -= this->next->length; - this->next = ((void*)this->next) + this->next->length; - return TRUE; -} - -METHOD(radius_message_t, create_enumerator, enumerator_t*, - private_radius_message_t *this) -{ - attribute_enumerator_t *e; - - if (ntohs(this->msg->length) < sizeof(rmsg_t) + sizeof(rattr_t)) - { - return enumerator_create_empty(); - } - INIT(e, - .public = { - .enumerate = (void*)_attribute_enumerate, - .destroy = (void*)free, - }, - .next = (rattr_t*)this->msg->attributes, - .left = ntohs(this->msg->length) - sizeof(rmsg_t), - ); - return &e->public; -} - -METHOD(radius_message_t, add, void, - private_radius_message_t *this, radius_attribute_type_t type, chunk_t data) -{ - rattr_t *attribute; - - data.len = min(data.len, 253); - this->msg = realloc(this->msg, - ntohs(this->msg->length) + sizeof(rattr_t) + data.len); - attribute = ((void*)this->msg) + ntohs(this->msg->length); - attribute->type = type; - attribute->length = data.len + sizeof(rattr_t); - memcpy(attribute->value, data.ptr, data.len); - this->msg->length = htons(ntohs(this->msg->length) + attribute->length); -} - -METHOD(radius_message_t, sign, void, - private_radius_message_t *this, rng_t *rng, signer_t *signer) -{ - char buf[HASH_SIZE_MD5]; - - /* build Request-Authenticator */ - rng->get_bytes(rng, HASH_SIZE_MD5, this->msg->authenticator); - - /* build Message-Authenticator attribute, using 16 null bytes */ - memset(buf, 0, sizeof(buf)); - add(this, RAT_MESSAGE_AUTHENTICATOR, chunk_create(buf, sizeof(buf))); - signer->get_signature(signer, - chunk_create((u_char*)this->msg, ntohs(this->msg->length)), - ((u_char*)this->msg) + ntohs(this->msg->length) - HASH_SIZE_MD5); -} - -METHOD(radius_message_t, verify, bool, - private_radius_message_t *this, u_int8_t *req_auth, chunk_t secret, - hasher_t *hasher, signer_t *signer) -{ - char buf[HASH_SIZE_MD5], res_auth[HASH_SIZE_MD5]; - enumerator_t *enumerator; - int type; - chunk_t data, msg; - bool has_eap = FALSE, has_auth = FALSE; - - /* replace Response by Request Authenticator for verification */ - memcpy(res_auth, this->msg->authenticator, HASH_SIZE_MD5); - memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5); - msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length)); - - /* verify Response-Authenticator */ - hasher->get_hash(hasher, msg, NULL); - hasher->get_hash(hasher, secret, buf); - if (!memeq(buf, res_auth, HASH_SIZE_MD5)) - { - DBG1(DBG_CFG, "RADIUS Response-Authenticator verification failed"); - return FALSE; - } - - /* verify Message-Authenticator attribute */ - enumerator = create_enumerator(this); - while (enumerator->enumerate(enumerator, &type, &data)) - { - if (type == RAT_MESSAGE_AUTHENTICATOR) - { - if (data.len != HASH_SIZE_MD5) - { - DBG1(DBG_CFG, "RADIUS Message-Authenticator invalid length"); - enumerator->destroy(enumerator); - return FALSE; - } - memcpy(buf, data.ptr, data.len); - memset(data.ptr, 0, data.len); - if (signer->verify_signature(signer, msg, - chunk_create(buf, sizeof(buf)))) - { - /* restore Message-Authenticator */ - memcpy(data.ptr, buf, data.len); - has_auth = TRUE; - break; - } - else - { - DBG1(DBG_CFG, "RADIUS Message-Authenticator verification failed"); - enumerator->destroy(enumerator); - return FALSE; - } - } - else if (type == RAT_EAP_MESSAGE) - { - has_eap = TRUE; - } - } - enumerator->destroy(enumerator); - /* restore Response-Authenticator */ - memcpy(this->msg->authenticator, res_auth, HASH_SIZE_MD5); - - if (has_eap && !has_auth) - { /* Message-Authenticator is required if we have an EAP-Message */ - DBG1(DBG_CFG, "RADIUS Message-Authenticator attribute missing"); - return FALSE; - } - return TRUE; -} - -METHOD(radius_message_t, get_code, radius_message_code_t, - private_radius_message_t *this) -{ - return this->msg->code; -} - -METHOD(radius_message_t, get_identifier, u_int8_t, - private_radius_message_t *this) -{ - return this->msg->identifier; -} - -METHOD(radius_message_t, set_identifier, void, - private_radius_message_t *this, u_int8_t identifier) -{ - this->msg->identifier = identifier; -} - -METHOD(radius_message_t, get_authenticator, u_int8_t*, - private_radius_message_t *this) -{ - return this->msg->authenticator; -} - - -METHOD(radius_message_t, get_encoding, chunk_t, - private_radius_message_t *this) -{ - return chunk_create((u_char*)this->msg, ntohs(this->msg->length)); -} - -METHOD(radius_message_t, destroy, void, - private_radius_message_t *this) -{ - free(this->msg); - free(this); -} - -/** - * Generic constructor - */ -static private_radius_message_t *radius_message_create() -{ - private_radius_message_t *this; - - INIT(this, - .public = { - .create_enumerator = _create_enumerator, - .add = _add, - .get_code = _get_code, - .get_identifier = _get_identifier, - .set_identifier = _set_identifier, - .get_authenticator = _get_authenticator, - .get_encoding = _get_encoding, - .sign = _sign, - .verify = _verify, - .destroy = _destroy, - }, - ); - - return this; -} - -/** - * See header - */ -radius_message_t *radius_message_create_request() -{ - private_radius_message_t *this = radius_message_create(); - - INIT(this->msg, - .code = RMC_ACCESS_REQUEST, - .identifier = 0, - .length = htons(sizeof(rmsg_t)), - ); - - return &this->public; -} - -/** - * See header - */ -radius_message_t *radius_message_parse_response(chunk_t data) -{ - private_radius_message_t *this = radius_message_create(); - - this->msg = malloc(data.len); - memcpy(this->msg, data.ptr, data.len); - if (data.len < sizeof(rmsg_t) || - ntohs(this->msg->length) != data.len) - { - DBG1(DBG_IKE, "RADIUS message has invalid length"); - destroy(this); - return NULL; - } - return &this->public; -} - diff --git a/src/libcharon/plugins/eap_radius/radius_message.h b/src/libcharon/plugins/eap_radius/radius_message.h deleted file mode 100644 index 266839d3b..000000000 --- a/src/libcharon/plugins/eap_radius/radius_message.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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 radius_message radius_message - * @{ @ingroup eap_radius - */ - -#ifndef RADIUS_MESSAGE_H_ -#define RADIUS_MESSAGE_H_ - -#include <library.h> - -typedef struct radius_message_t radius_message_t; -typedef enum radius_message_code_t radius_message_code_t; -typedef enum radius_attribute_type_t radius_attribute_type_t; - -/** - * RADIUS Message Codes. - */ -enum radius_message_code_t { - RMC_ACCESS_REQUEST = 1, - RMC_ACCESS_ACCEPT = 2, - RMC_ACCESS_REJECT = 3, - RMC_ACCOUNTING_REQUEST = 4, - RMC_ACCOUNTING_RESPONSE = 5, - RMC_ACCESS_CHALLENGE = 11, -}; - -/** - * Enum names for radius_attribute_type_t. - */ -extern enum_name_t *radius_message_code_names; - -/** - * RADIUS Attribute Types. - */ -enum radius_attribute_type_t { - RAT_USER_NAME = 1, - RAT_USER_PASSWORD = 2, - RAT_CHAP_PASSWORD = 3, - RAT_NAS_IP_ADDRESS = 4, - RAT_NAS_PORT = 5, - RAT_SERVICE_TYPE = 6, - RAT_FRAMED_PROTOCOL = 7, - RAT_FRAMED_IP_ADDRESS = 8, - RAT_FRAMED_IP_NETMASK = 9, - RAT_FRAMED_ROUTING = 10, - RAT_FILTER_ID = 11, - RAT_FRAMED_MTU = 12, - RAT_FRAMED_COMPRESSION = 13, - RAT_LOGIN_IP_HOST = 14, - RAT_LOGIN_SERVICE = 15, - RAT_LOGIN_TCP_PORT = 16, - RAT_REPLY_MESSAGE = 18, - RAT_CALLBACK_NUMBER = 19, - RAT_CALLBACK_ID = 20, - RAT_FRAMED_ROUTE = 22, - RAT_FRAMED_IPX_NETWORK = 23, - RAT_STATE = 24, - RAT_CLASS = 25, - RAT_VENDOR_SPECIFIC = 26, - RAT_SESSION_TIMEOUT = 27, - RAT_IDLE_TIMEOUT = 28, - RAT_TERMINATION_ACTION = 29, - RAT_CALLED_STATION_ID = 30, - RAT_CALLING_STATION_ID = 31, - RAT_NAS_IDENTIFIER = 32, - RAT_PROXY_STATE = 33, - RAT_LOGIN_LAT_SERVICE = 34, - RAT_LOGIN_LAT_NODE = 35, - RAT_LOGIN_LAT_GROUP = 36, - RAT_FRAMED_APPLETALK_LINK = 37, - RAT_FRAMED_APPLETALK_NETWORK = 38, - RAT_FRAMED_APPLETALK_ZONE = 39, - RAT_ACCT_STATUS_TYPE = 40, - RAT_ACCT_DELAY_TIME = 41, - RAT_ACCT_INPUT_OCTETS = 42, - RAT_ACCT_OUTPUT_OCTETS = 43, - RAT_ACCT_SESSION_ID = 44, - RAT_ACCT_AUTHENTIC = 45, - RAT_ACCT_SESSION_TIME = 46, - RAT_ACCT_INPUT_PACKETS = 47, - RAT_ACCT_OUTPUT_PACKETS = 48, - RAT_ACCT_TERMINATE_CAUSE = 49, - RAT_ACCT_MULTI_SESSION_ID = 50, - RAT_ACCT_LINK_COUNT = 51, - RAT_ACCT_INPUT_GIGAWORDS = 52, - RAT_ACCT_OUTPUT_GIGAWORDS = 53, - RAT_EVENT_TIMESTAMP = 55, - RAT_EGRESS_VLANID = 56, - RAT_INGRESS_FILTERS = 57, - RAT_EGRESS_VLAN_NAME = 58, - RAT_USER_PRIORITY_TABLE = 59, - RAT_CHAP_CHALLENGE = 60, - RAT_NAS_PORT_TYPE = 61, - RAT_PORT_LIMIT = 62, - RAT_LOGIN_LAT_PORT = 63, - RAT_TUNNEL_TYPE = 64, - RAT_TUNNEL_MEDIUM_TYPE = 65, - RAT_TUNNEL_CLIENT_ENDPOINT = 66, - RAT_TUNNEL_SERVER_ENDPOINT = 67, - RAT_ACCT_TUNNEL_CONNECTION = 68, - RAT_TUNNEL_PASSWORD = 69, - RAT_ARAP_PASSWORD = 70, - RAT_ARAP_FEATURES = 71, - RAT_ARAP_ZONE_ACCESS = 72, - RAT_ARAP_SECURITY = 73, - RAT_ARAP_SECURITY_DATA = 74, - RAT_PASSWORD_RETRY = 75, - RAT_PROMPT = 76, - RAT_CONNECT_INFO = 77, - RAT_CONFIGURATION_TOKEN = 78, - RAT_EAP_MESSAGE = 79, - RAT_MESSAGE_AUTHENTICATOR = 80, - RAT_TUNNEL_PRIVATE_GROUP_ID = 81, - RAT_TUNNEL_ASSIGNMENT_ID = 82, - RAT_TUNNEL_PREFERENCE = 83, - RAT_ARAP_CHALLENGE_RESPONSE = 84, - RAT_ACCT_INTERIM_INTERVAL = 85, - RAT_ACCT_TUNNEL_PACKETS_LOST = 86, - RAT_NAS_PORT_ID = 87, - RAT_FRAMED_POOL = 88, - RAT_CUI = 89, - RAT_TUNNEL_CLIENT_AUTH_ID = 90, - RAT_TUNNEL_SERVER_AUTH_ID = 91, - RAT_NAS_FILTER_RULE = 92, - RAT_UNASSIGNED = 93, - RAT_ORIGINATING_LINE_INFO = 94, - RAT_NAS_IPV6_ADDRESS = 95, - RAT_FRAMED_INTERFACE_ID = 96, - RAT_FRAMED_IPV6_PREFIX = 97, - RAT_LOGIN_IPV6_HOST = 98, - RAT_FRAMED_IPV6_ROUTE = 99, - RAT_FRAMED_IPV6_POOL = 100, - RAT_ERROR_CAUSE = 101, - RAT_EAP_KEY_NAME = 102, - RAT_DIGEST_RESPONSE = 103, - RAT_DIGEST_REALM = 104, - RAT_DIGEST_NONCE = 105, - RAT_DIGEST_RESPONSE_AUTH = 106, - RAT_DIGEST_NEXTNONCE = 107, - RAT_DIGEST_METHOD = 108, - RAT_DIGEST_URI = 109, - RAT_DIGEST_QOP = 110, - RAT_DIGEST_ALGORITHM = 111, - RAT_DIGEST_ENTITY_BODY_HASH = 112, - RAT_DIGEST_CNONCE = 113, - RAT_DIGEST_NONCE_COUNT = 114, - RAT_DIGEST_USERNAME = 115, - RAT_DIGEST_OPAQUE = 116, - RAT_DIGEST_AUTH_PARAM = 117, - RAT_DIGEST_AKA_AUTS = 118, - RAT_DIGEST_DOMAIN = 119, - RAT_DIGEST_STALE = 120, - RAT_DIGEST_HA1 = 121, - RAT_SIP_AOR = 122, - RAT_DELEGATED_IPV6_PREFIX = 123, - RAT_MIP6_FEATURE_VECTOR = 124, - RAT_MIP6_HOME_LINK_PREFIX = 125, -}; - -/** - * Enum names for radius_attribute_type_t. - */ -extern enum_name_t *radius_attribute_type_names; - -/** - * A RADIUS message, contains attributes. - */ -struct radius_message_t { - - /** - * Create an enumerator over contained RADIUS attributes. - * - * @return enumerator over (int type, chunk_t data) - */ - enumerator_t* (*create_enumerator)(radius_message_t *this); - - /** - * Add a RADIUS attribute to the message. - * - * @param type type of attribute to add - * @param attribute data, gets cloned - */ - void (*add)(radius_message_t *this, radius_attribute_type_t type, - chunk_t data); - - /** - * Get the message type (code). - * - * @return message code - */ - radius_message_code_t (*get_code)(radius_message_t *this); - - /** - * Get the message identifier. - * - * @return message identifier - */ - u_int8_t (*get_identifier)(radius_message_t *this); - - /** - * Set the message identifier. - * - * @param identifier message identifier - */ - void (*set_identifier)(radius_message_t *this, u_int8_t identifier); - - /** - * Get the 16 byte authenticator. - * - * @return pointer to the Authenticator field - */ - u_int8_t* (*get_authenticator)(radius_message_t *this); - - /** - * Get the RADIUS message in its encoded form. - * - * @return chunk pointing to internal RADIUS message. - */ - chunk_t (*get_encoding)(radius_message_t *this); - - /** - * Calculate and add the Message-Authenticator attribute to the message. - * - * @param rng RNG to create Request-Authenticator - * @param signer HMAC-MD5 signer with secret set - */ - void (*sign)(radius_message_t *this, rng_t *rng, signer_t *signer); - - /** - * Verify the integrity of a received RADIUS response. - * - * @param req_auth 16 byte Authenticator of the corresponding request - * @param secret shared RADIUS secret - * @param hasher hasher to verify Response-Authenticator - * @param signer signer to verify Message-Authenticator attribute - */ - bool (*verify)(radius_message_t *this, u_int8_t *req_auth, chunk_t secret, - hasher_t *hasher, signer_t *signer); - - /** - * Destroy the message. - */ - void (*destroy)(radius_message_t *this); -}; - -/** - * Create an empty RADIUS request message (RMT_ACCESS_REQUEST). - * - * @return radius_message_t object - */ -radius_message_t *radius_message_create_request(); - -/** - * Parse and verify a recevied RADIUS response. - * - * @param data received message data - * @return radius_message_t object, NULL if length invalid - */ -radius_message_t *radius_message_parse_response(chunk_t data); - -#endif /** RADIUS_MESSAGE_H_ @}*/ diff --git a/src/libcharon/plugins/eap_radius/radius_server.c b/src/libcharon/plugins/eap_radius/radius_server.c deleted file mode 100644 index 3baf39807..000000000 --- a/src/libcharon/plugins/eap_radius/radius_server.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2010 Martin Willi - * Copyright (C) 2010 revosec AG - * - * 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. - */ - -#include "radius_server.h" - -#include <threading/mutex.h> -#include <threading/condvar.h> -#include <utils/linked_list.h> - -typedef struct private_radius_server_t private_radius_server_t; - -/** - * Private data of an radius_server_t object. - */ -struct private_radius_server_t { - - /** - * Public radius_server_t interface. - */ - radius_server_t public; - - /** - * list of radius sockets, as radius_socket_t - */ - linked_list_t *sockets; - - /** - * Total number of sockets, in list + currently in use - */ - int socket_count; - - /** - * mutex to lock sockets list - */ - mutex_t *mutex; - - /** - * condvar to wait for sockets - */ - condvar_t *condvar; - - /** - * Server name - */ - char *name; - - /** - * NAS-Identifier - */ - chunk_t nas_identifier; - - /** - * Preference boost for this server - */ - int preference; - - /** - * Is the server currently reachable - */ - bool reachable; - - /** - * Retry counter for unreachable servers - */ - int retry; - - /** - * reference count - */ - refcount_t ref; -}; - -METHOD(radius_server_t, get_socket, radius_socket_t*, - private_radius_server_t *this) -{ - radius_socket_t *skt; - - this->mutex->lock(this->mutex); - while (this->sockets->remove_first(this->sockets, (void**)&skt) != SUCCESS) - { - this->condvar->wait(this->condvar, this->mutex); - } - this->mutex->unlock(this->mutex); - return skt; -} - -METHOD(radius_server_t, put_socket, void, - private_radius_server_t *this, radius_socket_t *skt, bool result) -{ - this->mutex->lock(this->mutex); - this->sockets->insert_last(this->sockets, skt); - this->mutex->unlock(this->mutex); - this->condvar->signal(this->condvar); - this->reachable = result; -} - -METHOD(radius_server_t, get_nas_identifier, chunk_t, - private_radius_server_t *this) -{ - return this->nas_identifier; -} - -METHOD(radius_server_t, get_preference, int, - private_radius_server_t *this) -{ - int pref; - - if (this->socket_count == 0) - { /* don't have sockets, huh? */ - return -1; - } - /* calculate preference between 0-100 + boost */ - pref = this->preference; - pref += this->sockets->get_count(this->sockets) * 100 / this->socket_count; - if (this->reachable) - { /* reachable server get a boost: pref = 110-210 + boost */ - return pref + 110; - } - /* Not reachable. Increase preference randomly to let it retry from - * time to time, especially if other servers have high load. */ - this->retry++; - if (this->retry % 128 == 0) - { /* every 64th request gets 210, same as unloaded reachable */ - return pref + 110; - } - if (this->retry % 32 == 0) - { /* every 32th request gets 190, wins against average loaded */ - return pref + 90; - } - if (this->retry % 8 == 0) - { /* every 8th request gets 110, same as server under load */ - return pref + 10; - } - /* other get ~100, less than fully loaded */ - return pref; -} - -METHOD(radius_server_t, get_name, char*, - private_radius_server_t *this) -{ - return this->name; -} - -METHOD(radius_server_t, get_ref, radius_server_t*, - private_radius_server_t *this) -{ - ref_get(&this->ref); - return &this->public; -} - - -METHOD(radius_server_t, destroy, void, - private_radius_server_t *this) -{ - if (ref_put(&this->ref)) - { - this->mutex->destroy(this->mutex); - this->condvar->destroy(this->condvar); - this->sockets->destroy_offset(this->sockets, - offsetof(radius_socket_t, destroy)); - free(this); - } -} - -/** - * See header - */ -radius_server_t *radius_server_create(char *name, char *address, u_int16_t port, - char *nas_identifier, char *secret, int sockets, int preference) -{ - private_radius_server_t *this; - radius_socket_t *socket; - - INIT(this, - .public = { - .get_socket = _get_socket, - .put_socket = _put_socket, - .get_nas_identifier = _get_nas_identifier, - .get_preference = _get_preference, - .get_name = _get_name, - .get_ref = _get_ref, - .destroy = _destroy, - }, - .reachable = TRUE, - .nas_identifier = chunk_create(nas_identifier, strlen(nas_identifier)), - .socket_count = sockets, - .sockets = linked_list_create(), - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), - .name = name, - .preference = preference, - .ref = 1, - ); - - while (sockets--) - { - socket = radius_socket_create(address, port, - chunk_create(secret, strlen(secret))); - if (!socket) - { - destroy(this); - return NULL; - } - this->sockets->insert_last(this->sockets, socket); - } - return &this->public; -} diff --git a/src/libcharon/plugins/eap_radius/radius_server.h b/src/libcharon/plugins/eap_radius/radius_server.h deleted file mode 100644 index c59361c49..000000000 --- a/src/libcharon/plugins/eap_radius/radius_server.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2010 Martin Willi - * Copyright (C) 2010 revosec AG - * - * 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 radius_server radius_server - * @{ @ingroup eap_radius - */ - -#ifndef RADIUS_SERVER_H_ -#define RADIUS_SERVER_H_ - -typedef struct radius_server_t radius_server_t; - -#include "radius_socket.h" - -/** - * RADIUS server configuration. - */ -struct radius_server_t { - - /** - * Get a RADIUS socket from the pool to communicate with this server. - * - * @return RADIUS socket - */ - radius_socket_t* (*get_socket)(radius_server_t *this); - - /** - * Release a socket to the pool after use. - * - * @param skt RADIUS socket to release - * @param result result of the socket use, TRUE for success - */ - void (*put_socket)(radius_server_t *this, radius_socket_t *skt, bool result); - - /** - * Get the NAS-Identifier to use with this server. - * - * @return NAS-Identifier, internal data - */ - chunk_t (*get_nas_identifier)(radius_server_t *this); - - /** - * Get the preference of this server. - * - * Based on the available sockets and the server reachability a preference - * value is calculated: better servers return a higher value. - */ - int (*get_preference)(radius_server_t *this); - - /** - * Get the name of the RADIUS server. - * - * @return server name - */ - char* (*get_name)(radius_server_t *this); - - /** - * Increase reference count of this server. - * - * @return this - */ - radius_server_t* (*get_ref)(radius_server_t *this); - - /** - * Destroy a radius_server_t. - */ - void (*destroy)(radius_server_t *this); -}; - -/** - * Create a radius_server instance. - * - * @param name server name - * @param address server address - * @param port server port - * @param nas_identifier NAS-Identifier to use with this server - * @param secret secret to use with this server - * @param sockets number of sockets to create in pool - * @param preference preference boost for this server - */ -radius_server_t *radius_server_create(char *name, char *address, u_int16_t port, - char *nas_identifier, char *secret, int sockets, int preference); - -#endif /** RADIUS_SERVER_H_ @}*/ diff --git a/src/libcharon/plugins/eap_radius/radius_socket.c b/src/libcharon/plugins/eap_radius/radius_socket.c deleted file mode 100644 index b3229c288..000000000 --- a/src/libcharon/plugins/eap_radius/radius_socket.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2010 Martin Willi - * Copyright (C) 2010 revosec AG - * - * 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. - */ - -#include "radius_socket.h" - -#include <errno.h> -#include <unistd.h> - -#include <debug.h> - -/** - * Vendor-Id of Microsoft specific attributes - */ -#define VENDOR_ID_MICROSOFT 311 - -/** - * Microsoft specific vendor attributes - */ -#define MS_MPPE_SEND_KEY 16 -#define MS_MPPE_RECV_KEY 17 - -typedef struct private_radius_socket_t private_radius_socket_t; - -/** - * Private data of an radius_socket_t object. - */ -struct private_radius_socket_t { - - /** - * Public radius_socket_t interface. - */ - radius_socket_t public; - - /** - * socket file descriptor - */ - int fd; - - /** - * Server address - */ - char *address; - - /** - * Server port - */ - u_int16_t port; - - /** - * current RADIUS identifier - */ - u_int8_t identifier; - - /** - * hasher to use for response verification - */ - hasher_t *hasher; - - /** - * HMAC-MD5 signer to build Message-Authenticator attribute - */ - signer_t *signer; - - /** - * random number generator for RADIUS request authenticator - */ - rng_t *rng; - - /** - * RADIUS secret - */ - chunk_t secret; -}; - -/** - * Check or establish RADIUS connection - */ -static bool check_connection(private_radius_socket_t *this) -{ - if (this->fd == -1) - { - host_t *server; - - server = host_create_from_dns(this->address, AF_UNSPEC, this->port); - if (!server) - { - DBG1(DBG_CFG, "resolving RADIUS server address '%s' failed", - this->address); - return FALSE; - } - this->fd = socket(server->get_family(server), SOCK_DGRAM, IPPROTO_UDP); - if (this->fd == -1) - { - DBG1(DBG_CFG, "opening RADIUS socket for %#H failed: %s", - server, strerror(errno)); - server->destroy(server); - return FALSE; - } - if (connect(this->fd, server->get_sockaddr(server), - *server->get_sockaddr_len(server)) < 0) - { - DBG1(DBG_CFG, "connecting RADIUS socket to %#H failed: %s", - server, strerror(errno)); - server->destroy(server); - close(this->fd); - this->fd = -1; - return FALSE; - } - server->destroy(server); - } - return TRUE; -} - -METHOD(radius_socket_t, request, radius_message_t*, - private_radius_socket_t *this, radius_message_t *request) -{ - chunk_t data; - int i; - - /* set Message Identifier */ - request->set_identifier(request, this->identifier++); - /* sign the request */ - request->sign(request, this->rng, this->signer); - - if (!check_connection(this)) - { - return NULL; - } - - data = request->get_encoding(request); - /* timeout after 2, 3, 4, 5 seconds */ - for (i = 2; i <= 5; i++) - { - radius_message_t *response; - bool retransmit = FALSE; - struct timeval tv; - char buf[4096]; - fd_set fds; - int res; - - if (send(this->fd, data.ptr, data.len, 0) != data.len) - { - DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno)); - return NULL; - } - tv.tv_sec = i; - tv.tv_usec = 0; - - while (TRUE) - { - FD_ZERO(&fds); - FD_SET(this->fd, &fds); - res = select(this->fd + 1, &fds, NULL, NULL, &tv); - /* TODO: updated tv to time not waited. Linux does this for us. */ - if (res < 0) - { /* failed */ - DBG1(DBG_CFG, "waiting for RADIUS message failed: %s", - strerror(errno)); - break; - } - if (res == 0) - { /* timeout */ - DBG1(DBG_CFG, "retransmitting RADIUS message"); - retransmit = TRUE; - break; - } - res = recv(this->fd, buf, sizeof(buf), MSG_DONTWAIT); - if (res <= 0) - { - DBG1(DBG_CFG, "receiving RADIUS message failed: %s", - strerror(errno)); - break; - } - response = radius_message_parse_response(chunk_create(buf, res)); - if (response) - { - if (response->verify(response, - request->get_authenticator(request), this->secret, - this->hasher, this->signer)) - { - return response; - } - response->destroy(response); - } - DBG1(DBG_CFG, "received invalid RADIUS message, ignored"); - } - if (!retransmit) - { - break; - } - } - DBG1(DBG_CFG, "RADIUS server is not responding"); - return NULL; -} - -/** - * Decrypt a MS-MPPE-Send/Recv-Key - */ -static chunk_t decrypt_mppe_key(private_radius_socket_t *this, u_int16_t salt, - chunk_t C, radius_message_t *request) -{ - chunk_t A, R, P, seed; - u_char *c, *p; - - /** - * From RFC2548 (encryption): - * b(1) = MD5(S + R + A) c(1) = p(1) xor b(1) C = c(1) - * b(2) = MD5(S + c(1)) c(2) = p(2) xor b(2) C = C + c(2) - * . . . - * b(i) = MD5(S + c(i-1)) c(i) = p(i) xor b(i) C = C + c(i) - */ - - if (C.len % HASH_SIZE_MD5 || C.len < HASH_SIZE_MD5) - { - return chunk_empty; - } - - A = chunk_create((u_char*)&salt, sizeof(salt)); - R = chunk_create(request->get_authenticator(request), HASH_SIZE_MD5); - P = chunk_alloca(C.len); - p = P.ptr; - c = C.ptr; - - seed = chunk_cata("cc", R, A); - - while (c < C.ptr + C.len) - { - /* b(i) = MD5(S + c(i-1)) */ - this->hasher->get_hash(this->hasher, this->secret, NULL); - this->hasher->get_hash(this->hasher, seed, p); - - /* p(i) = b(i) xor c(1) */ - memxor(p, c, HASH_SIZE_MD5); - - /* prepare next round */ - seed = chunk_create(c, HASH_SIZE_MD5); - c += HASH_SIZE_MD5; - p += HASH_SIZE_MD5; - } - - /* remove truncation, first byte is key length */ - if (*P.ptr >= P.len) - { /* decryption failed? */ - return chunk_empty; - } - return chunk_clone(chunk_create(P.ptr + 1, *P.ptr)); -} - -METHOD(radius_socket_t, decrypt_msk, chunk_t, - private_radius_socket_t *this, radius_message_t *request, - radius_message_t *response) -{ - struct { - u_int32_t id; - u_int8_t type; - u_int8_t length; - u_int16_t salt; - u_int8_t key[]; - } __attribute__((packed)) *mppe_key; - enumerator_t *enumerator; - chunk_t data, send = chunk_empty, recv = chunk_empty; - int type; - - enumerator = response->create_enumerator(response); - while (enumerator->enumerate(enumerator, &type, &data)) - { - if (type == RAT_VENDOR_SPECIFIC && - data.len > sizeof(*mppe_key)) - { - mppe_key = (void*)data.ptr; - if (ntohl(mppe_key->id) == VENDOR_ID_MICROSOFT && - mppe_key->length == data.len - sizeof(mppe_key->id)) - { - data = chunk_create(mppe_key->key, data.len - sizeof(*mppe_key)); - if (mppe_key->type == MS_MPPE_SEND_KEY) - { - send = decrypt_mppe_key(this, mppe_key->salt, data, request); - } - if (mppe_key->type == MS_MPPE_RECV_KEY) - { - recv = decrypt_mppe_key(this, mppe_key->salt, data, request); - } - } - } - } - enumerator->destroy(enumerator); - if (send.ptr && recv.ptr) - { - return chunk_cat("mm", recv, send); - } - chunk_clear(&send); - chunk_clear(&recv); - return chunk_empty; -} - -METHOD(radius_socket_t, destroy, void, - private_radius_socket_t *this) -{ - DESTROY_IF(this->hasher); - DESTROY_IF(this->signer); - DESTROY_IF(this->rng); - if (this->fd != -1) - { - close(this->fd); - } - free(this); -} - -/** - * See header - */ -radius_socket_t *radius_socket_create(char *address, u_int16_t port, - chunk_t secret) -{ - private_radius_socket_t *this; - - INIT(this, - .public = { - .request = _request, - .decrypt_msk = _decrypt_msk, - .destroy = _destroy, - }, - .address = address, - .port = port, - .fd = -1, - ); - - this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5); - this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128); - this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); - if (!this->hasher || !this->signer || !this->rng) - { - DBG1(DBG_CFG, "RADIUS initialization failed, HMAC/MD5/RNG required"); - destroy(this); - return NULL; - } - this->secret = secret; - this->signer->set_key(this->signer, secret); - /* we use a random identifier, helps if we restart often */ - this->identifier = random(); - - return &this->public; -} diff --git a/src/libcharon/plugins/eap_radius/radius_socket.h b/src/libcharon/plugins/eap_radius/radius_socket.h deleted file mode 100644 index 2875008eb..000000000 --- a/src/libcharon/plugins/eap_radius/radius_socket.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2010 Martin Willi - * Copyright (C) 2010 revosec AG - * - * 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 radius_socket radius_socket - * @{ @ingroup eap_radius - */ - -#ifndef RADIUS_SOCKET_H_ -#define RADIUS_SOCKET_H_ - -typedef struct radius_socket_t radius_socket_t; - -#include "radius_message.h" - -#include <utils/host.h> - -/** - * RADIUS socket to a server. - */ -struct radius_socket_t { - - /** - * Send a RADIUS request, wait for response. - * - * The socket fills in RADIUS Message identifier, builds a - * Request-Authenticator and calculates the Message-Authenticator - * attribute. - * The received response gets verified using the Response-Identifier - * and the Message-Authenticator attribute. - * - * @param request request message - * @return response message, NULL if timed out - */ - radius_message_t* (*request)(radius_socket_t *this, - radius_message_t *request); - - /** - * Decrypt the MSK encoded in a messages MS-MPPE-Send/Recv-Key. - * - * @param request associated RADIUS request message - * @param response RADIUS response message containing attributes - * @return allocated MSK, empty chunk if none found - */ - chunk_t (*decrypt_msk)(radius_socket_t *this, radius_message_t *request, - radius_message_t *response); - - /** - * Destroy a radius_socket_t. - */ - void (*destroy)(radius_socket_t *this); -}; - -/** - * Create a radius_socket instance. - * - * @param address server name - * @param port server port - * @param secret RADIUS secret - */ -radius_socket_t *radius_socket_create(char *address, u_int16_t port, - chunk_t secret); - -#endif /** RADIUS_SOCKET_H_ @}*/ diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in index b9ab6656b..d06929522 100644 --- a/src/libcharon/plugins/eap_sim/Makefile.in +++ b/src/libcharon/plugins/eap_sim/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/eap_sim/eap_sim_peer.c b/src/libcharon/plugins/eap_sim/eap_sim_peer.c index 083bf73a3..1d1ab99e0 100644 --- a/src/libcharon/plugins/eap_sim/eap_sim_peer.c +++ b/src/libcharon/plugins/eap_sim/eap_sim_peer.c @@ -18,6 +18,7 @@ #include <daemon.h> #include <simaka_message.h> +#include <simaka_manager.h> /* number of tries we do authenticate */ #define MAX_TRIES 3 @@ -41,6 +42,11 @@ struct private_eap_sim_peer_t { eap_sim_peer_t public; /** + * SIM backend manager + */ + simaka_manager_t *mgr; + + /** * permanent ID of peer */ identification_t *permanent; @@ -116,7 +122,7 @@ static eap_payload_t* create_client_error(private_eap_sim_peer_t *this, encoded = htons(code); message->add_attribute(message, AT_CLIENT_ERROR_CODE, chunk_create((char*)&encoded, sizeof(encoded))); - out = message->generate(message, chunk_empty); + out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); return out; } @@ -188,7 +194,7 @@ static status_t process_start(private_eap_sim_peer_t *this, switch (id_req) { case AT_ANY_ID_REQ: - this->reauth = charon->sim->card_get_reauth(charon->sim, + this->reauth = this->mgr->card_get_reauth(this->mgr, this->permanent, this->mk, &this->counter); if (this->reauth) { @@ -197,8 +203,8 @@ static status_t process_start(private_eap_sim_peer_t *this, } /* FALL */ case AT_FULLAUTH_ID_REQ: - this->pseudonym = charon->sim->card_get_pseudonym(charon->sim, - this->permanent); + this->pseudonym = this->mgr->card_get_pseudonym(this->mgr, + this->permanent); if (this->pseudonym) { id = this->pseudonym->get_encoding(this->pseudonym); @@ -228,7 +234,7 @@ static status_t process_start(private_eap_sim_peer_t *this, { message->add_attribute(message, AT_IDENTITY, id); } - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); return NEED_MORE; @@ -287,8 +293,8 @@ static status_t process_challenge(private_eap_sim_peer_t *this, sreses = sres = chunk_alloca(rands.len / 4); while (rands.len >= SIM_RAND_LEN) { - if (!charon->sim->card_get_triplet(charon->sim, this->permanent, - rands.ptr, sres.ptr, kc.ptr)) + if (!this->mgr->card_get_triplet(this->mgr, this->permanent, + rands.ptr, sres.ptr, kc.ptr)) { DBG1(DBG_IKE, "unable to get EAP-SIM triplet"); *out = create_client_error(this, SIM_UNABLE_TO_PROCESS); @@ -328,13 +334,13 @@ static status_t process_challenge(private_eap_sim_peer_t *this, case AT_NEXT_REAUTH_ID: this->counter = 0; id = identification_create_from_data(data); - charon->sim->card_set_reauth(charon->sim, this->permanent, id, - this->mk, this->counter); + this->mgr->card_set_reauth(this->mgr, this->permanent, id, + this->mk, this->counter); id->destroy(id); break; case AT_NEXT_PSEUDONYM: id = identification_create_from_data(data); - charon->sim->card_set_pseudonym(charon->sim, this->permanent, id); + this->mgr->card_set_pseudonym(this->mgr, this->permanent, id); id->destroy(id); break; default: @@ -346,7 +352,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this, /* build response with AT_MAC, built over "EAP packet | n*SRES" */ message = simaka_message_create(FALSE, this->identifier, EAP_SIM, SIM_CHALLENGE, this->crypto); - *out = message->generate(message, sreses); + *out = eap_payload_create_data_own(message->generate(message, sreses)); message->destroy(message); return NEED_MORE; } @@ -443,13 +449,13 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this, identification_t *reauth; reauth = identification_create_from_data(data); - charon->sim->card_set_reauth(charon->sim, this->permanent, reauth, - this->mk, this->counter); + this->mgr->card_set_reauth(this->mgr, this->permanent, reauth, + this->mk, this->counter); reauth->destroy(reauth); } } message->add_attribute(message, AT_COUNTER, counter); - *out = message->generate(message, nonce); + *out = eap_payload_create_data_own(message->generate(message, nonce)); message->destroy(message); return NEED_MORE; } @@ -500,7 +506,8 @@ static status_t process_notification(private_eap_sim_peer_t *this, { /* empty notification reply */ message = simaka_message_create(FALSE, this->identifier, EAP_SIM, SIM_NOTIFICATION, this->crypto); - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, + chunk_empty)); message->destroy(message); } else @@ -519,7 +526,7 @@ METHOD(eap_method_t, process, status_t, /* store received EAP message identifier */ this->identifier = in->get_identifier(in); - message = simaka_message_create_from_payload(in, this->crypto); + message = simaka_message_create_from_payload(in->get_data(in), this->crypto); if (!message) { *out = create_client_error(this, SIM_UNABLE_TO_PROCESS); @@ -633,7 +640,8 @@ eap_sim_peer_t *eap_sim_peer_create(identification_t *server, .destroy = _destroy, }, }, - .crypto = simaka_crypto_create(), + .crypto = simaka_crypto_create(EAP_SIM), + .mgr = lib->get(lib, "sim-manager"), ); if (!this->crypto) diff --git a/src/libcharon/plugins/eap_sim/eap_sim_peer.h b/src/libcharon/plugins/eap_sim/eap_sim_peer.h index 89f81301e..ba72ce484 100644 --- a/src/libcharon/plugins/eap_sim/eap_sim_peer.h +++ b/src/libcharon/plugins/eap_sim/eap_sim_peer.h @@ -27,9 +27,6 @@ typedef struct eap_sim_peer_t eap_sim_peer_t; /** * EAP-SIM peer implementation. - * - * This EAP-SIM module uses sim_card_t implementations for triplet calculation, - * found via the eap_sim_manager_t. */ struct eap_sim_peer_t { diff --git a/src/libcharon/plugins/eap_sim/eap_sim_plugin.c b/src/libcharon/plugins/eap_sim/eap_sim_plugin.c index b15292544..5bc0af6bd 100644 --- a/src/libcharon/plugins/eap_sim/eap_sim_plugin.c +++ b/src/libcharon/plugins/eap_sim/eap_sim_plugin.c @@ -19,20 +19,61 @@ #include "eap_sim_peer.h" #include <daemon.h> +#include <simaka_manager.h> + +typedef struct private_eap_sim_plugin_t private_eap_sim_plugin_t; + +/** + * Private data of an eap_sim_plugin_t object. + */ +struct private_eap_sim_plugin_t { + + /** + * Public interface. + */ + eap_sim_plugin_t public; + + /** + * EAP-SIM backend manager + */ + simaka_manager_t *mgr; +}; METHOD(plugin_t, get_name, char*, - eap_sim_plugin_t *this) + private_eap_sim_plugin_t *this) { return "eap-sim"; } +METHOD(plugin_t, get_features, int, + private_eap_sim_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_PROVIDE(CUSTOM, "sim-manager"), + PLUGIN_CALLBACK(eap_method_register, eap_sim_server_create), + PLUGIN_PROVIDE(EAP_SERVER, EAP_SIM), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(PRF, PRF_FIPS_SHA1_160), + PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA1_128), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_CALLBACK(eap_method_register, eap_sim_peer_create), + PLUGIN_PROVIDE(EAP_PEER, EAP_SIM), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(PRF, PRF_FIPS_SHA1_160), + PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA1_128), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, - eap_sim_plugin_t *this) + private_eap_sim_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_sim_server_create); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_sim_peer_create); + lib->set(lib, "sim-manager", NULL); + this->mgr->destroy(this->mgr); free(this); } @@ -41,21 +82,20 @@ METHOD(plugin_t, destroy, void, */ plugin_t *eap_sim_plugin_create() { - eap_sim_plugin_t *this; + private_eap_sim_plugin_t *this; INIT(this, - .plugin = { - .get_name = _get_name, - .reload = (void*)return_false, - .destroy = _destroy, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, }, + .mgr = simaka_manager_create(), ); + lib->set(lib, "sim-manager", this->mgr); - charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_SERVER, - (eap_constructor_t)eap_sim_server_create); - charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_PEER, - (eap_constructor_t)eap_sim_peer_create); - - return &this->plugin; + return &this->public.plugin; } diff --git a/src/libcharon/plugins/eap_sim/eap_sim_plugin.h b/src/libcharon/plugins/eap_sim/eap_sim_plugin.h index 4e10380c4..0c71ca548 100644 --- a/src/libcharon/plugins/eap_sim/eap_sim_plugin.h +++ b/src/libcharon/plugins/eap_sim/eap_sim_plugin.h @@ -30,6 +30,11 @@ typedef struct eap_sim_plugin_t eap_sim_plugin_t; /** * EAP-SIM plugin. + * + * This plugin implements the protocol level of EAP-SIM and uses simaka_card_t + * and simaka_provider_t backends to provide triplets. It registers a + * simaka_manager_t on the library as "sim-manager", other plugins can use it + * to provide the required backends. */ struct eap_sim_plugin_t { diff --git a/src/libcharon/plugins/eap_sim/eap_sim_server.c b/src/libcharon/plugins/eap_sim/eap_sim_server.c index d1dfde5d6..e0f7e92ad 100644 --- a/src/libcharon/plugins/eap_sim/eap_sim_server.c +++ b/src/libcharon/plugins/eap_sim/eap_sim_server.c @@ -19,6 +19,7 @@ #include <simaka_message.h> #include <simaka_crypto.h> +#include <simaka_manager.h> /* number of triplets for one authentication */ #define TRIPLET_COUNT 3 @@ -39,6 +40,11 @@ struct private_eap_sim_server_t { eap_sim_server_t public; /** + * SIM backend manager + */ + simaka_manager_t *mgr; + + /** * permanent ID of peer */ identification_t *permanent; @@ -127,7 +133,7 @@ METHOD(eap_method_t, initiate, status_t, { message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty); } - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); this->pending = SIM_START; @@ -163,14 +169,14 @@ static status_t reauthenticate(private_eap_sim_server_t *this, SIM_REAUTHENTICATION, this->crypto); message->add_attribute(message, AT_COUNTER, this->counter); message->add_attribute(message, AT_NONCE_S, this->nonce); - next = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk); + next = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk); if (next) { message->add_attribute(message, AT_NEXT_REAUTH_ID, next->get_encoding(next)); next->destroy(next); } - *out = message->generate(message, chunk_empty); + *out = eap_payload_create_data_own(message->generate(message, chunk_empty)); message->destroy(message); this->pending = SIM_REAUTHENTICATION; @@ -298,8 +304,8 @@ static status_t process_start(private_eap_sim_server_t *this, char mk[HASH_SIZE_SHA1]; u_int16_t counter; - permanent = charon->sim->provider_is_reauth(charon->sim, id, - mk, &counter); + permanent = this->mgr->provider_is_reauth(this->mgr, id, + mk, &counter); if (permanent) { this->permanent->destroy(this->permanent); @@ -315,7 +321,7 @@ static status_t process_start(private_eap_sim_server_t *this, } if (this->use_pseudonym) { - permanent = charon->sim->provider_is_pseudonym(charon->sim, id); + permanent = this->mgr->provider_is_pseudonym(this->mgr, id); if (permanent) { this->permanent->destroy(this->permanent); @@ -348,8 +354,8 @@ static status_t process_start(private_eap_sim_server_t *this, rands.len = kcs.len = sreses.len = 0; for (i = 0; i < TRIPLET_COUNT; i++) { - if (!charon->sim->provider_get_triplet(charon->sim, this->permanent, - rand.ptr, sres.ptr, kc.ptr)) + if (!this->mgr->provider_get_triplet(this->mgr, this->permanent, + rand.ptr, sres.ptr, kc.ptr)) { if (this->use_pseudonym) { @@ -386,24 +392,21 @@ static status_t process_start(private_eap_sim_server_t *this, message = simaka_message_create(TRUE, this->identifier++, EAP_SIM, SIM_CHALLENGE, this->crypto); message->add_attribute(message, AT_RAND, rands); - id = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk.ptr); + id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr); if (id) { message->add_attribute(message, AT_NEXT_REAUTH_ID, id->get_encoding(id)); id->destroy(id); } - else + id = this->mgr->provider_gen_pseudonym(this->mgr, this->permanent); + if (id) { - id = charon->sim->provider_gen_pseudonym(charon->sim, this->permanent); - if (id) - { - message->add_attribute(message, AT_NEXT_PSEUDONYM, - id->get_encoding(id)); - id->destroy(id); - } + message->add_attribute(message, AT_NEXT_PSEUDONYM, + id->get_encoding(id)); + id->destroy(id); } - *out = message->generate(message, nonce); + *out = eap_payload_create_data_own(message->generate(message, nonce)); message->destroy(message); free(mk.ptr); @@ -483,7 +486,7 @@ METHOD(eap_method_t, process, status_t, simaka_message_t *message; status_t status; - message = simaka_message_create_from_payload(in, this->crypto); + message = simaka_message_create_from_payload(in->get_data(in), this->crypto); if (!message) { return FAILED; @@ -588,7 +591,8 @@ eap_sim_server_t *eap_sim_server_create(identification_t *server, .destroy = _destroy, }, }, - .crypto = simaka_crypto_create(), + .crypto = simaka_crypto_create(EAP_SIM), + .mgr = lib->get(lib, "sim-manager"), ); if (!this->crypto) diff --git a/src/libcharon/plugins/eap_sim/eap_sim_server.h b/src/libcharon/plugins/eap_sim/eap_sim_server.h index 978e1e1e9..c0ed64ff2 100644 --- a/src/libcharon/plugins/eap_sim/eap_sim_server.h +++ b/src/libcharon/plugins/eap_sim/eap_sim_server.h @@ -27,9 +27,6 @@ typedef struct eap_sim_server_t eap_sim_server_t; /** * EAP-SIM server implementation. - * - * This EAP-SIM module uses sim_provider_t implementations for triplet - * calculation, found via the eap_sim_manager_t. */ struct eap_sim_server_t { diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.am b/src/libcharon/plugins/eap_sim_file/Makefile.am index 2b59a7c88..d76cdc5ca 100644 --- a/src/libcharon/plugins/eap_sim_file/Makefile.am +++ b/src/libcharon/plugins/eap_sim_file/Makefile.am @@ -1,6 +1,6 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\" @@ -8,6 +8,7 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-sim-file.la else plugin_LTLIBRARIES = libstrongswan-eap-sim-file.la +libstrongswan_eap_sim_file_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la endif libstrongswan_eap_sim_file_la_SOURCES = \ diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in index 5662a1c53..bebf62e5b 100644 --- a/src/libcharon/plugins/eap_sim_file/Makefile.in +++ b/src/libcharon/plugins/eap_sim_file/Makefile.in @@ -74,7 +74,8 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_eap_sim_file_la_LIBADD = +@MONOLITHIC_FALSE@libstrongswan_eap_sim_file_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libsimaka/libsimaka.la am_libstrongswan_eap_sim_file_la_OBJECTS = eap_sim_file_plugin.lo \ eap_sim_file_card.lo eap_sim_file_provider.lo \ eap_sim_file_triplets.lo @@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -204,6 +208,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -220,11 +225,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -279,11 +287,12 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\" @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-sim-file.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-sim-file.la +@MONOLITHIC_FALSE@libstrongswan_eap_sim_file_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la libstrongswan_eap_sim_file_la_SOURCES = \ eap_sim_file_plugin.h eap_sim_file_plugin.c \ eap_sim_file_card.h eap_sim_file_card.c \ diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c index 5397c418e..bd47e5085 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c @@ -35,7 +35,7 @@ struct private_eap_sim_file_card_t { eap_sim_file_triplets_t *triplets; }; -METHOD(sim_card_t, get_triplet, bool, +METHOD(simaka_card_t, get_triplet, bool, private_eap_sim_file_card_t *this, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) { @@ -66,7 +66,7 @@ METHOD(sim_card_t, get_triplet, bool, return FALSE; } -METHOD(sim_card_t, get_quintuplet, status_t, +METHOD(simaka_card_t, get_quintuplet, status_t, private_eap_sim_file_card_t *this, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len) diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h index 1a5470968..45b0e51db 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h @@ -23,7 +23,7 @@ #include "eap_sim_file_triplets.h" -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_card.h> typedef struct eap_sim_file_card_t eap_sim_file_card_t; @@ -33,9 +33,9 @@ typedef struct eap_sim_file_card_t eap_sim_file_card_t; struct eap_sim_file_card_t { /** - * Implements sim_card_t interface + * Implements simaka_card_t interface */ - sim_card_t card; + simaka_card_t card; /** * Destroy a eap_sim_file_card_t. diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c index 0ab5a1848..eae76729c 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c @@ -56,14 +56,70 @@ METHOD(plugin_t, get_name, char*, return "eap-sim-file"; } -METHOD(plugin_t, destroy, void, - private_eap_sim_file_t *this) +/** + * Load triplet file + */ +static bool load_triplets(private_eap_sim_file_t *this, + plugin_feature_t *feature, bool reg, void *data) { - charon->sim->remove_card(charon->sim, &this->card->card); - charon->sim->remove_provider(charon->sim, &this->provider->provider); + if (reg) + { + this->triplets = eap_sim_file_triplets_create(TRIPLET_FILE); + if (!this->triplets) + { + return FALSE; + } + this->provider = eap_sim_file_provider_create(this->triplets); + this->card = eap_sim_file_card_create(this->triplets); + return TRUE; + } this->card->destroy(this->card); this->provider->destroy(this->provider); this->triplets->destroy(this->triplets); + this->card = NULL; + this->provider = NULL; + this->triplets = NULL; + return TRUE; +} + +/** + * Callback providing our card to register + */ +static simaka_card_t* get_card(private_eap_sim_file_t *this) +{ + return &this->card->card; +} + +/** + * Callback providing our provider to register + */ +static simaka_provider_t* get_provider(private_eap_sim_file_t *this) +{ + return &this->provider->provider; +} + +METHOD(plugin_t, get_features, int, + private_eap_sim_file_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((void*)load_triplets, NULL), + PLUGIN_PROVIDE(CUSTOM, "eap-sim-file-triplets"), + PLUGIN_CALLBACK(simaka_manager_register, get_card), + PLUGIN_PROVIDE(CUSTOM, "sim-card"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + PLUGIN_DEPENDS(CUSTOM, "eap-sim-file-triplets"), + PLUGIN_CALLBACK(simaka_manager_register, get_provider), + PLUGIN_PROVIDE(CUSTOM, "sim-provider"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + PLUGIN_DEPENDS(CUSTOM, "eap-sim-file-triplets"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_eap_sim_file_t *this) +{ free(this); } @@ -78,25 +134,12 @@ plugin_t *eap_sim_file_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, - .triplets = eap_sim_file_triplets_create(TRIPLET_FILE), ); - this->provider = eap_sim_file_provider_create(this->triplets); - if (!this->provider) - { - this->triplets->destroy(this->triplets); - free(this); - return NULL; - } - this->card = eap_sim_file_card_create(this->triplets); - - charon->sim->add_card(charon->sim, &this->card->card); - charon->sim->add_provider(charon->sim, &this->provider->provider); - return &this->public.plugin; } diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c index 38b651404..4ca1eb93f 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c @@ -35,7 +35,7 @@ struct private_eap_sim_file_provider_t { eap_sim_file_triplets_t *triplets; }; -METHOD(sim_provider_t, get_triplet, bool, +METHOD(simaka_provider_t, get_triplet, bool, private_eap_sim_file_provider_t *this, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) { diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h index 10fda282a..577345dbf 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h @@ -23,6 +23,8 @@ #include "eap_sim_file_triplets.h" +#include <simaka_provider.h> + typedef struct eap_sim_file_provider_t eap_sim_file_provider_t; /** @@ -31,9 +33,9 @@ typedef struct eap_sim_file_provider_t eap_sim_file_provider_t; struct eap_sim_file_provider_t { /** - * Implements sim_provider_t interface. + * Implements simaka_provider_t interface. */ - sim_provider_t provider; + simaka_provider_t provider; /** * Destroy a eap_sim_file_provider_t. diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c index c693923fe..de3b69382 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c @@ -21,6 +21,7 @@ #include <daemon.h> #include <utils/linked_list.h> #include <threading/mutex.h> +#include <simaka_manager.h> typedef struct private_eap_sim_file_triplets_t private_eap_sim_file_triplets_t; @@ -149,7 +150,7 @@ static void parse_token(char *to, char *from, size_t len) /** * Read the triplets from the file */ -static void read_triplets(private_eap_sim_file_triplets_t *this, char *path) +static bool read_triplets(private_eap_sim_file_triplets_t *this, char *path) { char line[512]; FILE *file; @@ -160,7 +161,7 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path) { DBG1(DBG_CFG, "opening triplet file %s failed: %s", path, strerror(errno)); - return; + return FALSE; } /* read line by line */ @@ -226,6 +227,7 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path) DBG1(DBG_CFG, "read %d triplets from %s", this->triplets->get_count(this->triplets), path); + return TRUE; } METHOD(eap_sim_file_triplets_t, destroy, void, @@ -251,8 +253,12 @@ eap_sim_file_triplets_t *eap_sim_file_triplets_create(char *file) .triplets = linked_list_create(), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), ); - read_triplets(this, file); + if (!read_triplets(this, file)) + { + destroy(this); + return NULL; + } return &this->public; } diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h index 8f8130810..c8e9e0359 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h @@ -21,7 +21,7 @@ #ifndef EAP_SIM_FILE_TRIPLETS_H_ #define EAP_SIM_FILE_TRIPLETS_H_ -#include <sa/authenticators/eap/sim_manager.h> +#include <utils/enumerator.h> typedef struct eap_sim_file_triplets_t eap_sim_file_triplets_t; diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.am b/src/libcharon/plugins/eap_sim_pcsc/Makefile.am index 2d75fe3ad..fae6fccfc 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.am +++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.am @@ -1,18 +1,19 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic ${pcsclite_CFLAGS} +libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version +libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS} + if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la else plugin_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la +libstrongswan_eap_sim_pcsc_la_LIBADD += $(top_builddir)/src/libsimaka/libsimaka.la endif libstrongswan_eap_sim_pcsc_la_SOURCES = \ eap_sim_pcsc_plugin.h eap_sim_pcsc_plugin.c \ eap_sim_pcsc_card.h eap_sim_pcsc_card.c - -libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version -libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS} diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in index a8249a7ac..5c05b2bf1 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in +++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in @@ -34,6 +34,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libsimaka/libsimaka.la subdir = src/libcharon/plugins/eap_sim_pcsc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -75,7 +76,8 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = -libstrongswan_eap_sim_pcsc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +libstrongswan_eap_sim_pcsc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__append_1) am_libstrongswan_eap_sim_pcsc_la_OBJECTS = eap_sim_pcsc_plugin.lo \ eap_sim_pcsc_card.lo libstrongswan_eap_sim_pcsc_la_OBJECTS = \ @@ -196,6 +198,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -204,6 +209,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -220,11 +226,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -268,6 +276,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -279,17 +288,18 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic ${pcsclite_CFLAGS} +libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version +libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS} \ + $(am__append_1) @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la libstrongswan_eap_sim_pcsc_la_SOURCES = \ eap_sim_pcsc_plugin.h eap_sim_pcsc_plugin.c \ eap_sim_pcsc_card.h eap_sim_pcsc_card.c -libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version -libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS} all: all-am .SUFFIXES: diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c index d0a2718f3..c3f0f24b3 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c +++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c @@ -87,7 +87,7 @@ static bool decode_imsi_ef(unsigned char *input, int input_len, char *output) return TRUE; } -METHOD(sim_card_t, get_triplet, bool, +METHOD(simaka_card_t, get_triplet, bool, private_eap_sim_pcsc_card_t *this, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) { @@ -207,7 +207,8 @@ METHOD(sim_card_t, get_triplet, bool, if (dwRecvLength < APDU_STATUS_LEN || pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA) { - DBG1(DBG_IKE, "Select MF failed: %b", pbRecvBuffer, dwRecvLength); + DBG1(DBG_IKE, "Select MF failed: %b", pbRecvBuffer, + (u_int)dwRecvLength); continue; } @@ -223,7 +224,8 @@ METHOD(sim_card_t, get_triplet, bool, if (dwRecvLength < APDU_STATUS_LEN || pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA) { - DBG1(DBG_IKE, "Select DF GSM failed: %b", pbRecvBuffer, dwRecvLength); + DBG1(DBG_IKE, "Select DF GSM failed: %b", pbRecvBuffer, + (u_int)dwRecvLength); continue; } @@ -239,7 +241,8 @@ METHOD(sim_card_t, get_triplet, bool, if (dwRecvLength < APDU_STATUS_LEN || pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA) { - DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer, dwRecvLength); + DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer, + (u_int)dwRecvLength); continue; } @@ -255,14 +258,15 @@ METHOD(sim_card_t, get_triplet, bool, if (dwRecvLength < APDU_STATUS_LEN || pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS) { - DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer, dwRecvLength); + DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer, + (u_int)dwRecvLength); continue; } if (!decode_imsi_ef(pbRecvBuffer, dwRecvLength-APDU_STATUS_LEN, imsi)) { DBG1(DBG_IKE, "Couldn't decode IMSI EF: %b", - pbRecvBuffer, dwRecvLength); + pbRecvBuffer, (u_int)dwRecvLength); continue; } @@ -288,7 +292,7 @@ METHOD(sim_card_t, get_triplet, bool, pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA) { DBG1(DBG_IKE, "Run GSM Algorithm failed: %b", - pbRecvBuffer, dwRecvLength); + pbRecvBuffer, (u_int)dwRecvLength); continue; } @@ -305,7 +309,8 @@ METHOD(sim_card_t, get_triplet, bool, if (dwRecvLength < APDU_STATUS_LEN || pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS) { - DBG1(DBG_IKE, "Get Response failed: %b", pbRecvBuffer, dwRecvLength); + DBG1(DBG_IKE, "Get Response failed: %b", pbRecvBuffer, + (u_int)dwRecvLength); continue; } @@ -320,7 +325,7 @@ METHOD(sim_card_t, get_triplet, bool, else { DBG1(DBG_IKE, "Get Response incorrect length: %b", - pbRecvBuffer, dwRecvLength); + pbRecvBuffer, (u_int)dwRecvLength); continue; } @@ -351,7 +356,7 @@ METHOD(sim_card_t, get_triplet, bool, return found; } -METHOD(sim_card_t, get_quintuplet, status_t, +METHOD(simaka_card_t, get_quintuplet, status_t, private_eap_sim_pcsc_card_t *this, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len) diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h index e7659656b..6b69f76ec 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h +++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h @@ -20,7 +20,7 @@ #ifndef EAP_SIM_PCSC_CARD_H_ #define EAP_SIM_PCSC_CARD_H_ -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_card.h> typedef struct eap_sim_pcsc_card_t eap_sim_pcsc_card_t; @@ -30,9 +30,9 @@ typedef struct eap_sim_pcsc_card_t eap_sim_pcsc_card_t; struct eap_sim_pcsc_card_t { /** - * Implements sim_card_t interface + * Implements simaka_card_t interface */ - sim_card_t card; + simaka_card_t card; /** * Destroy a eap_sim_pcsc_card_t. diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c index 44096455e..898e85345 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c +++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c @@ -41,10 +41,29 @@ METHOD(plugin_t, get_name, char*, return "eap-sim-pcsc"; } +/** + * Callback providing our card to register + */ +static simaka_card_t* get_card(private_eap_sim_pcsc_plugin_t *this) +{ + return &this->card->card; +} + +METHOD(plugin_t, get_features, int, + private_eap_sim_pcsc_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(simaka_manager_register, get_card), + PLUGIN_PROVIDE(CUSTOM, "sim-card"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_eap_sim_pcsc_plugin_t *this) { - charon->sim->remove_card(charon->sim, &this->card->card); this->card->destroy(this->card); free(this); } @@ -60,13 +79,12 @@ plugin_t *eap_sim_pcsc_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, .card = eap_sim_pcsc_card_create(), ); - charon->sim->add_card(charon->sim, &this->card->card); return &this->public.plugin; } diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am index a158d6dbe..a8e03f650 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am +++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am @@ -1,6 +1,6 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic @@ -8,6 +8,7 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la else plugin_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la +libstrongswan_eap_simaka_pseudonym_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la endif libstrongswan_eap_simaka_pseudonym_la_SOURCES = \ diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in index 98e80bc71..0d7c32c14 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in @@ -74,7 +74,8 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_eap_simaka_pseudonym_la_LIBADD = +@MONOLITHIC_FALSE@libstrongswan_eap_simaka_pseudonym_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libsimaka/libsimaka.la am_libstrongswan_eap_simaka_pseudonym_la_OBJECTS = \ eap_simaka_pseudonym_plugin.lo eap_simaka_pseudonym_card.lo \ eap_simaka_pseudonym_provider.lo @@ -197,6 +198,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -205,6 +209,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -221,11 +226,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -269,6 +276,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -280,11 +288,12 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la +@MONOLITHIC_FALSE@libstrongswan_eap_simaka_pseudonym_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la libstrongswan_eap_simaka_pseudonym_la_SOURCES = \ eap_simaka_pseudonym_plugin.h eap_simaka_pseudonym_plugin.c \ eap_simaka_pseudonym_card.h eap_simaka_pseudonym_card.c \ diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c index 9b0f1bc71..5f78c967a 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c +++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c @@ -57,11 +57,8 @@ static bool equals(identification_t *key1, identification_t *key2) return key1->equals(key1, key2); } -/** - * Implementation of sim_card_t.get_pseudonym - */ -static identification_t *get_pseudonym(private_eap_simaka_pseudonym_card_t *this, - identification_t *id) +METHOD(simaka_card_t, get_pseudonym, identification_t*, + private_eap_simaka_pseudonym_card_t *this, identification_t *id) { identification_t *pseudonym; @@ -73,11 +70,9 @@ static identification_t *get_pseudonym(private_eap_simaka_pseudonym_card_t *this return NULL; } -/** - * Implementation of sim_card_t.set_pseudonym - */ -static void set_pseudonym(private_eap_simaka_pseudonym_card_t *this, - identification_t *id, identification_t *pseudonym) +METHOD(simaka_card_t, set_pseudonym, void, + private_eap_simaka_pseudonym_card_t *this, identification_t *id, + identification_t *pseudonym) { identification_t *permanent; @@ -92,18 +87,16 @@ static void set_pseudonym(private_eap_simaka_pseudonym_card_t *this, DESTROY_IF(pseudonym); } -/** - * Implementation of sim_card_t.get_quintuplet - */ -static status_t get_quintuplet() +METHOD(simaka_card_t, get_quintuplet, status_t, + private_eap_simaka_pseudonym_card_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], + char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len) { return NOT_SUPPORTED; } -/** - * Implementation of eap_simaka_pseudonym_card_t.destroy. - */ -static void destroy(private_eap_simaka_pseudonym_card_t *this) +METHOD(eap_simaka_pseudonym_card_t, destroy, void, + private_eap_simaka_pseudonym_card_t *this) { enumerator_t *enumerator; identification_t *id; @@ -135,19 +128,22 @@ eap_simaka_pseudonym_card_t *eap_simaka_pseudonym_card_create() { private_eap_simaka_pseudonym_card_t *this; - this = malloc_thing(private_eap_simaka_pseudonym_card_t); - - this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))get_quintuplet; - this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; - this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))get_pseudonym; - this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))set_pseudonym; - this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null; - this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))nop; - this->public.destroy = (void(*)(eap_simaka_pseudonym_card_t*))destroy; - - this->pseudonym = hashtable_create((void*)hash, (void*)equals, 0); - this->permanent = hashtable_create((void*)hash, (void*)equals, 0); + INIT(this, + .public = { + .card = { + .get_triplet = (void*)return_false, + .get_quintuplet = _get_quintuplet, + .resync = (void*)return_false, + .get_pseudonym = _get_pseudonym, + .set_pseudonym = _set_pseudonym, + .get_reauth = (void*)return_null, + .set_reauth = (void*)nop, + }, + .destroy = _destroy, + }, + .pseudonym = hashtable_create((void*)hash, (void*)equals, 0), + .permanent = hashtable_create((void*)hash, (void*)equals, 0), + ); return &this->public; } diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h index 1b5940fdc..6c73a8cb9 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h +++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h @@ -21,7 +21,7 @@ #ifndef EAP_SIMAKA_PSEUDONYM_CARD_H_ #define EAP_SIMAKA_PSEUDONYM_CARD_H_ -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_card.h> typedef struct eap_simaka_pseudonym_card_t eap_simaka_pseudonym_card_t; @@ -31,9 +31,9 @@ typedef struct eap_simaka_pseudonym_card_t eap_simaka_pseudonym_card_t; struct eap_simaka_pseudonym_card_t { /** - * Implements sim_card_t interface + * Implements simaka_card_t interface */ - sim_card_t card; + simaka_card_t card; /** * Destroy a eap_simaka_pseudonym_card_t. diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c index 06631b1c5..e2cc0e84f 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c +++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c @@ -48,13 +48,60 @@ METHOD(plugin_t, get_name, char*, return "eap-simaka-pseudonym"; } +/** + * Callback providing our card to register + */ +static simaka_card_t* get_card(private_eap_simaka_pseudonym_t *this) +{ + if (!this->card) + { + this->card = eap_simaka_pseudonym_card_create(); + } + return &this->card->card; +} + +/** + * Callback providing our provider to register + */ +static simaka_provider_t* get_provider(private_eap_simaka_pseudonym_t *this) +{ + if (!this->provider) + { + this->provider = eap_simaka_pseudonym_provider_create(); + if (!this->provider) + { + return NULL; + } + } + return &this->provider->provider; +} + +METHOD(plugin_t, get_features, int, + private_eap_simaka_pseudonym_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(simaka_manager_register, get_card), + PLUGIN_PROVIDE(CUSTOM, "aka-card"), + PLUGIN_DEPENDS(CUSTOM, "aka-manager"), + PLUGIN_PROVIDE(CUSTOM, "sim-card"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + PLUGIN_CALLBACK(simaka_manager_register, get_provider), + PLUGIN_PROVIDE(CUSTOM, "aka-provider"), + PLUGIN_DEPENDS(CUSTOM, "aka-manager"), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_PROVIDE(CUSTOM, "sim-provider"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_eap_simaka_pseudonym_t *this) { - charon->sim->remove_card(charon->sim, &this->card->card); - charon->sim->remove_provider(charon->sim, &this->provider->provider); - this->card->destroy(this->card); - this->provider->destroy(this->provider); + DESTROY_IF(this->card); + DESTROY_IF(this->provider); free(this); } @@ -69,23 +116,12 @@ plugin_t *eap_simaka_pseudonym_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, - .provider = eap_simaka_pseudonym_provider_create(), ); - if (!this->provider) - { - free(this); - return NULL; - } - this->card = eap_simaka_pseudonym_card_create(); - - charon->sim->add_card(charon->sim, &this->card->card); - charon->sim->add_provider(charon->sim, &this->provider->provider); - return &this->public.plugin; } diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c index 0613b8807..49c3ad328 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c +++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c @@ -61,11 +61,8 @@ static bool equals(identification_t *key1, identification_t *key2) return key1->equals(key1, key2); } -/** - * Implementation of sim_provider_t.is_pseudonym - */ -static identification_t* is_pseudonym( - private_eap_simaka_pseudonym_provider_t *this, identification_t *id) +METHOD(simaka_provider_t, is_pseudonym, identification_t*, + private_eap_simaka_pseudonym_provider_t *this, identification_t *id) { identification_t *permanent; @@ -91,11 +88,8 @@ static identification_t *gen_identity( return identification_create_from_string(hex); } -/** - * Implementation of sim_provider_t.get_pseudonym - */ -static identification_t* gen_pseudonym( - private_eap_simaka_pseudonym_provider_t *this, identification_t *id) +METHOD(simaka_provider_t, gen_pseudonym, identification_t*, + private_eap_simaka_pseudonym_provider_t *this, identification_t *id) { identification_t *pseudonym, *permanent; @@ -121,10 +115,8 @@ static identification_t* gen_pseudonym( return pseudonym->clone(pseudonym); } -/** - * Implementation of eap_simaka_pseudonym_provider_t.destroy. - */ -static void destroy(private_eap_simaka_pseudonym_provider_t *this) +METHOD(eap_simaka_pseudonym_provider_t, destroy, void, + private_eap_simaka_pseudonym_provider_t *this) { enumerator_t *enumerator; identification_t *id; @@ -157,18 +149,21 @@ eap_simaka_pseudonym_provider_t *eap_simaka_pseudonym_provider_create() { private_eap_simaka_pseudonym_provider_t *this; - this = malloc_thing(private_eap_simaka_pseudonym_provider_t); - - this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; - this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; - this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))is_pseudonym; - this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))gen_pseudonym; - this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null; - this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null; - this->public.destroy = (void(*)(eap_simaka_pseudonym_provider_t*))destroy; - - this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); + INIT(this, + .public = { + .provider = { + .get_triplet = (void*)return_false, + .get_quintuplet = (void*)return_false, + .resync = (void*)return_false, + .is_pseudonym = _is_pseudonym, + .gen_pseudonym = _gen_pseudonym, + .is_reauth = (void*)return_null, + .gen_reauth = (void*)return_null, + }, + .destroy = _destroy, + }, + .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK), + ); if (!this->rng) { free(this); diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h index 5d8e6d221..2dea516c3 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h +++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h @@ -21,7 +21,7 @@ #ifndef EAP_SIMAKA_PSEDUONYM_PROVIDER_H_ #define EAP_SIMAKA_PSEDUONYM_PROVIDER_H_ -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_provider.h> typedef struct eap_simaka_pseudonym_provider_t eap_simaka_pseudonym_provider_t; @@ -31,9 +31,9 @@ typedef struct eap_simaka_pseudonym_provider_t eap_simaka_pseudonym_provider_t; struct eap_simaka_pseudonym_provider_t { /** - * Implements sim_provider_t interface. + * Implements simaka_provider_t interface. */ - sim_provider_t provider; + simaka_provider_t provider; /** * Destroy a eap_simaka_pseudonym_provider_t. diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.am b/src/libcharon/plugins/eap_simaka_reauth/Makefile.am index fbcd544d3..0b35c7521 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.am +++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.am @@ -1,6 +1,6 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic @@ -8,6 +8,7 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la else plugin_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la +libstrongswan_eap_simaka_reauth_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la endif libstrongswan_eap_simaka_reauth_la_SOURCES = \ diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in index 56bc188b0..6177f3b3a 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in @@ -74,7 +74,8 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_eap_simaka_reauth_la_LIBADD = +@MONOLITHIC_FALSE@libstrongswan_eap_simaka_reauth_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libsimaka/libsimaka.la am_libstrongswan_eap_simaka_reauth_la_OBJECTS = \ eap_simaka_reauth_plugin.lo eap_simaka_reauth_card.lo \ eap_simaka_reauth_provider.lo @@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -204,6 +208,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -220,11 +225,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -279,11 +287,12 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la +@MONOLITHIC_FALSE@libstrongswan_eap_simaka_reauth_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la libstrongswan_eap_simaka_reauth_la_SOURCES = \ eap_simaka_reauth_plugin.h eap_simaka_reauth_plugin.c \ eap_simaka_reauth_card.h eap_simaka_reauth_card.c \ diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c index 14d0416d9..870d72781 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c +++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c @@ -66,12 +66,9 @@ static bool equals(identification_t *key1, identification_t *key2) return key1->equals(key1, key2); } -/** - * Implementation of sim_card_t.get_reauth - */ -static identification_t *get_reauth(private_eap_simaka_reauth_card_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter) +METHOD(simaka_card_t, get_reauth, identification_t*, + private_eap_simaka_reauth_card_t *this, identification_t *id, + char mk[HASH_SIZE_SHA1], u_int16_t *counter) { reauth_data_t *data; identification_t *reauth; @@ -90,12 +87,9 @@ static identification_t *get_reauth(private_eap_simaka_reauth_card_t *this, return reauth; } -/** - * Implementation of sim_card_t.set_reauth - */ -static void set_reauth(private_eap_simaka_reauth_card_t *this, - identification_t *id, identification_t* next, - char mk[HASH_SIZE_SHA1], u_int16_t counter) +METHOD(simaka_card_t, set_reauth, void, + private_eap_simaka_reauth_card_t *this, identification_t *id, + identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter) { reauth_data_t *data; @@ -115,18 +109,16 @@ static void set_reauth(private_eap_simaka_reauth_card_t *this, memcpy(data->mk, mk, HASH_SIZE_SHA1); } -/** - * Implementation of sim_card_t.get_quintuplet - */ -static status_t get_quintuplet() +METHOD(simaka_card_t, get_quintuplet, status_t, + private_eap_simaka_reauth_card_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], + char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len) { return NOT_SUPPORTED; } -/** - * Implementation of eap_simaka_reauth_card_t.destroy. - */ -static void destroy(private_eap_simaka_reauth_card_t *this) +METHOD(eap_simaka_reauth_card_t, destroy, void, + private_eap_simaka_reauth_card_t *this) { enumerator_t *enumerator; reauth_data_t *data; @@ -152,18 +144,21 @@ eap_simaka_reauth_card_t *eap_simaka_reauth_card_create() { private_eap_simaka_reauth_card_t *this; - this = malloc_thing(private_eap_simaka_reauth_card_t); - - this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_null; - this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))get_quintuplet; - this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; - this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))return_null; - this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop; - this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))get_reauth; - this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))set_reauth; - this->public.destroy = (void(*)(eap_simaka_reauth_card_t*))destroy; - - this->reauth = hashtable_create((void*)hash, (void*)equals, 0); + INIT(this, + .public = { + .card = { + .get_triplet = (void*)return_null, + .get_quintuplet = _get_quintuplet, + .resync = (void*)return_false, + .get_pseudonym = (void*)return_null, + .set_pseudonym = (void*)nop, + .get_reauth = _get_reauth, + .set_reauth = _set_reauth, + }, + .destroy = _destroy, + }, + .reauth = hashtable_create((void*)hash, (void*)equals, 0), + ); return &this->public; } diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h index f24dc8a15..683de7559 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h +++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h @@ -21,7 +21,7 @@ #ifndef EAP_SIMAKA_REAUTH_CARD_H_ #define EAP_SIMAKA_REAUTH_CARD_H_ -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_provider.h> typedef struct eap_simaka_reauth_card_t eap_simaka_reauth_card_t; @@ -31,9 +31,9 @@ typedef struct eap_simaka_reauth_card_t eap_simaka_reauth_card_t; struct eap_simaka_reauth_card_t { /** - * Implements sim_card_t interface + * Implements simaka_card_t interface */ - sim_card_t card; + simaka_card_t card; /** * Destroy a eap_simaka_reauth_card_t. diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c index 343e4eefb..ab3ab2f4d 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c +++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c @@ -48,13 +48,60 @@ METHOD(plugin_t, get_name, char*, return "eap-simaka-reauth"; } +/** + * Callback providing our card to register + */ +static simaka_card_t* get_card(private_eap_simaka_reauth_t *this) +{ + if (!this->card) + { + this->card = eap_simaka_reauth_card_create(); + } + return &this->card->card; +} + +/** + * Callback providing our provider to register + */ +static simaka_provider_t* get_provider(private_eap_simaka_reauth_t *this) +{ + if (!this->provider) + { + this->provider = eap_simaka_reauth_provider_create(); + if (!this->provider) + { + return NULL; + } + } + return &this->provider->provider; +} + +METHOD(plugin_t, get_features, int, + private_eap_simaka_reauth_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(simaka_manager_register, get_card), + PLUGIN_PROVIDE(CUSTOM, "aka-card"), + PLUGIN_DEPENDS(CUSTOM, "aka-manager"), + PLUGIN_PROVIDE(CUSTOM, "sim-card"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + PLUGIN_CALLBACK(simaka_manager_register, get_provider), + PLUGIN_PROVIDE(CUSTOM, "aka-provider"), + PLUGIN_DEPENDS(CUSTOM, "aka-manager"), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_PROVIDE(CUSTOM, "sim-provider"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_eap_simaka_reauth_t *this) { - charon->sim->remove_card(charon->sim, &this->card->card); - charon->sim->remove_provider(charon->sim, &this->provider->provider); - this->card->destroy(this->card); - this->provider->destroy(this->provider); + DESTROY_IF(this->card); + DESTROY_IF(this->provider); free(this); } @@ -69,23 +116,12 @@ plugin_t *eap_simaka_reauth_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, - .provider = eap_simaka_reauth_provider_create(), ); - if (!this->provider) - { - free(this); - return NULL; - } - this->card = eap_simaka_reauth_card_create(); - - charon->sim->add_card(charon->sim, &this->card->card); - charon->sim->add_provider(charon->sim, &this->provider->provider); - return &this->public.plugin; } diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c index f962b2d84..ba1a32778 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c +++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c @@ -87,12 +87,9 @@ static identification_t *gen_identity(private_eap_simaka_reauth_provider_t *this return identification_create_from_string(hex); } -/** - * Implementation of sim_provider_t.is_reauth - */ -static identification_t *is_reauth(private_eap_simaka_reauth_provider_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter) +METHOD(simaka_provider_t, is_reauth, identification_t*, + private_eap_simaka_reauth_provider_t *this, identification_t *id, + char mk[HASH_SIZE_SHA1], u_int16_t *counter) { identification_t *permanent; reauth_data_t *data; @@ -114,11 +111,9 @@ static identification_t *is_reauth(private_eap_simaka_reauth_provider_t *this, return permanent->clone(permanent); } -/** - * Implementation of sim_provider_t.gen_reauth - */ -static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1]) +METHOD(simaka_provider_t, gen_reauth, identification_t*, + private_eap_simaka_reauth_provider_t *this, identification_t *id, + char mk[HASH_SIZE_SHA1]) { reauth_data_t *data; identification_t *permanent; @@ -136,9 +131,9 @@ static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this, } else { /* generate new entry */ - data = malloc_thing(reauth_data_t); - data->counter = 0; - data->id = gen_identity(this); + INIT(data, + .id = gen_identity(this), + ); id = id->clone(id); this->reauth->put(this->reauth, id, data); this->permanent->put(this->permanent, data->id, id); @@ -148,10 +143,8 @@ static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this, return data->id->clone(data->id); } -/** - * Implementation of eap_simaka_reauth_provider_t.destroy. - */ -static void destroy(private_eap_simaka_reauth_provider_t *this) +METHOD(eap_simaka_reauth_provider_t, destroy, void, + private_eap_simaka_reauth_provider_t *this) { enumerator_t *enumerator; identification_t *id; @@ -184,18 +177,23 @@ static void destroy(private_eap_simaka_reauth_provider_t *this) */ eap_simaka_reauth_provider_t *eap_simaka_reauth_provider_create() { - private_eap_simaka_reauth_provider_t *this = malloc_thing(private_eap_simaka_reauth_provider_t); - - this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; - this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; - this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; - this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; - this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))is_reauth; - this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))gen_reauth; - this->public.destroy = (void(*)(eap_simaka_reauth_provider_t*))destroy; - - this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); + private_eap_simaka_reauth_provider_t *this; + + INIT(this, + .public = { + .provider = { + .get_triplet = (void*)return_false, + .get_quintuplet = (void*)return_false, + .resync = (void*)return_false, + .is_pseudonym = (void*)return_null, + .gen_pseudonym = (void*)return_null, + .is_reauth = _is_reauth, + .gen_reauth = _gen_reauth, + }, + .destroy = _destroy, + }, + .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK), + ); if (!this->rng) { free(this); diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h index 7ae151a27..bc6376d53 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h +++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h @@ -21,7 +21,7 @@ #ifndef EAP_SIMAKA_REAUTH_PROVIDER_H_ #define EAP_SIMAKA_REAUTH_PROVIDER_H_ -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_provider.h> typedef struct eap_simaka_reauth_provider_t eap_simaka_reauth_provider_t; @@ -31,9 +31,9 @@ typedef struct eap_simaka_reauth_provider_t eap_simaka_reauth_provider_t; struct eap_simaka_reauth_provider_t { /** - * Implements sim_provider_t interface. + * Implements simaka_provider_t interface. */ - sim_provider_t provider; + simaka_provider_t provider; /** * Destroy a eap_simaka_reauth_provider_t. diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.am b/src/libcharon/plugins/eap_simaka_sql/Makefile.am index 73768be0e..c83267e67 100644 --- a/src/libcharon/plugins/eap_simaka_sql/Makefile.am +++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.am @@ -1,6 +1,6 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\" @@ -8,6 +8,7 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-simaka-sql.la else plugin_LTLIBRARIES = libstrongswan-eap-simaka-sql.la +libstrongswan_eap_simaka_sql_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la endif libstrongswan_eap_simaka_sql_la_SOURCES = \ diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in index 93c7aed03..3639e24e8 100644 --- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in @@ -74,7 +74,8 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_eap_simaka_sql_la_LIBADD = +@MONOLITHIC_FALSE@libstrongswan_eap_simaka_sql_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libsimaka/libsimaka.la am_libstrongswan_eap_simaka_sql_la_OBJECTS = eap_simaka_sql_plugin.lo \ eap_simaka_sql_card.lo eap_simaka_sql_provider.lo libstrongswan_eap_simaka_sql_la_OBJECTS = \ @@ -195,6 +196,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +207,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +224,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +274,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -278,11 +286,12 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\" @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-simaka-sql.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-simaka-sql.la +@MONOLITHIC_FALSE@libstrongswan_eap_simaka_sql_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la libstrongswan_eap_simaka_sql_la_SOURCES = \ eap_simaka_sql_plugin.h eap_simaka_sql_plugin.c \ eap_simaka_sql_card.h eap_simaka_sql_card.c \ diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c index b7590405f..90627b52e 100644 --- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c +++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c @@ -42,7 +42,7 @@ struct private_eap_simaka_sql_card_t { bool remove_used; }; -METHOD(sim_card_t, get_triplet, bool, +METHOD(simaka_card_t, get_triplet, bool, private_eap_simaka_sql_card_t *this, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) { @@ -90,7 +90,7 @@ METHOD(sim_card_t, get_triplet, bool, return found; } -METHOD(sim_card_t, get_quintuplet, status_t, +METHOD(simaka_card_t, get_quintuplet, status_t, private_eap_simaka_sql_card_t *this, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len) diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h index 46b7de25e..760755a56 100644 --- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h +++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h @@ -22,7 +22,7 @@ #define EAP_SIMAKA_SQL_CARD_H_ #include <database/database.h> -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_manager.h> typedef struct eap_simaka_sql_card_t eap_simaka_sql_card_t; @@ -32,9 +32,9 @@ typedef struct eap_simaka_sql_card_t eap_simaka_sql_card_t; struct eap_simaka_sql_card_t { /** - * Implements sim_card_t interface + * Implements simaka_card_t interface */ - sim_card_t card; + simaka_card_t card; /** * Destroy a eap_simaka_sql_card_t. diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c index 5a528153d..6e590fae7 100644 --- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c +++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c @@ -53,14 +53,93 @@ METHOD(plugin_t, get_name, char*, return "eap-simaka-sql"; } -METHOD(plugin_t, destroy, void, - private_eap_simaka_sql_t *this) +/** + * Load database + */ +static bool load_db(private_eap_simaka_sql_t *this, + plugin_feature_t *feature, bool reg, void *data) { - charon->sim->remove_card(charon->sim, &this->card->card); - charon->sim->remove_provider(charon->sim, &this->provider->provider); + if (reg) + { + bool remove_used; + char *uri; + + uri = lib->settings->get_str(lib->settings, + "charon.plugins.eap-simaka-sql.database", NULL); + if (!uri) + { + DBG1(DBG_CFG, "eap-simaka-sql database URI missing"); + return FALSE; + } + this->db = lib->db->create(lib->db, uri); + if (!this->db) + { + DBG1(DBG_CFG, "opening eap-simaka-sql database failed"); + return FALSE; + } + remove_used = lib->settings->get_bool(lib->settings, + "charon.plugins.eap-simaka-sql.remove_used", FALSE); + + this->provider = eap_simaka_sql_provider_create(this->db, remove_used); + this->card = eap_simaka_sql_card_create(this->db, remove_used); + return TRUE; + } this->card->destroy(this->card); this->provider->destroy(this->provider); this->db->destroy(this->db); + this->card = NULL; + this->provider = NULL; + this->db = NULL; + return TRUE; +} + +/** + * Callback providing our card to register + */ +static simaka_card_t* get_card(private_eap_simaka_sql_t *this) +{ + return &this->card->card; +} + +/** + * Callback providing our provider to register + */ +static simaka_provider_t* get_provider(private_eap_simaka_sql_t *this) +{ + return &this->provider->provider; +} + +METHOD(plugin_t, get_features, int, + private_eap_simaka_sql_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((void*)load_db, NULL), + PLUGIN_PROVIDE(CUSTOM, "eap-simaka-sql-db"), + PLUGIN_DEPENDS(DATABASE, DB_ANY), + PLUGIN_SDEPEND(DATABASE, DB_SQLITE), + PLUGIN_SDEPEND(DATABASE, DB_MYSQL), + PLUGIN_CALLBACK(simaka_manager_register, get_card), + PLUGIN_PROVIDE(CUSTOM, "aka-card"), + PLUGIN_DEPENDS(CUSTOM, "aka-manager"), + PLUGIN_DEPENDS(CUSTOM, "eap-simaka-sql-db"), + PLUGIN_PROVIDE(CUSTOM, "sim-card"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + PLUGIN_DEPENDS(CUSTOM, "eap-simaka-sql-db"), + PLUGIN_CALLBACK(simaka_manager_register, get_provider), + PLUGIN_PROVIDE(CUSTOM, "aka-provider"), + PLUGIN_DEPENDS(CUSTOM, "aka-manager"), + PLUGIN_DEPENDS(CUSTOM, "eap-simaka-sql-db"), + PLUGIN_PROVIDE(CUSTOM, "sim-provider"), + PLUGIN_DEPENDS(CUSTOM, "sim-manager"), + PLUGIN_DEPENDS(CUSTOM, "eap-simaka-sql-db"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_eap_simaka_sql_t *this) +{ free(this); } @@ -70,41 +149,16 @@ METHOD(plugin_t, destroy, void, plugin_t *eap_simaka_sql_plugin_create() { private_eap_simaka_sql_t *this; - database_t *db; - bool remove_used; - char *uri; - - uri = lib->settings->get_str(lib->settings, - "charon.plugins.eap-simaka-sql.database", NULL); - if (!uri) - { - DBG1(DBG_CFG, "eap-simaka-sql database URI missing"); - return NULL; - } - db = lib->db->create(lib->db, uri); - if (!db) - { - DBG1(DBG_CFG, "opening eap-simaka-sql database failed"); - return NULL; - } - remove_used = lib->settings->get_bool(lib->settings, - "charon.plugins.eap-simaka-sql.remove_used", FALSE); INIT(this, .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, - .db = db, - .provider = eap_simaka_sql_provider_create(db, remove_used), - .card = eap_simaka_sql_card_create(db, remove_used), ); - charon->sim->add_card(charon->sim, &this->card->card); - charon->sim->add_provider(charon->sim, &this->provider->provider); - return &this->public.plugin; } diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c index 73cccf549..21a19655f 100644 --- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c +++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c @@ -42,7 +42,7 @@ struct private_eap_simaka_sql_provider_t { bool remove_used; }; -METHOD(sim_provider_t, get_triplet, bool, +METHOD(simaka_provider_t, get_triplet, bool, private_eap_simaka_sql_provider_t *this, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) { @@ -53,7 +53,7 @@ METHOD(sim_provider_t, get_triplet, bool, snprintf(buf, sizeof(buf), "%Y", id); query = this->db->query(this->db, - "select rand, sres, kc from triplets where id = ? order by use", + "select rand, sres, kc from triplets where id = ? order by used", DB_TEXT, buf, DB_BLOB, DB_BLOB, DB_BLOB); if (query) { @@ -82,7 +82,7 @@ METHOD(sim_provider_t, get_triplet, bool, else { this->db->execute(this->db, NULL, - "update triplets set use = ? where id = ? and rand = ?", + "update triplets set used = ? where id = ? and rand = ?", DB_UINT, time(NULL), DB_TEXT, buf, DB_BLOB, chunk_create(rand, SIM_RAND_LEN)); } @@ -90,7 +90,7 @@ METHOD(sim_provider_t, get_triplet, bool, return found; } -METHOD(sim_provider_t, get_quintuplet, bool, +METHOD(simaka_provider_t, get_quintuplet, bool, private_eap_simaka_sql_provider_t *this, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]) @@ -102,7 +102,7 @@ METHOD(sim_provider_t, get_quintuplet, bool, snprintf(buf, sizeof(buf), "%Y", id); query = this->db->query(this->db, "select rand, res, ck, ik, autn " - "from quintuplets where id = ? order by use", DB_TEXT, buf, + "from quintuplets where id = ? order by used", DB_TEXT, buf, DB_BLOB, DB_BLOB, DB_BLOB, DB_BLOB, DB_BLOB); if (query) { @@ -137,7 +137,7 @@ METHOD(sim_provider_t, get_quintuplet, bool, else { this->db->execute(this->db, NULL, - "update quintuplets set use = ? where id = ? and rand = ?", + "update quintuplets set used = ? where id = ? and rand = ?", DB_UINT, time(NULL), DB_TEXT, buf, DB_BLOB, chunk_create(rand, AKA_RAND_LEN)); } diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h index ecb0c8cb0..88a8b1f24 100644 --- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h +++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h @@ -22,7 +22,7 @@ #define EAP_SIMAKA_SQL_PROVIDER_H_ #include <database/database.h> -#include <sa/authenticators/eap/sim_manager.h> +#include <simaka_provider.h> typedef struct eap_simaka_sql_provider_t eap_simaka_sql_provider_t; @@ -32,9 +32,9 @@ typedef struct eap_simaka_sql_provider_t eap_simaka_sql_provider_t; struct eap_simaka_sql_provider_t { /** - * Implements sim_provider_t interface + * Implements simaka_provider_t interface */ - sim_provider_t provider; + simaka_provider_t provider; /** * Destroy a eap_simaka_sql_provider_t. diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in index c58bced06..67e2c0cb0 100644 --- a/src/libcharon/plugins/eap_tls/Makefile.in +++ b/src/libcharon/plugins/eap_tls/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c index 39e1a60d9..dc0289ba2 100644 --- a/src/libcharon/plugins/eap_tls/eap_tls.c +++ b/src/libcharon/plugins/eap_tls/eap_tls.c @@ -39,7 +39,7 @@ struct private_eap_tls_t { }; /** Maximum number of EAP-TLS messages/fragments allowed */ -#define MAX_MESSAGE_COUNT 32 +#define MAX_MESSAGE_COUNT 32 /** Default size of a EAP-TLS fragment */ #define MAX_FRAGMENT_LEN 1024 @@ -148,8 +148,8 @@ static eap_tls_t *eap_tls_create(identification_t *server, max_msg_count = lib->settings->get_int(lib->settings, "charon.plugins.eap-tls.max_message_count", MAX_MESSAGE_COUNT); include_length = lib->settings->get_bool(lib->settings, - "charon.plugins.eap-tls.include_length", TRUE); - tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL); + "charon.plugins.eap-tls.include_length", TRUE); + tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL, NULL); this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count, include_length); if (!this->tls_eap) diff --git a/src/libcharon/plugins/eap_tls/eap_tls_plugin.c b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c index 7afb79819..5507d8e02 100644 --- a/src/libcharon/plugins/eap_tls/eap_tls_plugin.c +++ b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c @@ -25,13 +25,29 @@ METHOD(plugin_t, get_name, char*, return "eap-tls"; } +METHOD(plugin_t, get_features, int, + eap_tls_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_tls_create_server), + PLUGIN_PROVIDE(EAP_SERVER, EAP_TLS), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_CALLBACK(eap_method_register, eap_tls_create_peer), + PLUGIN_PROVIDE(EAP_PEER, EAP_TLS), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, eap_tls_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_tls_create_server); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_tls_create_peer); free(this); } @@ -45,15 +61,10 @@ plugin_t *eap_tls_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->eap->add_method(charon->eap, EAP_TLS, 0, EAP_SERVER, - (eap_constructor_t)eap_tls_create_server); - charon->eap->add_method(charon->eap, EAP_TLS, 0, EAP_PEER, - (eap_constructor_t)eap_tls_create_peer); - return &this->plugin; } diff --git a/src/libcharon/plugins/eap_tnc/Makefile.am b/src/libcharon/plugins/eap_tnc/Makefile.am index 9c5a445c5..0e10f7d9c 100644 --- a/src/libcharon/plugins/eap_tnc/Makefile.am +++ b/src/libcharon/plugins/eap_tnc/Makefile.am @@ -1,6 +1,11 @@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @@ -8,7 +13,9 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-eap-tnc.la else plugin_LTLIBRARIES = libstrongswan-eap-tnc.la -libstrongswan_eap_tnc_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +libstrongswan_eap_tnc_la_LIBADD = \ + $(top_builddir)/src/libtls/libtls.la \ + $(top_builddir)/src/libtnccs/libtnccs.la endif libstrongswan_eap_tnc_la_SOURCES = \ diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in index dfc052bf8..62278f835 100644 --- a/src/libcharon/plugins/eap_tnc/Makefile.in +++ b/src/libcharon/plugins/eap_tnc/Makefile.in @@ -75,7 +75,8 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) @MONOLITHIC_FALSE@libstrongswan_eap_tnc_la_DEPENDENCIES = \ -@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la am_libstrongswan_eap_tnc_la_OBJECTS = eap_tnc_plugin.lo eap_tnc.lo libstrongswan_eap_tnc_la_OBJECTS = \ $(am_libstrongswan_eap_tnc_la_OBJECTS) @@ -194,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -276,13 +284,21 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-tnc.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-tnc.la -@MONOLITHIC_FALSE@libstrongswan_eap_tnc_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +@MONOLITHIC_FALSE@libstrongswan_eap_tnc_la_LIBADD = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la + libstrongswan_eap_tnc_la_SOURCES = \ eap_tnc_plugin.h eap_tnc_plugin.c eap_tnc.h eap_tnc.c diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c index ab3f87688..33a83ba18 100644 --- a/src/libcharon/plugins/eap_tnc/eap_tnc.c +++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c @@ -15,9 +15,9 @@ #include "eap_tnc.h" +#include <tnc/tnc.h> +#include <tnc/tnccs/tnccs_manager.h> #include <tls_eap.h> - -#include <daemon.h> #include <debug.h> typedef struct private_eap_tnc_t private_eap_tnc_t; @@ -172,7 +172,7 @@ static eap_tnc_t *eap_tnc_create(identification_t *server, free(this); return NULL; } - tnccs = charon->tnccs->create_instance(charon->tnccs, type, is_server); + tnccs = tnc->tnccs->create_instance(tnc->tnccs, type, is_server); this->tls_eap = tls_eap_create(EAP_TNC, (tls_t*)tnccs, frag_size, max_msg_count, include_length); if (!this->tls_eap) diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c index 93847e636..813a75f48 100644 --- a/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c +++ b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c @@ -24,13 +24,26 @@ METHOD(plugin_t, get_name, char*, return "eap-tnc"; } +METHOD(plugin_t, get_features, int, + eap_tnc_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_tnc_create_server), + PLUGIN_PROVIDE(EAP_SERVER, EAP_TNC), + PLUGIN_DEPENDS(EAP_SERVER, EAP_TTLS), + PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"), + PLUGIN_CALLBACK(eap_method_register, eap_tnc_create_peer), + PLUGIN_PROVIDE(EAP_PEER, EAP_TNC), + PLUGIN_DEPENDS(EAP_PEER, EAP_TTLS), + PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, eap_tnc_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_tnc_create_server); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_tnc_create_peer); free(this); } @@ -44,16 +57,11 @@ plugin_t *eap_tnc_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->eap->add_method(charon->eap, EAP_TNC, 0, EAP_SERVER, - (eap_constructor_t)eap_tnc_create_server); - charon->eap->add_method(charon->eap, EAP_TNC, 0, EAP_PEER, - (eap_constructor_t)eap_tnc_create_peer); - return &this->plugin; } diff --git a/src/libcharon/plugins/eap_ttls/Makefile.am b/src/libcharon/plugins/eap_ttls/Makefile.am index 94ce5cc1e..8cc82cc2e 100644 --- a/src/libcharon/plugins/eap_ttls/Makefile.am +++ b/src/libcharon/plugins/eap_ttls/Makefile.am @@ -1,6 +1,7 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libradius AM_CFLAGS = -rdynamic diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in index d0d5341e2..b41fbd719 100644 --- a/src/libcharon/plugins/eap_ttls/Makefile.in +++ b/src/libcharon/plugins/eap_ttls/Makefile.in @@ -197,6 +197,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -205,6 +208,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -221,11 +225,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -269,6 +275,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -280,7 +287,8 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libradius AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-ttls.la diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c index 7193bc9f0..ace62f6b9 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c @@ -156,7 +156,8 @@ static eap_ttls_t *eap_ttls_create(identification_t *server, "charon.plugins.eap-ttls.max_message_count", MAX_MESSAGE_COUNT); include_length = lib->settings->get_bool(lib->settings, "charon.plugins.eap-ttls.include_length", TRUE); - tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application); + tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, + application, NULL); this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size, max_msg_count, include_length); if (!this->tls_eap) diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c index 0eb5e94be..0d531c437 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c @@ -54,7 +54,7 @@ struct private_eap_ttls_avp_t { }; METHOD(eap_ttls_avp_t, build, void, - private_eap_ttls_avp_t *this, tls_writer_t *writer, chunk_t data) + private_eap_ttls_avp_t *this, bio_writer_t *writer, chunk_t data) { char zero_padding[] = { 0x00, 0x00, 0x00 }; chunk_t avp_padding; @@ -73,14 +73,14 @@ METHOD(eap_ttls_avp_t, build, void, } METHOD(eap_ttls_avp_t, process, status_t, - private_eap_ttls_avp_t* this, tls_reader_t *reader, chunk_t *data) + private_eap_ttls_avp_t* this, bio_reader_t *reader, chunk_t *data) { size_t len; chunk_t buf; if (this->process_header) { - tls_reader_t *header; + bio_reader_t *header; u_int32_t avp_code; u_int8_t avp_flags; u_int32_t avp_len; @@ -110,7 +110,7 @@ METHOD(eap_ttls_avp_t, process, status_t, } /* parse AVP header */ - header = tls_reader_create(this->input); + header = bio_reader_create(this->input); success = header->read_uint32(header, &avp_code) && header->read_uint8(header, &avp_flags) && header->read_uint24(header, &avp_len); diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h index cad1d9c56..e56d92fc2 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h @@ -25,8 +25,8 @@ typedef struct eap_ttls_avp_t eap_ttls_avp_t; #include <library.h> -#include <tls_reader.h> -#include <tls_writer.h> +#include <bio/bio_reader.h> +#include <bio/bio_writer.h> /** * EAP-TTLS Attribute-Value Pair (AVP) handler. @@ -43,7 +43,7 @@ struct eap_ttls_avp_t { * - FAILED if AVP processing failed * - NEED_MORE if another invocation of process/build needed */ - status_t (*process)(eap_ttls_avp_t *this, tls_reader_t *reader, + status_t (*process)(eap_ttls_avp_t *this, bio_reader_t *reader, chunk_t *data); /** @@ -52,7 +52,7 @@ struct eap_ttls_avp_t { * @param writer TLS data buffer to write to * @param data EAP Message to send */ - void (*build)(eap_ttls_avp_t *this, tls_writer_t *writer, chunk_t data); + void (*build)(eap_ttls_avp_t *this, bio_writer_t *writer, chunk_t data); /** * Destroy a eap_ttls_application_t. diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c index 931eb2e89..4b6897b1d 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c @@ -18,7 +18,7 @@ #include <debug.h> #include <daemon.h> - +#include <radius_message.h> #include <sa/authenticators/eap/eap_method.h> typedef struct private_eap_ttls_peer_t private_eap_ttls_peer_t; @@ -64,10 +64,8 @@ struct private_eap_ttls_peer_t { eap_ttls_avp_t *avp; }; -#define MAX_RADIUS_ATTRIBUTE_SIZE 253 - METHOD(tls_application_t, process, status_t, - private_eap_ttls_peer_t *this, tls_reader_t *reader) + private_eap_ttls_peer_t *this, bio_reader_t *reader) { chunk_t avp_data = chunk_empty; chunk_t eap_data = chunk_empty; @@ -229,7 +227,7 @@ METHOD(tls_application_t, process, status_t, } METHOD(tls_application_t, build, status_t, - private_eap_ttls_peer_t *this, tls_writer_t *writer) + private_eap_ttls_peer_t *this, bio_writer_t *writer) { chunk_t data; eap_code_t code; diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c index cbc3929bb..7ccbc9381 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c @@ -25,13 +25,31 @@ METHOD(plugin_t, get_name, char*, return "eap-ttls"; } +METHOD(plugin_t, get_features, int, + eap_ttls_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(eap_method_register, eap_ttls_create_server), + PLUGIN_PROVIDE(EAP_SERVER, EAP_TTLS), + PLUGIN_DEPENDS(EAP_SERVER, EAP_IDENTITY), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_CALLBACK(eap_method_register, eap_ttls_create_peer), + PLUGIN_PROVIDE(EAP_PEER, EAP_TTLS), + PLUGIN_DEPENDS(EAP_PEER, EAP_IDENTITY), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, eap_ttls_plugin_t *this) { - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_ttls_create_server); - charon->eap->remove_method(charon->eap, - (eap_constructor_t)eap_ttls_create_peer); free(this); } @@ -45,15 +63,10 @@ plugin_t *eap_ttls_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->eap->add_method(charon->eap, EAP_TTLS, 0, EAP_SERVER, - (eap_constructor_t)eap_ttls_create_server); - charon->eap->add_method(charon->eap, EAP_TTLS, 0, EAP_PEER, - (eap_constructor_t)eap_ttls_create_peer); - return &this->plugin; } diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_server.c b/src/libcharon/plugins/eap_ttls/eap_ttls_server.c index 835cd7306..3c46993b7 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls_server.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_server.c @@ -135,7 +135,7 @@ static status_t start_phase2_tnc(private_eap_ttls_server_t *this) } METHOD(tls_application_t, process, status_t, - private_eap_ttls_server_t *this, tls_reader_t *reader) + private_eap_ttls_server_t *this, bio_reader_t *reader) { chunk_t data = chunk_empty; status_t status; @@ -284,7 +284,7 @@ METHOD(tls_application_t, process, status_t, } METHOD(tls_application_t, build, status_t, - private_eap_ttls_server_t *this, tls_writer_t *writer) + private_eap_ttls_server_t *this, bio_writer_t *writer) { chunk_t data; eap_code_t code; diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in index 4ba29472d..cfb51933c 100644 --- a/src/libcharon/plugins/farp/Makefile.in +++ b/src/libcharon/plugins/farp/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/farp/farp_listener.c b/src/libcharon/plugins/farp/farp_listener.c index 8eed49778..d1df4cc27 100644 --- a/src/libcharon/plugins/farp/farp_listener.c +++ b/src/libcharon/plugins/farp/farp_listener.c @@ -15,7 +15,7 @@ #include "farp_listener.h" -#include <utils/hashtable.h> +#include <utils/linked_list.h> #include <threading/rwlock.h> typedef struct private_farp_listener_t private_farp_listener_t; @@ -31,9 +31,9 @@ struct private_farp_listener_t { farp_listener_t public; /** - * Hashtable with active virtual IPs + * List with entry_t */ - hashtable_t *ips; + linked_list_t *entries; /** * RWlock for IP list @@ -42,88 +42,99 @@ struct private_farp_listener_t { }; /** - * Hashtable hash function + * Traffic selector cache entry */ -static u_int hash(host_t *key) +typedef struct { + /** list of local selectors */ + linked_list_t *local; + /** list of remote selectors */ + linked_list_t *remote; + /** reqid of CHILD_SA */ + u_int32_t reqid; +} entry_t; + +METHOD(listener_t, child_updown, bool, + private_farp_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + bool up) { - return chunk_hash(key->get_address(key)); -} - -/** - * Hashtable equals function - */ -static bool equals(host_t *a, host_t *b) -{ - return a->ip_equals(a, b); -} + enumerator_t *enumerator; + entry_t *entry; -METHOD(listener_t, ike_updown, bool, - private_farp_listener_t *this, ike_sa_t *ike_sa, bool up) -{ - if (!up) + if (up) { - host_t *ip; - - ip = ike_sa->get_virtual_ip(ike_sa, FALSE); - if (ip) - { - this->lock->write_lock(this->lock); - ip = this->ips->remove(this->ips, ip); - this->lock->unlock(this->lock); - DESTROY_IF(ip); - } + INIT(entry, + .local = child_sa->get_traffic_selectors(child_sa, TRUE), + .remote = child_sa->get_traffic_selectors(child_sa, FALSE), + .reqid = child_sa->get_reqid(child_sa), + ); + entry->local = entry->local->clone_offset(entry->local, + offsetof(traffic_selector_t, clone)); + entry->remote = entry->remote->clone_offset(entry->remote, + offsetof(traffic_selector_t, clone)); + + this->lock->write_lock(this->lock); + this->entries->insert_last(this->entries, entry); + this->lock->unlock(this->lock); } - return TRUE; -} - -METHOD(listener_t, message_hook, bool, - private_farp_listener_t *this, ike_sa_t *ike_sa, - message_t *message, bool incoming) -{ - if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && - message->get_exchange_type(message) == IKE_AUTH && - !message->get_request(message)) + else { - host_t *ip; - - ip = ike_sa->get_virtual_ip(ike_sa, FALSE); - if (ip) + this->lock->write_lock(this->lock); + enumerator = this->entries->create_enumerator(this->entries); + while (enumerator->enumerate(enumerator, &entry)) { - ip = ip->clone(ip); - this->lock->write_lock(this->lock); - ip = this->ips->put(this->ips, ip, ip); - this->lock->unlock(this->lock); - DESTROY_IF(ip); + if (entry->reqid == child_sa->get_reqid(child_sa)) + { + this->entries->remove_at(this->entries, enumerator); + entry->local->destroy_offset(entry->local, + offsetof(traffic_selector_t, destroy)); + entry->remote->destroy_offset(entry->remote, + offsetof(traffic_selector_t, destroy)); + free(entry); + } } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); } return TRUE; } -METHOD(farp_listener_t, is_active, bool, - private_farp_listener_t *this, host_t *ip) +METHOD(farp_listener_t, has_tunnel, bool, + private_farp_listener_t *this, host_t *local, host_t *remote) { - bool active; + enumerator_t *entries, *locals, *remotes; + traffic_selector_t *ts; + bool found = FALSE; + entry_t *entry; this->lock->read_lock(this->lock); - active = this->ips->get(this->ips, ip) != NULL; + entries = this->entries->create_enumerator(this->entries); + while (!found && entries->enumerate(entries, &entry)) + { + remotes = entry->remote->create_enumerator(entry->remote); + while (!found && remotes->enumerate(remotes, &ts)) + { + if (ts->includes(ts, remote)) + { + locals = entry->local->create_enumerator(entry->local); + while (!found && locals->enumerate(locals, &ts)) + { + found = ts->includes(ts, local); + } + locals->destroy(locals); + } + } + remotes->destroy(remotes); + } + entries->destroy(entries); this->lock->unlock(this->lock); - return active; + + return found; } METHOD(farp_listener_t, destroy, void, private_farp_listener_t *this) { - enumerator_t *enumerator; - host_t *key, *value; - - enumerator = this->ips->create_enumerator(this->ips); - while (enumerator->enumerate(enumerator, &key, &value)) - { - value->destroy(value); - } - enumerator->destroy(enumerator); - this->ips->destroy(this->ips); - + this->entries->destroy(this->entries); this->lock->destroy(this->lock); free(this); } @@ -138,14 +149,12 @@ farp_listener_t *farp_listener_create() INIT(this, .public = { .listener = { - .ike_updown = _ike_updown, - .message = _message_hook, + .child_updown = _child_updown, }, - .is_active = _is_active, + .has_tunnel = _has_tunnel, .destroy = _destroy, }, - .ips = hashtable_create((hashtable_hash_t)hash, - (hashtable_equals_t)equals, 8), + .entries = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); diff --git a/src/libcharon/plugins/farp/farp_listener.h b/src/libcharon/plugins/farp/farp_listener.h index bd96d7a1c..3155f60e2 100644 --- a/src/libcharon/plugins/farp/farp_listener.h +++ b/src/libcharon/plugins/farp/farp_listener.h @@ -37,12 +37,13 @@ struct farp_listener_t { listener_t listener; /** - * Check if a given IP is currently used as virtual IP by a peer. + * Check if we have a tunnel between two IP addresses. * - * @param ip IP to check - * @return TRUE if IP is an active virtual IP + * @param local local IP + * @param remote remote IP + * @return TRUE if a tunnel is active */ - bool (*is_active)(farp_listener_t *this, host_t *ip); + bool (*has_tunnel)(farp_listener_t *this, host_t *local, host_t *remote); /** * Destroy a farp_listener_t. diff --git a/src/libcharon/plugins/farp/farp_spoofer.c b/src/libcharon/plugins/farp/farp_spoofer.c index a904a6538..587a3a74e 100644 --- a/src/libcharon/plugins/farp/farp_spoofer.c +++ b/src/libcharon/plugins/farp/farp_spoofer.c @@ -108,7 +108,7 @@ static job_requeue_t receive_arp(private_farp_spoofer_t *this) arp_t arp; int oldstate; ssize_t len; - host_t *ip; + host_t *local, *remote; oldstate = thread_cancelability(TRUE); len = recvfrom(this->skt, &arp, sizeof(arp), 0, @@ -117,16 +117,16 @@ static job_requeue_t receive_arp(private_farp_spoofer_t *this) if (len == sizeof(arp)) { - ip = host_create_from_chunk(AF_INET, + local = host_create_from_chunk(AF_INET, + chunk_create((char*)&arp.sender_ip, 4), 0); + remote = host_create_from_chunk(AF_INET, chunk_create((char*)&arp.target_ip, 4), 0); - if (ip) + if (this->listener->has_tunnel(this->listener, local, remote)) { - if (this->listener->is_active(this->listener, ip)) - { - send_arp(this, &arp, &addr); - } - ip->destroy(ip); + send_arp(this, &arp, &addr); } + local->destroy(local); + remote->destroy(remote); } return JOB_REQUEUE_DIRECT; @@ -189,8 +189,8 @@ farp_spoofer_t *farp_spoofer_create(farp_listener_t *listener) return NULL; } - this->job = callback_job_create((callback_job_cb_t)receive_arp, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)receive_arp, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; diff --git a/src/libcharon/plugins/ha/Makefile.am b/src/libcharon/plugins/ha/Makefile.am index 0df1b8d91..bc1b49d48 100644 --- a/src/libcharon/plugins/ha/Makefile.am +++ b/src/libcharon/plugins/ha/Makefile.am @@ -1,5 +1,5 @@ -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ +INCLUDES = -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in index fe72c5c8e..c66a550cd 100644 --- a/src/libcharon/plugins/ha/Makefile.in +++ b/src/libcharon/plugins/ha/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -276,7 +283,7 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ +INCLUDES = -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c index 9ff3fd5ff..970a8a2b9 100644 --- a/src/libcharon/plugins/ha/ha_cache.c +++ b/src/libcharon/plugins/ha/ha_cache.c @@ -196,22 +196,37 @@ METHOD(ha_cache_t, delete_, void, */ static status_t rekey_children(ike_sa_t *ike_sa) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; status_t status = SUCCESS; - iterator = ike_sa->create_child_sa_iterator(ike_sa); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = ike_sa->create_child_sa_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { - DBG1(DBG_CFG, "resyncing CHILD_SA"); - status = ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE)); + if (ike_sa->supports_extension(ike_sa, EXT_MS_WINDOWS) && + ike_sa->has_condition(ike_sa, COND_NAT_THERE)) + { + /* NATed Windows clients don't accept CHILD_SA rekeying, but fail + * with an "invalid situation" error. We just close the CHILD_SA, + * Windows will reestablish it immediately if required. */ + DBG1(DBG_CFG, "resyncing CHILD_SA using a delete"); + status = ike_sa->delete_child_sa(ike_sa, + child_sa->get_protocol(child_sa), + child_sa->get_spi(child_sa, TRUE)); + } + else + { + DBG1(DBG_CFG, "resyncing CHILD_SA using a rekey"); + status = ike_sa->rekey_child_sa(ike_sa, + child_sa->get_protocol(child_sa), + child_sa->get_spi(child_sa, TRUE)); + } if (status == DESTROY_ME) { break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return status; } @@ -228,7 +243,7 @@ static void rekey_segment(private_ha_cache_t *this, u_int segment) list = linked_list_create(); enumerator = charon->ike_sa_manager->create_enumerator( - charon->ike_sa_manager); + charon->ike_sa_manager, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && @@ -355,8 +370,8 @@ ha_cache_t *ha_cache_create(ha_kernel_t *kernel, ha_socket_t *socket, { /* request a resync as soon as we are up */ lib->scheduler->schedule_job(lib->scheduler, (job_t*) - callback_job_create((callback_job_cb_t)request_resync, - this, NULL, NULL), 1); + callback_job_create_with_prio((callback_job_cb_t)request_resync, + this, NULL, NULL, JOB_PRIO_CRITICAL), 1); } return &this->public; } diff --git a/src/libcharon/plugins/ha/ha_ctl.c b/src/libcharon/plugins/ha/ha_ctl.c index 15f7824f9..9c99807ed 100644 --- a/src/libcharon/plugins/ha/ha_ctl.c +++ b/src/libcharon/plugins/ha/ha_ctl.c @@ -141,8 +141,8 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache) strerror(errno)); } - this->job = callback_job_create((callback_job_cb_t)dispatch_fifo, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)dispatch_fifo, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; } diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c index 0d0df8dd1..994f91d20 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -220,7 +220,7 @@ static void process_ike_update(private_ha_dispatcher_t *this, ike_sa_t *ike_sa = NULL; peer_cfg_t *peer_cfg = NULL; auth_cfg_t *auth; - bool received_vip = FALSE; + bool received_vip = FALSE, first_peer_addr = TRUE; enumerator = message->create_attribute_enumerator(message); while (enumerator->enumerate(enumerator, &attribute, &value)) @@ -260,9 +260,13 @@ static void process_ike_update(private_ha_dispatcher_t *this, ike_sa->set_virtual_ip(ike_sa, FALSE, value.host); received_vip = TRUE; break; - case HA_ADDITIONAL_ADDR: - ike_sa->add_additional_address(ike_sa, - value.host->clone(value.host)); + case HA_PEER_ADDR: + if (first_peer_addr) + { + ike_sa->clear_peer_addresses(ike_sa); + first_peer_addr = FALSE; + } + ike_sa->add_peer_address(ike_sa, value.host->clone(value.host)); break; case HA_CONFIG_NAME: peer_cfg = charon->backends->get_peer_cfg_by_name( @@ -281,6 +285,10 @@ static void process_ike_update(private_ha_dispatcher_t *this, set_extension(ike_sa, value.u32, EXT_NATT); set_extension(ike_sa, value.u32, EXT_MOBIKE); set_extension(ike_sa, value.u32, EXT_HASH_AND_URL); + set_extension(ike_sa, value.u32, EXT_MULTIPLE_AUTH); + set_extension(ike_sa, value.u32, EXT_STRONGSWAN); + set_extension(ike_sa, value.u32, EXT_EAP_ONLY_AUTHENTICATION); + set_extension(ike_sa, value.u32, EXT_MS_WINDOWS); break; case HA_CONDITIONS: set_condition(ike_sa, value.u32, COND_NAT_ANY); @@ -290,6 +298,7 @@ static void process_ike_update(private_ha_dispatcher_t *this, set_condition(ike_sa, value.u32, COND_EAP_AUTHENTICATED); set_condition(ike_sa, value.u32, COND_CERTREQ_SEEN); set_condition(ike_sa, value.u32, COND_ORIGINAL_INITIATOR); + set_condition(ike_sa, value.u32, COND_STALE); break; default: break; @@ -872,8 +881,8 @@ ha_dispatcher_t *ha_dispatcher_create(ha_socket_t *socket, .kernel = kernel, .attr = attr, ); - this->job = callback_job_create((callback_job_cb_t)dispatch, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)dispatch, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c index 1efba4e8f..e818aec9c 100644 --- a/src/libcharon/plugins/ha/ha_ike.c +++ b/src/libcharon/plugins/ha/ha_ike.c @@ -143,7 +143,7 @@ METHOD(listener_t, ike_updown, bool, if (up) { - iterator_t *iterator; + enumerator_t *enumerator; peer_cfg_t *peer_cfg; u_int32_t extension, condition; host_t *addr; @@ -158,11 +158,16 @@ METHOD(listener_t, ike_updown, bool, | copy_condition(ike_sa, COND_NAT_FAKE) | copy_condition(ike_sa, COND_EAP_AUTHENTICATED) | copy_condition(ike_sa, COND_CERTREQ_SEEN) - | copy_condition(ike_sa, COND_ORIGINAL_INITIATOR); + | copy_condition(ike_sa, COND_ORIGINAL_INITIATOR) + | copy_condition(ike_sa, COND_STALE); extension = copy_extension(ike_sa, EXT_NATT) | copy_extension(ike_sa, EXT_MOBIKE) - | copy_extension(ike_sa, EXT_HASH_AND_URL); + | copy_extension(ike_sa, EXT_HASH_AND_URL) + | copy_extension(ike_sa, EXT_MULTIPLE_AUTH) + | copy_extension(ike_sa, EXT_STRONGSWAN) + | copy_extension(ike_sa, EXT_EAP_ONLY_AUTHENTICATION) + | copy_extension(ike_sa, EXT_MS_WINDOWS); id = ike_sa->get_id(ike_sa); @@ -180,12 +185,12 @@ METHOD(listener_t, ike_updown, bool, m->add_attribute(m, HA_CONDITIONS, condition); m->add_attribute(m, HA_EXTENSIONS, extension); m->add_attribute(m, HA_CONFIG_NAME, peer_cfg->get_name(peer_cfg)); - iterator = ike_sa->create_additional_address_iterator(ike_sa); - while (iterator->iterate(iterator, (void**)&addr)) + enumerator = ike_sa->create_peer_address_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, (void**)&addr)) { - m->add_attribute(m, HA_ADDITIONAL_ADDR, addr); + m->add_attribute(m, HA_PEER_ADDR, addr); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } else { diff --git a/src/libcharon/plugins/ha/ha_kernel.c b/src/libcharon/plugins/ha/ha_kernel.c index 56bdbf454..2377a2630 100644 --- a/src/libcharon/plugins/ha/ha_kernel.c +++ b/src/libcharon/plugins/ha/ha_kernel.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Martin Willi + * Copyright (C) 2009-2011 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,7 +18,7 @@ typedef u_int32_t u32; typedef u_int8_t u8; -#include <linux/jhash.h> +#include <sys/utsname.h> #include <string.h> #include <errno.h> #include <unistd.h> @@ -28,6 +28,16 @@ typedef u_int8_t u8; #define CLUSTERIP_DIR "/proc/net/ipt_CLUSTERIP" +/** + * Versions of jhash used in the Linux kernel + */ +typedef enum { + /* old variant, http://burtleburtle.net/bob/c/lookup2.c */ + JHASH_LOOKUP2, + /* new variant, http://burtleburtle.net/bob/c/lookup3.c, since 2.6.37 */ + JHASH_LOOKUP3, +} jhash_version_t; + typedef struct private_ha_kernel_t private_ha_kernel_t; /** @@ -41,17 +51,98 @@ struct private_ha_kernel_t { ha_kernel_t public; /** - * Init value for jhash + * Total number of ClusterIP segments */ - u_int initval; + u_int count; /** - * Total number of ClusterIP segments + * jhash version the kernel uses */ - u_int count; + jhash_version_t version; }; /** + * Get the jhash version based on the uname().release + */ +static jhash_version_t get_jhash_version() +{ + struct utsname utsname; + int a, b, c; + + if (uname(&utsname) == 0) + { + switch (sscanf(utsname.release, "%d.%d.%d", &a, &b, &c)) + { + case 3: + if (a == 2 && b == 6) + { + if (c < 37) + { + DBG1(DBG_CFG, "detected Linux %d.%d.%d, using old " + "jhash", a, b, c); + return JHASH_LOOKUP2; + } + DBG1(DBG_CFG, "detected Linux %d.%d.%d, using new " + "jhash", a, b, c); + return JHASH_LOOKUP3; + } + /* FALL */ + case 2: + DBG1(DBG_CFG, "detected Linux %d.%d, using new jhash", a, b); + return JHASH_LOOKUP3; + default: + break; + } + } + DBG1(DBG_CFG, "detecting Linux version failed, using new jhash"); + return JHASH_LOOKUP3; +} + +/** + * Rotate 32 bit word x by k bits + */ +#define jhash_rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/** + * jhash algorithm of two words, as used in kernel (using 0 as initval) + */ +static u_int32_t jhash(jhash_version_t version, u_int32_t a, u_int32_t b) +{ + u_int32_t c = 0; + + switch (version) + { + case JHASH_LOOKUP2: + a += 0x9e3779b9; + b += 0x9e3779b9; + + a -= b; a -= c; a ^= (c >> 13); + b -= c; b -= a; b ^= (a << 8); + c -= a; c -= b; c ^= (b >> 13); + a -= b; a -= c; a ^= (c >> 12); + b -= c; b -= a; b ^= (a << 16); + c -= a; c -= b; c ^= (b >> 5); + a -= b; a -= c; a ^= (c >> 3); + b -= c; b -= a; b ^= (a << 10); + c -= a; c -= b; c ^= (b >> 15); + break; + case JHASH_LOOKUP3: + a += 0xdeadbeef; + b += 0xdeadbeef; + + c ^= b; c -= jhash_rot(b, 14); + a ^= c; a -= jhash_rot(c, 11); + b ^= a; b -= jhash_rot(a, 25); + c ^= b; c -= jhash_rot(b, 16); + a ^= c; a -= jhash_rot(c, 4); + b ^= a; b -= jhash_rot(a, 14); + c ^= b; c -= jhash_rot(b, 24); + break; + } + return c; +} + +/** * Segmentate a calculated hash */ static u_int hash2segment(private_ha_kernel_t *this, u_int64_t hash) @@ -78,7 +169,7 @@ METHOD(ha_kernel_t, get_segment, u_int, u_int32_t addr; addr = host2int(host); - hash = jhash_1word(ntohl(addr), this->initval); + hash = jhash(this->version, ntohl(addr), 0); return hash2segment(this, hash); } @@ -90,7 +181,7 @@ METHOD(ha_kernel_t, get_segment_spi, u_int, u_int32_t addr; addr = host2int(host); - hash = jhash_2words(ntohl(addr), ntohl(spi), this->initval); + hash = jhash(this->version, ntohl(addr), ntohl(spi)); return hash2segment(this, hash); } @@ -100,7 +191,7 @@ METHOD(ha_kernel_t, get_segment_int, u_int, { unsigned long hash; - hash = jhash_1word(ntohl(n), this->initval); + hash = jhash(this->version, ntohl(n), 0); return hash2segment(this, hash); } @@ -123,7 +214,7 @@ static void enable_disable(private_ha_kernel_t *this, u_int segment, file, strerror(errno)); return; } - if (write(fd, cmd, strlen(cmd) == -1)) + if (write(fd, cmd, strlen(cmd)) == -1) { DBG1(DBG_CFG, "writing to CLUSTERIP file '%s' failed: %s", file, strerror(errno)); @@ -149,6 +240,7 @@ static segment_mask_t get_active(private_ha_kernel_t *this, char *file) return 0; } len = read(fd, buf, sizeof(buf)-1); + close(fd); if (len == -1) { DBG1(DBG_CFG, "reading from CLUSTERIP file '%s' failed: %s", @@ -182,11 +274,14 @@ METHOD(ha_kernel_t, activate, void, char *file; enumerator = enumerator_create_directory(CLUSTERIP_DIR); - while (enumerator->enumerate(enumerator, NULL, &file, NULL)) + if (enumerator) { - enable_disable(this, segment, file, TRUE); + while (enumerator->enumerate(enumerator, NULL, &file, NULL)) + { + enable_disable(this, segment, file, TRUE); + } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); } METHOD(ha_kernel_t, deactivate, void, @@ -196,11 +291,14 @@ METHOD(ha_kernel_t, deactivate, void, char *file; enumerator = enumerator_create_directory(CLUSTERIP_DIR); - while (enumerator->enumerate(enumerator, NULL, &file, NULL)) + if (enumerator) { - enable_disable(this, segment, file, FALSE); + while (enumerator->enumerate(enumerator, NULL, &file, NULL)) + { + enable_disable(this, segment, file, FALSE); + } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); } /** @@ -214,23 +312,26 @@ static void disable_all(private_ha_kernel_t *this) int i; enumerator = enumerator_create_directory(CLUSTERIP_DIR); - while (enumerator->enumerate(enumerator, NULL, &file, NULL)) + if (enumerator) { - if (chown(file, charon->uid, charon->gid) != 0) + while (enumerator->enumerate(enumerator, NULL, &file, NULL)) { - DBG1(DBG_CFG, "changing ClusterIP permissions failed: %s", - strerror(errno)); - } - active = get_active(this, file); - for (i = 1; i <= this->count; i++) - { - if (active & SEGMENTS_BIT(i)) + if (chown(file, charon->uid, charon->gid) != 0) { - enable_disable(this, i, file, FALSE); + DBG1(DBG_CFG, "changing ClusterIP permissions failed: %s", + strerror(errno)); + } + active = get_active(this, file); + for (i = 1; i <= this->count; i++) + { + if (active & SEGMENTS_BIT(i)) + { + enable_disable(this, i, file, FALSE); + } } } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); } METHOD(ha_kernel_t, destroy, void, @@ -255,7 +356,7 @@ ha_kernel_t *ha_kernel_create(u_int count) .deactivate = _deactivate, .destroy = _destroy, }, - .initval = 0, + .version = get_jhash_version(), .count = count, ); diff --git a/src/libcharon/plugins/ha/ha_message.c b/src/libcharon/plugins/ha/ha_message.c index f98f78dd4..810109a5d 100644 --- a/src/libcharon/plugins/ha/ha_message.c +++ b/src/libcharon/plugins/ha/ha_message.c @@ -184,7 +184,7 @@ METHOD(ha_message_t, add_attribute, void, case HA_REMOTE_ADDR: case HA_LOCAL_VIP: case HA_REMOTE_VIP: - case HA_ADDITIONAL_ADDR: + case HA_PEER_ADDR: { host_encoding_t *enc; host_t *host; @@ -386,7 +386,7 @@ METHOD(enumerator_t, attribute_enumerate, bool, case HA_REMOTE_ADDR: case HA_LOCAL_VIP: case HA_REMOTE_VIP: - case HA_ADDITIONAL_ADDR: + case HA_PEER_ADDR: { host_encoding_t *enc; diff --git a/src/libcharon/plugins/ha/ha_message.h b/src/libcharon/plugins/ha/ha_message.h index 1f8eabd62..d0323d7a0 100644 --- a/src/libcharon/plugins/ha/ha_message.h +++ b/src/libcharon/plugins/ha/ha_message.h @@ -98,8 +98,8 @@ enum ha_message_attribute_t { HA_LOCAL_VIP, /** host_t*, remote virtual IP */ HA_REMOTE_VIP, - /** host_t*, additional MOBIKE peer address */ - HA_ADDITIONAL_ADDR, + /** host_t*, known peer addresses (used for MOBIKE) */ + HA_PEER_ADDR, /** u_int8_t, initiator of an exchange, TRUE for local */ HA_INITIATOR, /** chunk_t, initiators nonce */ diff --git a/src/libcharon/plugins/ha/ha_segments.c b/src/libcharon/plugins/ha/ha_segments.c index 7c7bef851..c5a180683 100644 --- a/src/libcharon/plugins/ha/ha_segments.c +++ b/src/libcharon/plugins/ha/ha_segments.c @@ -166,7 +166,8 @@ static void enable_disable(private_ha_segments_t *this, u_int segment, if (changes) { - enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager); + enumerator = charon->ike_sa_manager->create_enumerator( + charon->ike_sa_manager, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { if (ike_sa->get_state(ike_sa) != old) @@ -279,8 +280,8 @@ static job_requeue_t watchdog(private_ha_segments_t *this) */ static void start_watchdog(private_ha_segments_t *this) { - this->job = callback_job_create((callback_job_cb_t)watchdog, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)watchdog, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); } diff --git a/src/libcharon/plugins/ha/ha_segments.h b/src/libcharon/plugins/ha/ha_segments.h index eb9e5c1d5..76da38082 100644 --- a/src/libcharon/plugins/ha/ha_segments.h +++ b/src/libcharon/plugins/ha/ha_segments.h @@ -55,7 +55,7 @@ struct ha_segments_t { * Activate a set of IKE_SAs identified by a segment. * * @param segment numerical segment to takeover, 0 for all - * @param notify wheter to notify other nodes about activation + * @param notify whether to notify other nodes about activation */ void (*activate)(ha_segments_t *this, u_int segment, bool notify); @@ -63,7 +63,7 @@ struct ha_segments_t { * Deactivate a set of IKE_SAs identified by a segment. * * @param segment numerical segment to takeover, 0 for all - * @param notify wheter to notify other nodes about deactivation + * @param notify whether to notify other nodes about deactivation */ void (*deactivate)(ha_segments_t *this, u_int segment, bool notify); diff --git a/src/libcharon/plugins/ha/ha_socket.c b/src/libcharon/plugins/ha/ha_socket.c index 086178442..c02cf1021 100644 --- a/src/libcharon/plugins/ha/ha_socket.c +++ b/src/libcharon/plugins/ha/ha_socket.c @@ -105,8 +105,8 @@ METHOD(ha_socket_t, push, void, .fd = this->fd, ); - job = callback_job_create((callback_job_cb_t)send_message, - data, (void*)job_data_destroy, NULL); + job = callback_job_create_with_prio((callback_job_cb_t)send_message, + data, (void*)job_data_destroy, NULL, JOB_PRIO_HIGH); lib->processor->queue_job(lib->processor, (job_t*)job); return; } diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in index db3a7c702..56684ee11 100644 --- a/src/libcharon/plugins/led/Makefile.in +++ b/src/libcharon/plugins/led/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/led/led_listener.c b/src/libcharon/plugins/led/led_listener.c index 18def8005..4aae2abe5 100644 --- a/src/libcharon/plugins/led/led_listener.c +++ b/src/libcharon/plugins/led/led_listener.c @@ -156,9 +156,9 @@ static void blink_activity(private_led_listener_t *this) { set_led(this->activity, this->activity_max); } - lib->scheduler->schedule_job_ms(lib->scheduler, - (job_t*)callback_job_create((callback_job_cb_t)reset_activity_led, - this, NULL, NULL), this->blink_time); + lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*) + callback_job_create_with_prio((callback_job_cb_t)reset_activity_led, + this, NULL, NULL, JOB_PRIO_CRITICAL), this->blink_time); this->mutex->unlock(this->mutex); } } diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in index 1e9a5fe82..bbd20d4b9 100644 --- a/src/libcharon/plugins/load_tester/Makefile.in +++ b/src/libcharon/plugins/load_tester/Makefile.in @@ -197,6 +197,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -205,6 +208,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -221,11 +225,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -269,6 +275,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c index 71391d593..6bc6f91e4 100644 --- a/src/libcharon/plugins/load_tester/load_tester_config.c +++ b/src/libcharon/plugins/load_tester/load_tester_config.c @@ -65,6 +65,16 @@ struct private_load_tester_config_t { char *responder_auth; /** + * Initiator ID to enforce + */ + char *initiator_id; + + /** + * Responder ID to enforce + */ + char *responder_id; + + /** * IKE_SA rekeying delay */ u_int ike_rekey; @@ -75,6 +85,11 @@ struct private_load_tester_config_t { u_int child_rekey; /** + * DPD check delay + */ + u_int dpd_delay; + + /** * incremental numbering of generated configs */ u_int num; @@ -102,24 +117,46 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str, enumerator = enumerator_create_token(str, "|", " "); while (enumerator->enumerate(enumerator, &str)) { + id = NULL; auth = auth_cfg_create(); rnd++; - if (streq(str, "psk")) - { /* PSK authentication, use FQDNs */ - class = AUTH_CLASS_PSK; - if ((local && !num) || (!local && num)) + if (this->initiator_id) + { + if ((local && num) || (!local && !num)) { - id = identification_create_from_string("srv.strongswan.org"); + snprintf(buf, sizeof(buf), this->initiator_id, num, rnd); + id = identification_create_from_string(buf); } - else if (local) + } + if (this->responder_id) + { + if ((local && !num) || (!local && num)) { - snprintf(buf, sizeof(buf), "c%d-r%d.strongswan.org", num, rnd); + snprintf(buf, sizeof(buf), this->responder_id, num, rnd); id = identification_create_from_string(buf); } - else + } + + if (streq(str, "psk")) + { /* PSK authentication, use FQDNs */ + class = AUTH_CLASS_PSK; + if (!id) { - id = identification_create_from_string("*.strongswan.org"); + if ((local && !num) || (!local && num)) + { + id = identification_create_from_string("srv.strongswan.org"); + } + else if (local) + { + snprintf(buf, sizeof(buf), "c%d-r%d.strongswan.org", + num, rnd); + id = identification_create_from_string(buf); + } + else + { + id = identification_create_from_string("*.strongswan.org"); + } } } else if (strneq(str, "eap", strlen("eap"))) @@ -133,14 +170,18 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str, auth->add(auth, AUTH_RULE_EAP_TYPE, type); } } - if (local && num) + if (!id) { - snprintf(buf, sizeof(buf), "1%.10d%.4d@strongswan.org", num, rnd); - id = identification_create_from_string(buf); - } - else - { - id = identification_create_from_encoding(ID_ANY, chunk_empty); + if (local && num) + { + snprintf(buf, sizeof(buf), "1%.10d%.4d@strongswan.org", + num, rnd); + id = identification_create_from_string(buf); + } + else + { + id = identification_create_from_encoding(ID_ANY, chunk_empty); + } } } else @@ -152,21 +193,24 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str, } /* certificate authentication, use distinguished names */ class = AUTH_CLASS_PUBKEY; - if ((local && !num) || (!local && num)) - { - id = identification_create_from_string( - "CN=srv, OU=load-test, O=strongSwan"); - } - else if (local) + if (!id) { - snprintf(buf, sizeof(buf), - "CN=c%d-r%d, OU=load-test, O=strongSwan", num, rnd); - id = identification_create_from_string(buf); - } - else - { - id = identification_create_from_string( - "CN=*, OU=load-test, O=strongSwan"); + if ((local && !num) || (!local && num)) + { + id = identification_create_from_string( + "CN=srv, OU=load-test, O=strongSwan"); + } + else if (local) + { + snprintf(buf, sizeof(buf), + "CN=c%d-r%d, OU=load-test, O=strongSwan", num, rnd); + id = identification_create_from_string(buf); + } + else + { + id = identification_create_from_string( + "CN=*, OU=load-test, O=strongSwan"); + } } } auth->add(auth, AUTH_RULE_AUTH_CLASS, class); @@ -209,7 +253,7 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num) CERT_SEND_IF_ASKED, UNIQUE_NO, 1, /* keytries */ this->ike_rekey, 0, /* rekey, reauth */ 0, this->ike_rekey, /* jitter, overtime */ - FALSE, 0, /* mobike, dpddelay */ + FALSE, this->dpd_delay, /* mobike, dpddelay */ this->vip ? this->vip->clone(this->vip) : NULL, this->pool, FALSE, NULL, NULL); if (num) @@ -236,21 +280,15 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num) return peer_cfg; } -/** - * Implementation of backend_t.create_peer_cfg_enumerator. - */ -static enumerator_t* create_peer_cfg_enumerator(private_load_tester_config_t *this, - identification_t *me, - identification_t *other) +METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, + private_load_tester_config_t *this, + identification_t *me, identification_t *other) { return enumerator_create_single(this->peer_cfg, NULL); } -/** - * Implementation of backend_t.create_ike_cfg_enumerator. - */ -static enumerator_t* create_ike_cfg_enumerator(private_load_tester_config_t *this, - host_t *me, host_t *other) +METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, + private_load_tester_config_t *this, host_t *me, host_t *other) { ike_cfg_t *ike_cfg; @@ -258,11 +296,8 @@ static enumerator_t* create_ike_cfg_enumerator(private_load_tester_config_t *thi return enumerator_create_single(ike_cfg, NULL); } -/** - * implements backend_t.get_peer_cfg_by_name. - */ -static peer_cfg_t *get_peer_cfg_by_name(private_load_tester_config_t *this, - char *name) +METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*, + private_load_tester_config_t *this, char *name) { if (streq(name, "load-test")) { @@ -271,10 +306,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_load_tester_config_t *this, return NULL; } -/** - * Implementation of load_tester_config_t.destroy. - */ -static void destroy(private_load_tester_config_t *this) +METHOD(load_tester_config_t, destroy, void, + private_load_tester_config_t *this) { this->peer_cfg->destroy(this->peer_cfg); DESTROY_IF(this->proposal); @@ -287,14 +320,20 @@ static void destroy(private_load_tester_config_t *this) */ load_tester_config_t *load_tester_config_create() { - private_load_tester_config_t *this = malloc_thing(private_load_tester_config_t); - - this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator; - this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator; - this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name; - this->public.destroy = (void(*)(load_tester_config_t*))destroy; + private_load_tester_config_t *this; + + INIT(this, + .public = { + .backend = { + .create_peer_cfg_enumerator = _create_peer_cfg_enumerator, + .create_ike_cfg_enumerator = _create_ike_cfg_enumerator, + .get_peer_cfg_by_name = _get_peer_cfg_by_name, + }, + .destroy = _destroy, + }, + .num = 1, + ); - this->vip = NULL; if (lib->settings->get_bool(lib->settings, "charon.plugins.load-tester.request_virtual_ip", FALSE)) { @@ -317,16 +356,21 @@ load_tester_config_t *load_tester_config_create() "charon.plugins.load-tester.ike_rekey", 0); this->child_rekey = lib->settings->get_int(lib->settings, "charon.plugins.load-tester.child_rekey", 600); + this->dpd_delay = lib->settings->get_int(lib->settings, + "charon.plugins.load-tester.dpd_delay", 0); this->initiator_auth = lib->settings->get_str(lib->settings, "charon.plugins.load-tester.initiator_auth", "pubkey"); this->responder_auth = lib->settings->get_str(lib->settings, "charon.plugins.load-tester.responder_auth", "pubkey"); + this->initiator_id = lib->settings->get_str(lib->settings, + "charon.plugins.load-tester.initiator_id", NULL); + this->responder_id = lib->settings->get_str(lib->settings, + "charon.plugins.load-tester.responder_id", NULL); this->port = lib->settings->get_int(lib->settings, "charon.plugins.load-tester.dynamic_port", 0); - this->num = 1; this->peer_cfg = generate_config(this, 0); return &this->public; diff --git a/src/libcharon/plugins/load_tester/load_tester_creds.c b/src/libcharon/plugins/load_tester/load_tester_creds.c index 890703c1a..c34ea73c5 100644 --- a/src/libcharon/plugins/load_tester/load_tester_creds.c +++ b/src/libcharon/plugins/load_tester/load_tester_creds.c @@ -49,9 +49,14 @@ struct private_load_tester_creds_t { u_int32_t serial; /** - * Preshared key + * Preshared key for IKE */ - shared_key_t *shared; + shared_key_t *psk; + + /** + * Password for EAP + */ + shared_key_t *pwd; }; /** @@ -131,7 +136,7 @@ CwMLbJ7vQqwPHXRitDmNkEOK9H+vRnDf -----END CERTIFICATE----- */ -char cert[] = { +static char cert[] = { 0x30,0x82,0x01,0xf4,0x30,0x82,0x01,0x5d,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30, 0x37,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x03,0x13,0x03,0x73,0x72,0x76,0x31, @@ -168,17 +173,17 @@ char cert[] = { /** - * A preshared key + * Default IKE preshared key */ -static char psk[] = { - 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08 -}; +static char *default_psk = "default-psk"; /** - * Implements credential_set_t.create_private_enumerator + * Default EAP password for EAP */ -static enumerator_t* create_private_enumerator(private_load_tester_creds_t *this, - key_type_t type, identification_t *id) +static char *default_pwd = "default-pwd"; + +METHOD(credential_set_t, create_private_enumerator, enumerator_t*, + private_load_tester_creds_t *this, key_type_t type, identification_t *id) { if (this->private == NULL) { @@ -198,12 +203,9 @@ static enumerator_t* create_private_enumerator(private_load_tester_creds_t *this return enumerator_create_single(this->private, NULL); } -/** - * Implements credential_set_t.create_cert_enumerator - */ -static enumerator_t* create_cert_enumerator(private_load_tester_creds_t *this, - certificate_type_t cert, key_type_t key, - identification_t *id, bool trusted) +METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, + private_load_tester_creds_t *this, certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) { certificate_t *peer_cert; public_key_t *peer_key, *ca_key; @@ -265,49 +267,87 @@ static enumerator_t* create_cert_enumerator(private_load_tester_creds_t *this, } /** - * Implements credential_set_t.create_shared_enumerator + * Filter function for shared keys, returning ID matches */ -static enumerator_t* create_shared_enumerator(private_load_tester_creds_t *this, - shared_key_type_t type, identification_t *me, - identification_t *other) +static bool shared_filter(void *null, shared_key_t **in, shared_key_t **out, + void **un1, id_match_t *me, void **un2, id_match_t *other) +{ + *out = *in; + if (me) + { + *me = ID_MATCH_ANY; + } + if (other) + { + *other = ID_MATCH_ANY; + } + return TRUE; +} + +METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, + private_load_tester_creds_t *this, shared_key_type_t type, + identification_t *me, identification_t *other) { - return enumerator_create_single(this->shared, NULL); + shared_key_t *shared; + + switch (type) + { + case SHARED_IKE: + shared = this->psk; + break; + case SHARED_EAP: + shared = this->pwd; + break; + default: + return NULL; + } + return enumerator_create_filter(enumerator_create_single(shared, NULL), + (void*)shared_filter, NULL, NULL); } -/** - * Implementation of load_tester_creds_t.destroy - */ -static void destroy(private_load_tester_creds_t *this) +METHOD(load_tester_creds_t, destroy, void, + private_load_tester_creds_t *this) { DESTROY_IF(this->private); DESTROY_IF(this->ca); - this->shared->destroy(this->shared); + this->psk->destroy(this->psk); + this->pwd->destroy(this->pwd); free(this); } load_tester_creds_t *load_tester_creds_create() { - private_load_tester_creds_t *this = malloc_thing(private_load_tester_creds_t); - - this->public.credential_set.create_shared_enumerator = (enumerator_t*(*)(credential_set_t*, shared_key_type_t, identification_t*, identification_t*))create_shared_enumerator; - this->public.credential_set.create_private_enumerator = (enumerator_t*(*) (credential_set_t*, key_type_t, identification_t*))create_private_enumerator; - this->public.credential_set.create_cert_enumerator = (enumerator_t*(*) (credential_set_t*, certificate_type_t, key_type_t,identification_t *, bool))create_cert_enumerator; - this->public.credential_set.create_cdp_enumerator = (enumerator_t*(*) (credential_set_t *,certificate_type_t, identification_t *))return_null; - this->public.credential_set.cache_cert = (void (*)(credential_set_t *, certificate_t *))nop; - this->public.destroy = (void(*) (load_tester_creds_t*))destroy; - - this->private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, - BUILD_BLOB_ASN1_DER, chunk_create(private, sizeof(private)), - BUILD_END); + private_load_tester_creds_t *this; + char *pwd, *psk; - this->ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, - BUILD_BLOB_ASN1_DER, chunk_create(cert, sizeof(cert)), - BUILD_X509_FLAG, X509_CA, - BUILD_END); + psk = lib->settings->get_str(lib->settings, + "charon.plugins.load-tester.preshared_key", default_psk); + pwd = lib->settings->get_str(lib->settings, + "charon.plugins.load-tester.eap_password", default_pwd); - this->shared = shared_key_create(SHARED_IKE, - chunk_clone(chunk_create(psk, sizeof(psk)))); - this->serial = 0; + INIT(this, + .public = { + .credential_set = { + .create_shared_enumerator = _create_shared_enumerator, + .create_private_enumerator = _create_private_enumerator, + .create_cert_enumerator = _create_cert_enumerator, + .create_cdp_enumerator = (void*)return_null, + .cache_cert = (void*)nop, + }, + .destroy = _destroy, + }, + .private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + BUILD_BLOB_ASN1_DER, chunk_create(private, sizeof(private)), + BUILD_END), + .ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_BLOB_ASN1_DER, chunk_create(cert, sizeof(cert)), + BUILD_X509_FLAG, X509_CA, + BUILD_END), + .psk = shared_key_create(SHARED_IKE, + chunk_clone(chunk_create(psk, strlen(psk)))), + .pwd = shared_key_create(SHARED_EAP, + chunk_clone(chunk_create(pwd, strlen(pwd)))), + ); return &this->public; } diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c index fdec5300e..440197260 100644 --- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c +++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c @@ -35,75 +35,75 @@ struct private_load_tester_ipsec_t { }; METHOD(kernel_ipsec_t, get_spi, status_t, - private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) + private_load_tester_ipsec_t *this, host_t *src, host_t *dst, + u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) { *spi = ++this->spi; return SUCCESS; } METHOD(kernel_ipsec_t, get_cpi, status_t, - private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) + private_load_tester_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t reqid, u_int16_t *cpi) { return FAILED; } METHOD(kernel_ipsec_t, add_sa, status_t, - private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark, - u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, - u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, - u_int16_t cpi, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + private_load_tester_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark, + u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, + u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, + u_int16_t cpi, bool encap, bool esn, bool inbound, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts) { return SUCCESS; } METHOD(kernel_ipsec_t, update_sa, status_t, - private_load_tester_ipsec_t *this, u_int32_t spi, u_int8_t protocol, - u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, - host_t *new_dst, bool encap, bool new_encap, mark_t mark) + private_load_tester_ipsec_t *this, u_int32_t spi, u_int8_t protocol, + u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, + host_t *new_dst, bool encap, bool new_encap, mark_t mark) { return SUCCESS; } METHOD(kernel_ipsec_t, query_sa, status_t, - private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, u_int8_t protocol, mark_t mark, u_int64_t *bytes) + private_load_tester_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, mark_t mark, u_int64_t *bytes) { return NOT_SUPPORTED; } METHOD(kernel_ipsec_t, del_sa, status_t, - private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark) + private_load_tester_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark) { return SUCCESS; } METHOD(kernel_ipsec_t, add_policy, status_t, - private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts, - policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, - mark_t mark, bool routed) + private_load_tester_ipsec_t *this, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, + mark_t mark, policy_priority_t priority) { return SUCCESS; } METHOD(kernel_ipsec_t, query_policy, status_t, - private_load_tester_ipsec_t *this, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, - u_int32_t *use_time) + private_load_tester_ipsec_t *this, traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, + u_int32_t *use_time) { - *use_time = time_monotonic(NULL); + *use_time = 1; return SUCCESS; } METHOD(kernel_ipsec_t, del_policy, status_t, - private_load_tester_ipsec_t *this, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, - bool unrouted) + private_load_tester_ipsec_t *this, traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid, + mark_t mark, policy_priority_t priority) { return SUCCESS; } @@ -115,7 +115,7 @@ METHOD(kernel_ipsec_t, bypass_socket, bool, } METHOD(kernel_ipsec_t, destroy, void, - private_load_tester_ipsec_t *this) + private_load_tester_ipsec_t *this) { free(this); } @@ -136,9 +136,11 @@ load_tester_ipsec_t *load_tester_ipsec_create() .update_sa = _update_sa, .query_sa = _query_sa, .del_sa = _del_sa, + .flush_sas = (void*)return_failed, .add_policy = _add_policy, .query_policy = _query_policy, .del_policy = _del_policy, + .flush_policies = (void*)return_failed, .bypass_socket = _bypass_socket, .destroy = _destroy, }, diff --git a/src/libcharon/plugins/load_tester/load_tester_listener.c b/src/libcharon/plugins/load_tester/load_tester_listener.c index cf6dd0562..7c96f7d97 100644 --- a/src/libcharon/plugins/load_tester/load_tester_listener.c +++ b/src/libcharon/plugins/load_tester/load_tester_listener.c @@ -42,21 +42,25 @@ struct private_load_tester_listener_t { u_int established; /** + * Number of terminated SAs + */ + u_int terminated; + + /** * Shutdown the daemon if we have established this SA count */ u_int shutdown_on; }; -/** - * Implementation of listener_t.ike_state_change - */ -static bool ike_state_change(private_load_tester_listener_t *this, - ike_sa_t *ike_sa, ike_sa_state_t state) +METHOD(listener_t, ike_updown, bool, + private_load_tester_listener_t *this, ike_sa_t *ike_sa, bool up) { - if (state == IKE_ESTABLISHED) + if (up) { ike_sa_id_t *id = ike_sa->get_id(ike_sa); + this->established++; + if (this->delete_after_established) { lib->processor->queue_job(lib->processor, @@ -65,37 +69,48 @@ static bool ike_state_change(private_load_tester_listener_t *this, if (id->is_initiator(id)) { - if (this->shutdown_on == ++this->established) + if (this->shutdown_on == this->established) { DBG1(DBG_CFG, "load-test complete, raising SIGTERM"); kill(0, SIGTERM); } } } + else + { + this->terminated++; + } return TRUE; } -/** - * Implementation of load_tester_listener_t.destroy - */ -static void destroy(private_load_tester_listener_t *this) +METHOD(load_tester_listener_t, get_established, u_int, + private_load_tester_listener_t *this) +{ + return this->established - this->terminated; +} + +METHOD(load_tester_listener_t, destroy, void, + private_load_tester_listener_t *this) { free(this); } load_tester_listener_t *load_tester_listener_create(u_int shutdown_on) { - private_load_tester_listener_t *this = malloc_thing(private_load_tester_listener_t); - - memset(&this->public.listener, 0, sizeof(listener_t)); - this->public.listener.ike_state_change = (void*)ike_state_change; - this->public.destroy = (void(*) (load_tester_listener_t*))destroy; - - this->delete_after_established = lib->settings->get_bool(lib->settings, - "charon.plugins.load-tester.delete_after_established", FALSE); - - this->shutdown_on = shutdown_on; - this->established = 0; + private_load_tester_listener_t *this; + + INIT(this, + .public = { + .listener = { + .ike_updown = _ike_updown, + }, + .get_established = _get_established, + .destroy = _destroy, + }, + .delete_after_established = lib->settings->get_bool(lib->settings, + "charon.plugins.load-tester.delete_after_established", FALSE), + .shutdown_on = shutdown_on, + ); return &this->public; } diff --git a/src/libcharon/plugins/load_tester/load_tester_listener.h b/src/libcharon/plugins/load_tester/load_tester_listener.h index b9599294c..2621798c8 100644 --- a/src/libcharon/plugins/load_tester/load_tester_listener.h +++ b/src/libcharon/plugins/load_tester/load_tester_listener.h @@ -36,6 +36,13 @@ struct load_tester_listener_t { listener_t listener; /** + * Get the number of established IKE_SAs. + * + * @return number of SAs currently established + */ + u_int (*get_established)(load_tester_listener_t *this); + + /** * Destroy the backend. */ void (*destroy)(load_tester_listener_t *this); diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c index 94115e307..b260a9741 100644 --- a/src/libcharon/plugins/load_tester/load_tester_plugin.c +++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c @@ -68,7 +68,7 @@ struct private_load_tester_plugin_t { int initiators; /** - * currenly running initiators + * currently running initiators */ int running; @@ -78,6 +78,11 @@ struct private_load_tester_plugin_t { int delay; /** + * Throttle initiation if half-open IKE_SA count reached + */ + int init_limit; + + /** * mutex to lock running field */ mutex_t *mutex; @@ -96,10 +101,7 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this) int i, s = 0, ms = 0; this->mutex->lock(this->mutex); - if (!this->running) - { - this->running = this->initiators; - } + this->running++; this->mutex->unlock(this->mutex); if (this->delay) { @@ -113,6 +115,23 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this) child_cfg_t *child_cfg = NULL; enumerator_t *enumerator; + if (this->init_limit) + { + while ((charon->ike_sa_manager->get_count(charon->ike_sa_manager) - + this->listener->get_established(this->listener)) > + this->init_limit) + { + if (s) + { + sleep(s); + } + if (ms) + { + usleep(ms * 1000); + } + } + } + peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, "load-test"); if (!peer_cfg) @@ -129,7 +148,7 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this) charon->controller->initiate(charon->controller, peer_cfg, child_cfg->get_ref(child_cfg), - NULL, NULL); + NULL, NULL, 0); if (s) { sleep(s); @@ -141,8 +160,8 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this) } this->mutex->lock(this->mutex); this->running--; - this->mutex->unlock(this->mutex); this->condvar->signal(this->condvar); + this->mutex->unlock(this->mutex); return JOB_REQUEUE_NONE; } @@ -206,25 +225,26 @@ plugin_t *load_tester_plugin_create() "charon.plugins.load-tester.iterations", 1), .initiators = lib->settings->get_int(lib->settings, "charon.plugins.load-tester.initiators", 0), + .init_limit = lib->settings->get_int(lib->settings, + "charon.plugins.load-tester.init_limit", 0), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), .config = load_tester_config_create(), .creds = load_tester_creds_create(), - .listener = load_tester_listener_create(shutdown_on), ); lib->crypto->add_dh(lib->crypto, MODP_NULL, plugin_name, (dh_constructor_t)load_tester_diffie_hellman_create); charon->backends->add_backend(charon->backends, &this->config->backend); lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set); - charon->bus->add_listener(charon->bus, &this->listener->listener); if (lib->settings->get_bool(lib->settings, "charon.plugins.load-tester.shutdown_when_complete", 0)) { shutdown_on = this->iterations * this->initiators; } - + this->listener = load_tester_listener_create(shutdown_on); + charon->bus->add_listener(charon->bus, &this->listener->listener); if (lib->settings->get_bool(lib->settings, "charon.plugins.load-tester.fake_kernel", FALSE)) @@ -232,12 +252,11 @@ plugin_t *load_tester_plugin_create() hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface, (kernel_ipsec_constructor_t)load_tester_ipsec_create); } - this->running = 0; for (i = 0; i < this->initiators; i++) { - lib->processor->queue_job(lib->processor, - (job_t*)callback_job_create((callback_job_cb_t)do_load_test, - this, NULL, NULL)); + lib->processor->queue_job(lib->processor, (job_t*) + callback_job_create_with_prio((callback_job_cb_t)do_load_test, + this, NULL, NULL, JOB_PRIO_CRITICAL)); } return &this->public.plugin; } diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in index 27e72295c..d2b9d9a34 100644 --- a/src/libcharon/plugins/maemo/Makefile.in +++ b/src/libcharon/plugins/maemo/Makefile.in @@ -196,6 +196,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -204,6 +207,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -220,11 +224,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -268,6 +274,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/maemo/maemo_service.c b/src/libcharon/plugins/maemo/maemo_service.c index 0e9fd8ccc..6675e1d21 100644 --- a/src/libcharon/plugins/maemo/maemo_service.c +++ b/src/libcharon/plugins/maemo/maemo_service.c @@ -217,7 +217,7 @@ static void disconnect(private_maemo_service_t *this) id = ike_sa->get_unique_id(ike_sa); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); charon->controller->terminate_ike(charon->controller, id, - NULL, NULL); + NULL, NULL, 0); } this->current = (g_free(this->current), NULL); this->status = VPN_STATUS_DISCONNECTED; @@ -502,7 +502,8 @@ maemo_service_t *maemo_service_create() } lib->processor->queue_job(lib->processor, - (job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL)); + (job_t*)callback_job_create_with_prio((callback_job_cb_t)run, + this, NULL, NULL, JOB_PRIO_CRITICAL)); return &this->public; } diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in index 83b457b46..b8983ad21 100644 --- a/src/libcharon/plugins/medcli/Makefile.in +++ b/src/libcharon/plugins/medcli/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c index b5672dba9..ee3e95422 100644 --- a/src/libcharon/plugins/medcli/medcli_config.c +++ b/src/libcharon/plugins/medcli/medcli_config.c @@ -88,10 +88,8 @@ static traffic_selector_t *ts_from_string(char *str) return traffic_selector_create_dynamic(0, 0, 65535); } -/** - * implements backend_t.get_peer_cfg_by_name. - */ -static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *name) +METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*, + private_medcli_config_t *this, char *name) { enumerator_t *e; peer_cfg_t *peer_cfg, *med_cfg; @@ -192,11 +190,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam return peer_cfg; } -/** - * Implementation of backend_t.create_ike_cfg_enumerator. - */ -static enumerator_t* create_ike_cfg_enumerator(private_medcli_config_t *this, - host_t *me, host_t *other) +METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, + private_medcli_config_t *this, host_t *me, host_t *other) { return enumerator_create_single(this->ike, NULL); } @@ -216,10 +211,8 @@ typedef struct { int dpd; } peer_enumerator_t; -/** - * Implementation of peer_enumerator_t.public.enumerate - */ -static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) +METHOD(enumerator_t, peer_enumerator_enumerate, bool, + peer_enumerator_t *this, peer_cfg_t **cfg) { char *name, *local_net, *remote_net; chunk_t me, other; @@ -271,31 +264,29 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) return TRUE; } -/** - * Implementation of peer_enumerator_t.public.destroy - */ -static void peer_enumerator_destroy(peer_enumerator_t *this) +METHOD(enumerator_t, peer_enumerator_destroy, void, + peer_enumerator_t *this) { DESTROY_IF(this->current); this->inner->destroy(this->inner); free(this); } -/** - * Implementation of backend_t.create_peer_cfg_enumerator. - */ -static enumerator_t* create_peer_cfg_enumerator(private_medcli_config_t *this, - identification_t *me, - identification_t *other) +METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, + private_medcli_config_t *this, identification_t *me, + identification_t *other) { - peer_enumerator_t *e = malloc_thing(peer_enumerator_t); - - e->current = NULL; - e->ike = this->ike; - e->rekey = this->rekey; - e->dpd = this->dpd; - e->public.enumerate = (void*)peer_enumerator_enumerate; - e->public.destroy = (void*)peer_enumerator_destroy; + peer_enumerator_t *e; + + INIT(e, + .public = { + .enumerate = (void*)_peer_enumerator_enumerate, + .destroy = _peer_enumerator_destroy, + }, + .ike = this->ike, + .rekey = this->rekey, + .dpd = this->dpd, + ); /* filter on IDs: NULL or ANY or matching KEY_ID */ e->inner = this->db->query(this->db, @@ -335,7 +326,7 @@ static job_requeue_t initiate_config(peer_cfg_t *peer_cfg) peer_cfg->get_ref(peer_cfg); enumerator->destroy(enumerator); charon->controller->initiate(charon->controller, - peer_cfg, child_cfg, NULL, NULL); + peer_cfg, child_cfg, NULL, NULL, 0); } else { @@ -345,7 +336,7 @@ static job_requeue_t initiate_config(peer_cfg_t *peer_cfg) } /** - * schedule initation of all "active" connections + * schedule initiation of all "active" connections */ static void schedule_autoinit(private_medcli_config_t *this) { @@ -374,10 +365,8 @@ static void schedule_autoinit(private_medcli_config_t *this) } } -/** - * Implementation of medcli_config_t.destroy. - */ -static void destroy(private_medcli_config_t *this) +METHOD(medcli_config_t, destroy, void, + private_medcli_config_t *this) { this->ike->destroy(this->ike); free(this); @@ -388,18 +377,23 @@ static void destroy(private_medcli_config_t *this) */ medcli_config_t *medcli_config_create(database_t *db) { - private_medcli_config_t *this = malloc_thing(private_medcli_config_t); - - this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator; - this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator; - this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name; - this->public.destroy = (void(*)(medcli_config_t*))destroy; - - this->db = db; - this->rekey = lib->settings->get_time(lib->settings, "medcli.rekey", 1200); - this->dpd = lib->settings->get_time(lib->settings, "medcli.dpd", 300); - this->ike = ike_cfg_create(FALSE, FALSE, - "0.0.0.0", IKEV2_UDP_PORT, "0.0.0.0", IKEV2_UDP_PORT); + private_medcli_config_t *this; + + INIT(this, + .public = { + .backend = { + .create_peer_cfg_enumerator = _create_peer_cfg_enumerator, + .create_ike_cfg_enumerator = _create_ike_cfg_enumerator, + .get_peer_cfg_by_name = _get_peer_cfg_by_name, + }, + .destroy = _destroy, + }, + .db = db, + .rekey = lib->settings->get_time(lib->settings, "medcli.rekey", 1200), + .dpd = lib->settings->get_time(lib->settings, "medcli.dpd", 300), + .ike = ike_cfg_create(FALSE, FALSE, "0.0.0.0", IKEV2_UDP_PORT, + "0.0.0.0", IKEV2_UDP_PORT), + ); this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE)); schedule_autoinit(this); diff --git a/src/libcharon/plugins/medcli/medcli_creds.c b/src/libcharon/plugins/medcli/medcli_creds.c index 9729df3f5..9c4a0b756 100644 --- a/src/libcharon/plugins/medcli/medcli_creds.c +++ b/src/libcharon/plugins/medcli/medcli_creds.c @@ -49,11 +49,8 @@ typedef struct { private_key_t *current; } private_enumerator_t; -/** - * Implementation of private_enumerator_t.public.enumerate - */ -static bool private_enumerator_enumerate(private_enumerator_t *this, - private_key_t **key) +METHOD(enumerator_t, private_enumerator_enumerate, bool, + private_enumerator_t *this, private_key_t **key) { chunk_t chunk; @@ -73,21 +70,16 @@ static bool private_enumerator_enumerate(private_enumerator_t *this, return FALSE; } -/** - * Implementation of private_enumerator_t.public.destroy - */ -static void private_enumerator_destroy(private_enumerator_t *this) +METHOD(enumerator_t, private_enumerator_destroy, void, + private_enumerator_t *this) { DESTROY_IF(this->current); this->inner->destroy(this->inner); free(this); } -/** - * Implementation of credential_set_t.create_private_enumerator. - */ -static enumerator_t* create_private_enumerator(private_medcli_creds_t *this, - key_type_t type, identification_t *id) +METHOD(credential_set_t, create_private_enumerator, enumerator_t*, + private_medcli_creds_t *this, key_type_t type, identification_t *id) { private_enumerator_t *e; @@ -98,10 +90,12 @@ static enumerator_t* create_private_enumerator(private_medcli_creds_t *this, return NULL; } - e = malloc_thing(private_enumerator_t); - e->current = NULL; - e->public.enumerate = (void*)private_enumerator_enumerate; - e->public.destroy = (void*)private_enumerator_destroy; + INIT(e, + .public = { + .enumerate = (void*)_private_enumerator_enumerate, + .destroy = _private_enumerator_destroy, + }, + ); e->inner = this->db->query(this->db, "SELECT PrivateKey FROM ClientConfig WHERE KeyId = ?", DB_BLOB, id->get_encoding(id), @@ -128,11 +122,8 @@ typedef struct { key_type_t type; } cert_enumerator_t; -/** - * Implementation of cert_enumerator_t.public.enumerate - */ -static bool cert_enumerator_enumerate(cert_enumerator_t *this, - certificate_t **cert) +METHOD(enumerator_t, cert_enumerator_enumerate, bool, + cert_enumerator_t *this, certificate_t **cert) { public_key_t *public; chunk_t chunk; @@ -167,22 +158,17 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this, return FALSE; } -/** - * Implementation of cert_enumerator_t.public.destroy - */ -static void cert_enumerator_destroy(cert_enumerator_t *this) +METHOD(enumerator_t, cert_enumerator_destroy, void, + cert_enumerator_t *this) { DESTROY_IF(this->current); this->inner->destroy(this->inner); free(this); } -/** - * Implementation of credential_set_t.create_cert_enumerator. - */ -static enumerator_t* create_cert_enumerator(private_medcli_creds_t *this, - certificate_type_t cert, key_type_t key, - identification_t *id, bool trusted) +METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, + private_medcli_creds_t *this, certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) { cert_enumerator_t *e; @@ -192,11 +178,13 @@ static enumerator_t* create_cert_enumerator(private_medcli_creds_t *this, return NULL; } - e = malloc_thing(cert_enumerator_t); - e->current = NULL; - e->type = key; - e->public.enumerate = (void*)cert_enumerator_enumerate; - e->public.destroy = (void*)cert_enumerator_destroy; + INIT(e, + .public = { + .enumerate = (void*)_cert_enumerator_enumerate, + .destroy = _cert_enumerator_destroy, + }, + .type = key, + ); e->inner = this->db->query(this->db, "SELECT PublicKey FROM ClientConfig WHERE KeyId = ? UNION " "SELECT PublicKey FROM MediationServerConfig WHERE KeyId = ? UNION " @@ -213,10 +201,8 @@ static enumerator_t* create_cert_enumerator(private_medcli_creds_t *this, return &e->public; } -/** - * Implementation of backend_t.destroy. - */ -static void destroy(private_medcli_creds_t *this) +METHOD(medcli_creds_t, destroy, void, + private_medcli_creds_t *this) { free(this); } @@ -226,17 +212,21 @@ static void destroy(private_medcli_creds_t *this) */ medcli_creds_t *medcli_creds_create(database_t *db) { - private_medcli_creds_t *this = malloc_thing(private_medcli_creds_t); - - this->public.set.create_private_enumerator = (void*)create_private_enumerator; - this->public.set.create_cert_enumerator = (void*)create_cert_enumerator; - this->public.set.create_shared_enumerator = (void*)return_null; - this->public.set.create_cdp_enumerator = (void*)return_null; - this->public.set.cache_cert = (void*)nop; - - this->public.destroy = (void (*)(medcli_creds_t*))destroy; - - this->db = db; + private_medcli_creds_t *this; + + INIT(this, + .public = { + .set = { + .create_private_enumerator = _create_private_enumerator, + .create_cert_enumerator = _create_cert_enumerator, + .create_shared_enumerator = (void*)return_null, + .create_cdp_enumerator = (void*)return_null, + .cache_cert = (void*)nop, + }, + .destroy = _destroy, + }, + .db = db, + ); return &this->public; } diff --git a/src/libcharon/plugins/medcli/medcli_listener.c b/src/libcharon/plugins/medcli/medcli_listener.c index 142f02e6c..ba6b3d9d6 100644 --- a/src/libcharon/plugins/medcli/medcli_listener.c +++ b/src/libcharon/plugins/medcli/medcli_listener.c @@ -47,7 +47,7 @@ struct private_medcli_listener_t { }; /** - * Implementation of bus_listener_t.signal. + * Update connection status in the database */ static void set_state(private_medcli_listener_t *this, char *alias, mediated_state_t state) @@ -56,11 +56,9 @@ static void set_state(private_medcli_listener_t *this, char *alias, "UPDATE Connection SET Status = ? WHERE Alias = ?", DB_UINT, state, DB_TEXT, alias); } -/** - * Implementation of listener_t.ike_state_change - */ -static bool ike_state_change(private_medcli_listener_t *this, - ike_sa_t *ike_sa, ike_sa_state_t state) + +METHOD(listener_t, ike_state_change, bool, + private_medcli_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state) { if (ike_sa) { @@ -78,11 +76,9 @@ static bool ike_state_change(private_medcli_listener_t *this, return TRUE; } -/** - * Implementation of listener_t.child_state_change - */ -static bool child_state_change(private_medcli_listener_t *this, - ike_sa_t *ike_sa, child_sa_t *child_sa, child_sa_state_t state) +METHOD(listener_t, child_state_change, bool, + private_medcli_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + child_sa_state_t state) { if (ike_sa && child_sa) { @@ -101,10 +97,8 @@ static bool child_state_change(private_medcli_listener_t *this, return TRUE; } -/** - * Implementation of backend_t.destroy. - */ -static void destroy(private_medcli_listener_t *this) +METHOD(medcli_listener_t, destroy, void, + private_medcli_listener_t *this) { this->db->execute(this->db, NULL, "UPDATE Connection SET Status = ?", DB_UINT, STATE_DOWN); @@ -116,15 +110,19 @@ static void destroy(private_medcli_listener_t *this) */ medcli_listener_t *medcli_listener_create(database_t *db) { - private_medcli_listener_t *this = malloc_thing(private_medcli_listener_t); - - memset(&this->public.listener, 0, sizeof(listener_t)); - - this->public.listener.ike_state_change = (void*)ike_state_change; - this->public.listener.child_state_change = (void*)child_state_change; - this->public.destroy = (void (*)(medcli_listener_t*))destroy; + private_medcli_listener_t *this; + + INIT(this, + .public = { + .listener = { + .ike_state_change = _ike_state_change, + .child_state_change = _child_state_change, + }, + .destroy = _destroy, + }, + .db = db, + ); - this->db = db; db->execute(db, NULL, "UPDATE Connection SET Status = ?", DB_UINT, STATE_DOWN); diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in index 068f311a5..91df95cf0 100644 --- a/src/libcharon/plugins/medsrv/Makefile.in +++ b/src/libcharon/plugins/medsrv/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/medsrv/medsrv_config.c b/src/libcharon/plugins/medsrv/medsrv_config.c index c23955ad0..6cacb34f6 100644 --- a/src/libcharon/plugins/medsrv/medsrv_config.c +++ b/src/libcharon/plugins/medsrv/medsrv_config.c @@ -52,29 +52,21 @@ struct private_medsrv_config_t { ike_cfg_t *ike; }; -/** - * implements backend_t.get_peer_cfg_by_name. - */ -static peer_cfg_t *get_peer_cfg_by_name(private_medsrv_config_t *this, char *name) +METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*, + private_medsrv_config_t *this, char *name) { return NULL; } -/** - * Implementation of backend_t.create_ike_cfg_enumerator. - */ -static enumerator_t* create_ike_cfg_enumerator(private_medsrv_config_t *this, - host_t *me, host_t *other) +METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, + private_medsrv_config_t *this, host_t *me, host_t *other) { return enumerator_create_single(this->ike, NULL); } -/** - * Implementation of backend_t.create_peer_cfg_enumerator. - */ -static enumerator_t* create_peer_cfg_enumerator(private_medsrv_config_t *this, - identification_t *me, - identification_t *other) +METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, + private_medsrv_config_t *this, identification_t *me, + identification_t *other) { enumerator_t *e; @@ -98,11 +90,11 @@ static enumerator_t* create_peer_cfg_enumerator(private_medsrv_config_t *this, peer_cfg = peer_cfg_create( name, 2, this->ike->get_ref(this->ike), CERT_NEVER_SEND, UNIQUE_REPLACE, - 1, this->rekey*60, 0, /* keytries, rekey, reauth */ - this->rekey*5, this->rekey*3, /* jitter, overtime */ - TRUE, this->dpd, /* mobike, dpddelay */ - NULL, NULL, /* vip, pool */ - TRUE, NULL, NULL); /* mediation, med by, peer id */ + 1, this->rekey*60, 0, /* keytries, rekey, reauth */ + this->rekey*5, this->rekey*3, /* jitter, overtime */ + TRUE, this->dpd, /* mobike, dpddelay */ + NULL, NULL, /* vip, pool */ + TRUE, NULL, NULL); /* mediation, med by, peer id */ e->destroy(e); auth = auth_cfg_create(); @@ -121,10 +113,8 @@ static enumerator_t* create_peer_cfg_enumerator(private_medsrv_config_t *this, return NULL; } -/** - * Implementation of medsrv_config_t.destroy. - */ -static void destroy(private_medsrv_config_t *this) +METHOD(medsrv_config_t, destroy, void, + private_medsrv_config_t *this) { this->ike->destroy(this->ike); free(this); @@ -135,18 +125,23 @@ static void destroy(private_medsrv_config_t *this) */ medsrv_config_t *medsrv_config_create(database_t *db) { - private_medsrv_config_t *this = malloc_thing(private_medsrv_config_t); - - this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator; - this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator; - this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name; - this->public.destroy = (void(*)(medsrv_config_t*))destroy; - - this->db = db; - this->rekey = lib->settings->get_time(lib->settings, "medsrv.rekey", 1200); - this->dpd = lib->settings->get_time(lib->settings, "medsrv.dpd", 300); - this->ike = ike_cfg_create(FALSE, FALSE, - "0.0.0.0", IKEV2_UDP_PORT, "0.0.0.0", IKEV2_UDP_PORT); + private_medsrv_config_t *this; + + INIT(this, + .public = { + .backend = { + .create_peer_cfg_enumerator = _create_peer_cfg_enumerator, + .create_ike_cfg_enumerator = _create_ike_cfg_enumerator, + .get_peer_cfg_by_name = _get_peer_cfg_by_name, + }, + .destroy = _destroy, + }, + .db = db, + .rekey = lib->settings->get_time(lib->settings, "medsrv.rekey", 1200), + .dpd = lib->settings->get_time(lib->settings, "medsrv.dpd", 300), + .ike = ike_cfg_create(FALSE, FALSE, + "0.0.0.0", IKEV2_UDP_PORT, "0.0.0.0", IKEV2_UDP_PORT), + ); this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE)); return &this->public; diff --git a/src/libcharon/plugins/medsrv/medsrv_creds.c b/src/libcharon/plugins/medsrv/medsrv_creds.c index 8d1643908..3ae80f64c 100644 --- a/src/libcharon/plugins/medsrv/medsrv_creds.c +++ b/src/libcharon/plugins/medsrv/medsrv_creds.c @@ -51,11 +51,8 @@ typedef struct { key_type_t type; } cert_enumerator_t; -/** - * Implementation of cert_enumerator_t.public.enumerate - */ -static bool cert_enumerator_enumerate(cert_enumerator_t *this, - certificate_t **cert) +METHOD(enumerator_t, cert_enumerator_enumerate, bool, + cert_enumerator_t *this, certificate_t **cert) { certificate_t *trusted; public_key_t *public; @@ -91,22 +88,17 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this, return FALSE; } -/** - * Implementation of cert_enumerator_t.public.destroy - */ -static void cert_enumerator_destroy(cert_enumerator_t *this) +METHOD(enumerator_t, cert_enumerator_destroy, void, + cert_enumerator_t *this) { DESTROY_IF(this->current); this->inner->destroy(this->inner); free(this); } -/** - * Implementation of credential_set_t.create_cert_enumerator. - */ -static enumerator_t* create_cert_enumerator(private_medsrv_creds_t *this, - certificate_type_t cert, key_type_t key, - identification_t *id, bool trusted) +METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, + private_medsrv_creds_t *this, certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) { cert_enumerator_t *e; @@ -116,15 +108,17 @@ static enumerator_t* create_cert_enumerator(private_medsrv_creds_t *this, return NULL; } - e = malloc_thing(cert_enumerator_t); - e->current = NULL; - e->type = key; - e->public.enumerate = (void*)cert_enumerator_enumerate; - e->public.destroy = (void*)cert_enumerator_destroy; - e->inner = this->db->query(this->db, - "SELECT public_key FROM peer WHERE keyid = ?", - DB_BLOB, id->get_encoding(id), - DB_BLOB); + INIT(e, + .public = { + .enumerate = (void*)_cert_enumerator_enumerate, + .destroy = _cert_enumerator_destroy, + }, + .type = key, + .inner = this->db->query(this->db, + "SELECT public_key FROM peer WHERE keyid = ?", + DB_BLOB, id->get_encoding(id), + DB_BLOB), + ); if (!e->inner) { free(e); @@ -133,10 +127,8 @@ static enumerator_t* create_cert_enumerator(private_medsrv_creds_t *this, return &e->public; } -/** - * Implementation of backend_t.destroy. - */ -static void destroy(private_medsrv_creds_t *this) +METHOD(medsrv_creds_t, destroy, void, + private_medsrv_creds_t *this) { free(this); } @@ -146,17 +138,21 @@ static void destroy(private_medsrv_creds_t *this) */ medsrv_creds_t *medsrv_creds_create(database_t *db) { - private_medsrv_creds_t *this = malloc_thing(private_medsrv_creds_t); - - this->public.set.create_private_enumerator = (void*)return_null; - this->public.set.create_cert_enumerator = (void*)create_cert_enumerator; - this->public.set.create_shared_enumerator = (void*)return_null; - this->public.set.create_cdp_enumerator = (void*)return_null; - this->public.set.cache_cert = (void*)nop; - - this->public.destroy = (void (*)(medsrv_creds_t*))destroy; - - this->db = db; + private_medsrv_creds_t *this; + + INIT(this, + .public = { + .set = { + .create_private_enumerator = (void*)return_null, + .create_cert_enumerator = _create_cert_enumerator, + .create_shared_enumerator = (void*)return_null, + .create_cdp_enumerator = (void*)return_null, + .cache_cert = (void*)nop, + }, + .destroy = _destroy, + }, + .db = db, + ); return &this->public; } diff --git a/src/libcharon/plugins/nm/Makefile.in b/src/libcharon/plugins/nm/Makefile.in index 308d27229..d9ad2388e 100644 --- a/src/libcharon/plugins/nm/Makefile.in +++ b/src/libcharon/plugins/nm/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/nm/nm_creds.c b/src/libcharon/plugins/nm/nm_creds.c index ea98c056d..f8fae9504 100644 --- a/src/libcharon/plugins/nm/nm_creds.c +++ b/src/libcharon/plugins/nm/nm_creds.c @@ -170,11 +170,13 @@ static bool cert_filter(cert_data_t *data, certificate_t **in, static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this, key_type_t key, identification_t *id) { - cert_data_t *data = malloc_thing(cert_data_t); + cert_data_t *data; - data->this = this; - data->id = id; - data->key = key; + INIT(data, + .this = this, + .id = id, + .key = key, + ); this->lock->read_lock(this->lock); return enumerator_create_filter( @@ -182,12 +184,9 @@ static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this, (void*)cert_filter, data, (void*)cert_data_destroy); } -/** - * Implements credential_set_t.create_cert_enumerator - */ -static enumerator_t* create_cert_enumerator(private_nm_creds_t *this, - certificate_type_t cert, key_type_t key, - identification_t *id, bool trusted) +METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, + private_nm_creds_t *this, certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) { if (id && this->usercert && id->equals(id, this->usercert->get_subject(this->usercert))) @@ -201,11 +200,8 @@ static enumerator_t* create_cert_enumerator(private_nm_creds_t *this, return NULL; } -/** - * Implements credential_set_t.create_cert_enumerator - */ -static enumerator_t* create_private_enumerator(private_nm_creds_t *this, - key_type_t type, identification_t *id) +METHOD(credential_set_t, create_private_enumerator, enumerator_t*, + private_nm_creds_t *this, key_type_t type, identification_t *id) { if (this->key == NULL) { @@ -238,11 +234,9 @@ typedef struct { bool done; } shared_enumerator_t; -/** - * enumerate function for shared enumerator - */ -static bool shared_enumerate(shared_enumerator_t *this, shared_key_t **key, - id_match_t *me, id_match_t *other) +METHOD(enumerator_t, shared_enumerate, bool, + shared_enumerator_t *this, shared_key_t **key, id_match_t *me, + id_match_t *other) { if (this->done) { @@ -261,43 +255,41 @@ static bool shared_enumerate(shared_enumerator_t *this, shared_key_t **key, return TRUE; } -/** - * Destroy function for shared enumerator - */ -static void shared_destroy(shared_enumerator_t *this) +METHOD(enumerator_t, shared_destroy, void, + shared_enumerator_t *this) { this->key->destroy(this->key); this->this->lock->unlock(this->this->lock); free(this); } -/** - * Implements credential_set_t.create_cert_enumerator - */ -static enumerator_t* create_shared_enumerator(private_nm_creds_t *this, - shared_key_type_t type, identification_t *me, - identification_t *other) + +METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, + private_nm_creds_t *this, shared_key_type_t type, identification_t *me, + identification_t *other) { shared_enumerator_t *enumerator; chunk_t key; + this->lock->read_lock(this->lock); + switch (type) { case SHARED_EAP: case SHARED_IKE: if (!this->pass || !this->user) { - return NULL; + goto no_secret; } if (me && !me->equals(me, this->user)) { - return NULL; + goto no_secret; } key = chunk_create(this->pass, strlen(this->pass)); break; case SHARED_PRIVATE_KEY_PASS: if (!this->keypass) { - return NULL; + goto no_secret; } key = chunk_create(this->keypass, strlen(this->keypass)); break; @@ -305,28 +297,31 @@ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this, if (!this->keypass || !me || !chunk_equals(me->get_encoding(me), this->keyid)) { - return NULL; + goto no_secret; } key = chunk_create(this->keypass, strlen(this->keypass)); break; default: - return NULL; + goto no_secret; } - enumerator = malloc_thing(shared_enumerator_t); - enumerator->public.enumerate = (void*)shared_enumerate; - enumerator->public.destroy = (void*)shared_destroy; - enumerator->this = this; - enumerator->done = FALSE; - this->lock->read_lock(this->lock); + INIT(enumerator, + .public = { + .enumerate = (void*)_shared_enumerate, + .destroy = _shared_destroy, + }, + .this = this, + ); enumerator->key = shared_key_create(type, chunk_clone(key)); return &enumerator->public; + +no_secret: + this->lock->unlock(this->lock); + return NULL; } -/** - * Implementation of nm_creds_t.add_certificate - */ -static void add_certificate(private_nm_creds_t *this, certificate_t *cert) +METHOD(nm_creds_t, add_certificate, void, + private_nm_creds_t *this, certificate_t *cert) { this->lock->write_lock(this->lock); this->certs->insert_last(this->certs, cert); @@ -359,10 +354,8 @@ static void load_ca_file(private_nm_creds_t *this, char *file) } } -/** - * Implementation of nm_creds_t.load_ca_dir - */ -static void load_ca_dir(private_nm_creds_t *this, char *dir) +METHOD(nm_creds_t, load_ca_dir, void, + private_nm_creds_t *this, char *dir) { enumerator_t *enumerator; char *rel, *abs; @@ -390,11 +383,8 @@ static void load_ca_dir(private_nm_creds_t *this, char *dir) } } -/** - * Implementation of nm_creds_t.set_password - */ -static void set_username_password(private_nm_creds_t *this, identification_t *id, - char *password) +METHOD(nm_creds_t, set_username_password, void, + private_nm_creds_t *this, identification_t *id, char *password) { this->lock->write_lock(this->lock); DESTROY_IF(this->user); @@ -404,10 +394,8 @@ static void set_username_password(private_nm_creds_t *this, identification_t *id this->lock->unlock(this->lock); } -/** - * Implementation of nm_creds_t.set_key_password - */ -static void set_key_password(private_nm_creds_t *this, char *password) +METHOD(nm_creds_t, set_key_password, void, + private_nm_creds_t *this, char *password) { this->lock->write_lock(this->lock); free(this->keypass); @@ -415,10 +403,8 @@ static void set_key_password(private_nm_creds_t *this, char *password) this->lock->unlock(this->lock); } -/** - * Implementation of nm_creds_t.set_pin - */ -static void set_pin(private_nm_creds_t *this, chunk_t keyid, char *pin) +METHOD(nm_creds_t, set_pin, void, + private_nm_creds_t *this, chunk_t keyid, char *pin) { this->lock->write_lock(this->lock); free(this->keypass); @@ -428,11 +414,8 @@ static void set_pin(private_nm_creds_t *this, chunk_t keyid, char *pin) this->lock->unlock(this->lock); } -/** - * Implementation of nm_creds_t.set_cert_and_key - */ -static void set_cert_and_key(private_nm_creds_t *this, certificate_t *cert, - private_key_t *key) +METHOD(nm_creds_t, set_cert_and_key, void, + private_nm_creds_t *this, certificate_t *cert, private_key_t *key) { this->lock->write_lock(this->lock); DESTROY_IF(this->key); @@ -442,10 +425,8 @@ static void set_cert_and_key(private_nm_creds_t *this, certificate_t *cert, this->lock->unlock(this->lock); } -/** - * Implementation of nm_creds_t.clear - */ -static void clear(private_nm_creds_t *this) +METHOD(nm_creds_t, clear, void, + private_nm_creds_t *this) { certificate_t *cert; @@ -467,10 +448,8 @@ static void clear(private_nm_creds_t *this) this->keyid = chunk_empty; } -/** - * Implementation of nm_creds_t.destroy - */ -static void destroy(private_nm_creds_t *this) +METHOD(nm_creds_t, destroy, void, + private_nm_creds_t *this) { clear(this); this->certs->destroy(this->certs); @@ -483,32 +462,29 @@ static void destroy(private_nm_creds_t *this) */ nm_creds_t *nm_creds_create() { - private_nm_creds_t *this = malloc_thing(private_nm_creds_t); - - this->public.set.create_private_enumerator = (void*)create_private_enumerator; - this->public.set.create_cert_enumerator = (void*)create_cert_enumerator; - this->public.set.create_shared_enumerator = (void*)create_shared_enumerator; - this->public.set.create_cdp_enumerator = (void*)return_null; - this->public.set.cache_cert = (void*)nop; - this->public.add_certificate = (void(*)(nm_creds_t*, certificate_t *cert))add_certificate; - this->public.load_ca_dir = (void(*)(nm_creds_t*, char *dir))load_ca_dir; - this->public.set_username_password = (void(*)(nm_creds_t*, identification_t *id, char *password))set_username_password; - this->public.set_key_password = (void(*)(nm_creds_t*, char *password))set_key_password; - this->public.set_pin = (void(*)(nm_creds_t*, chunk_t keyid, char *pin))set_pin; - this->public.set_cert_and_key = (void(*)(nm_creds_t*, certificate_t *cert, private_key_t *key))set_cert_and_key; - this->public.clear = (void(*)(nm_creds_t*))clear; - this->public.destroy = (void(*)(nm_creds_t*))destroy; - - this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); - - this->certs = linked_list_create(); - this->user = NULL; - this->pass = NULL; - this->usercert = NULL; - this->key = NULL; - this->keypass = NULL; - this->keyid = chunk_empty; + private_nm_creds_t *this; + INIT(this, + .public = { + .set = { + .create_private_enumerator = _create_private_enumerator, + .create_cert_enumerator = _create_cert_enumerator, + .create_shared_enumerator = _create_shared_enumerator, + .create_cdp_enumerator = (void*)return_null, + .cache_cert = (void*)nop, + }, + .add_certificate = _add_certificate, + .load_ca_dir = _load_ca_dir, + .set_username_password = _set_username_password, + .set_key_password = _set_key_password, + .set_pin = _set_pin, + .set_cert_and_key = _set_cert_and_key, + .clear = _clear, + .destroy = _destroy, + }, + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .certs = linked_list_create(), + ); return &this->public; } diff --git a/src/libcharon/plugins/nm/nm_handler.c b/src/libcharon/plugins/nm/nm_handler.c index eacb54dda..408129ebe 100644 --- a/src/libcharon/plugins/nm/nm_handler.c +++ b/src/libcharon/plugins/nm/nm_handler.c @@ -40,11 +40,9 @@ struct private_nm_handler_t { linked_list_t *nbns; }; -/** - * Implementation of attribute_handler_t.handle - */ -static bool handle(private_nm_handler_t *this, identification_t *server, - configuration_attribute_type_t type, chunk_t data) +METHOD(attribute_handler_t, handle, bool, + private_nm_handler_t *this, identification_t *server, + configuration_attribute_type_t type, chunk_t data) { linked_list_t *list; @@ -93,11 +91,8 @@ static bool enumerate_dns(enumerator_t *this, return TRUE; } -/** - * Implementation of attribute_handler_t.create_attribute_enumerator - */ -static enumerator_t* create_attribute_enumerator(private_nm_handler_t *this, - identification_t *server, host_t *vip) +METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, + private_nm_handler_t *this, identification_t *server, host_t *vip) { if (vip && vip->get_family(vip) == AF_INET) { /* no IPv6 attributes yet */ @@ -120,11 +115,8 @@ static bool filter_chunks(void* null, char **in, chunk_t *out) return TRUE; } -/** - * Implementation of nm_handler_t.create_enumerator - */ -static enumerator_t* create_enumerator(private_nm_handler_t *this, - configuration_attribute_type_t type) +METHOD(nm_handler_t, create_enumerator, enumerator_t*, + private_nm_handler_t *this, configuration_attribute_type_t type) { linked_list_t *list; @@ -143,10 +135,8 @@ static enumerator_t* create_enumerator(private_nm_handler_t *this, (void*)filter_chunks, NULL, NULL); } -/** - * Implementation of nm_handler_t.reset - */ -static void reset(private_nm_handler_t *this) +METHOD(nm_handler_t, reset, void, + private_nm_handler_t *this) { void *data; @@ -160,10 +150,8 @@ static void reset(private_nm_handler_t *this) } } -/** - * Implementation of nm_handler_t.destroy. - */ -static void destroy(private_nm_handler_t *this) +METHOD(nm_handler_t, destroy, void, + private_nm_handler_t *this) { reset(this); this->dns->destroy(this->dns); @@ -176,17 +164,22 @@ static void destroy(private_nm_handler_t *this) */ nm_handler_t *nm_handler_create() { - private_nm_handler_t *this = malloc_thing(private_nm_handler_t); - - this->public.handler.handle = (bool(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle; - this->public.handler.release = (void(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))nop; - this->public.handler.create_attribute_enumerator = (enumerator_t*(*)(attribute_handler_t*, identification_t *server, host_t *vip))create_attribute_enumerator; - this->public.create_enumerator = (enumerator_t*(*)(nm_handler_t*, configuration_attribute_type_t type))create_enumerator; - this->public.reset = (void(*)(nm_handler_t*))reset; - this->public.destroy = (void(*)(nm_handler_t*))destroy; - - this->dns = linked_list_create(); - this->nbns = linked_list_create(); + private_nm_handler_t *this; + + INIT(this, + .public = { + .handler = { + .handle = _handle, + .release = nop, + .create_attribute_enumerator = _create_attribute_enumerator, + }, + .create_enumerator = _create_enumerator, + .reset = _reset, + .destroy = _destroy, + }, + .dns = linked_list_create(), + .nbns = linked_list_create(), + ); return &this->public; } diff --git a/src/libcharon/plugins/nm/nm_plugin.c b/src/libcharon/plugins/nm/nm_plugin.c index f1d3be7a5..84b7c810a 100644 --- a/src/libcharon/plugins/nm/nm_plugin.c +++ b/src/libcharon/plugins/nm/nm_plugin.c @@ -118,8 +118,8 @@ plugin_t *nm_plugin_create() }, .creds = nm_creds_create(), .handler = nm_handler_create(), - .plugin = nm_strongswan_plugin_new(this->creds, this->handler), ); + this->plugin = nm_strongswan_plugin_new(this->creds, this->handler); hydra->attributes->add_handler(hydra->attributes, &this->handler->handler); lib->credmgr->add_set(lib->credmgr, &this->creds->set); @@ -134,7 +134,8 @@ plugin_t *nm_plugin_create() charon->keep_cap(charon, CAP_DAC_OVERRIDE); lib->processor->queue_job(lib->processor, - (job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL)); + (job_t*)callback_job_create_with_prio((callback_job_cb_t)run, + this, NULL, NULL, JOB_PRIO_CRITICAL)); return &this->public.plugin; } diff --git a/src/libcharon/plugins/nm/nm_service.c b/src/libcharon/plugins/nm/nm_service.c index 4300b57cf..a6783fcc3 100644 --- a/src/libcharon/plugins/nm/nm_service.c +++ b/src/libcharon/plugins/nm/nm_service.c @@ -82,12 +82,11 @@ static void signal_ipv4_config(NMVPNPlugin *plugin, { GValue *val; GHashTable *config; - host_t *me, *other; + host_t *me; nm_handler_t *handler; config = g_hash_table_new(g_str_hash, g_str_equal); me = ike_sa->get_my_host(ike_sa); - other = ike_sa->get_other_host(ike_sa); handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler; /* NM requires a tundev, but netkey does not use one. Passing an invalid @@ -632,7 +631,8 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err) u_int id; /* our ike_sa pointer might be invalid, lookup sa */ - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { if (priv->ike_sa == ike_sa) @@ -640,7 +640,7 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err) id = ike_sa->get_unique_id(ike_sa); enumerator->destroy(enumerator); charon->controller->terminate_ike(charon->controller, id, - controller_cb_empty, NULL); + controller_cb_empty, NULL, 0); return TRUE; } } diff --git a/src/libcharon/plugins/nm/nm_service.h b/src/libcharon/plugins/nm/nm_service.h index b00000b6f..828d1a452 100644 --- a/src/libcharon/plugins/nm/nm_service.h +++ b/src/libcharon/plugins/nm/nm_service.h @@ -21,7 +21,7 @@ #ifndef NM_SERVICE_H_ #define NM_SERVICE_H_ -#include <glib/gtypes.h> +#include <glib.h> #include <glib-object.h> #include <nm-vpn-plugin.h> diff --git a/src/libcharon/plugins/radattr/Makefile.am b/src/libcharon/plugins/radattr/Makefile.am new file mode 100644 index 000000000..0ea8df5d1 --- /dev/null +++ b/src/libcharon/plugins/radattr/Makefile.am @@ -0,0 +1,17 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libradius + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-radattr.la +else +libstrongswan_radattr_la_LIBADD = $(top_builddir)/src/libradius/libradius.la +plugin_LTLIBRARIES = libstrongswan-radattr.la +endif + +libstrongswan_radattr_la_SOURCES = radattr_plugin.h radattr_plugin.c \ + radattr_listener.h radattr_listener.c + +libstrongswan_radattr_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in new file mode 100644 index 000000000..ecea0df16 --- /dev/null +++ b/src/libcharon/plugins/radattr/Makefile.in @@ -0,0 +1,616 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libcharon/plugins/radattr +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +@MONOLITHIC_FALSE@libstrongswan_radattr_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libradius/libradius.la +am_libstrongswan_radattr_la_OBJECTS = radattr_plugin.lo \ + radattr_listener.lo +libstrongswan_radattr_la_OBJECTS = \ + $(am_libstrongswan_radattr_la_OBJECTS) +libstrongswan_radattr_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_radattr_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_radattr_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_radattr_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstrongswan_radattr_la_SOURCES) +DIST_SOURCES = $(libstrongswan_radattr_la_SOURCES) +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@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +default_pkcs11 = @default_pkcs11@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +oldincludedir = @oldincludedir@ +openac_plugins = @openac_plugins@ +p_plugins = @p_plugins@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pluto_plugins = @pluto_plugins@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libradius + +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-radattr.la +@MONOLITHIC_FALSE@libstrongswan_radattr_la_LIBADD = $(top_builddir)/src/libradius/libradius.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-radattr.la +libstrongswan_radattr_la_SOURCES = radattr_plugin.h radattr_plugin.c \ + radattr_listener.h radattr_listener.c + +libstrongswan_radattr_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/radattr/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/radattr/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libstrongswan-radattr.la: $(libstrongswan_radattr_la_OBJECTS) $(libstrongswan_radattr_la_DEPENDENCIES) + $(libstrongswan_radattr_la_LINK) $(am_libstrongswan_radattr_la_rpath) $(libstrongswan_radattr_la_OBJECTS) $(libstrongswan_radattr_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radattr_listener.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radattr_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libcharon/plugins/radattr/radattr_listener.c b/src/libcharon/plugins/radattr/radattr_listener.c new file mode 100644 index 000000000..94b718a1b --- /dev/null +++ b/src/libcharon/plugins/radattr/radattr_listener.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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. + */ + +#include "radattr_listener.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <errno.h> + +#include <daemon.h> + +#include <radius_message.h> + +/** + * Maximum size of an attribute to add + */ +#define MAX_ATTR_SIZE 1024 + +typedef struct private_radattr_listener_t private_radattr_listener_t; + +/** + * Private data of an radattr_listener_t object. + */ +struct private_radattr_listener_t { + + /** + * Public radattr_listener_t interface. + */ + radattr_listener_t public; + + /** + * Directory to look for attribute files + */ + char *dir; + + /** + * IKE_AUTH message ID to attribute + */ + int mid; +}; + +/** + * Print RADIUS attributes found in IKE message notifies + */ +static void print_radius_attributes(private_radattr_listener_t *this, + message_t *message) +{ + radius_attribute_type_t type; + enumerator_t *enumerator; + notify_payload_t *notify; + payload_t *payload; + chunk_t data; + + enumerator = message->create_payload_enumerator(message); + while (enumerator->enumerate(enumerator, &payload)) + { + if (payload->get_type(payload) == NOTIFY) + { + notify = (notify_payload_t*)payload; + if (notify->get_notify_type(notify) == RADIUS_ATTRIBUTE) + { + data = notify->get_notification_data(notify); + if (data.len >= 2) + { + type = data.ptr[0]; + data = chunk_skip(data, 2); + if (chunk_printable(data, NULL, 0)) + { + DBG1(DBG_IKE, "received RADIUS %N: %.*s", + radius_attribute_type_names, type, + (int)data.len, data.ptr); + } + else + { + DBG1(DBG_IKE, "received RADIUS %N: %#B", + radius_attribute_type_names, type, &data); + + } + } + } + } + } + enumerator->destroy(enumerator); +} + +/** + * Add a RADIUS attribute from a client-ID specific file to an IKE message + */ +static void add_radius_attribute(private_radattr_listener_t *this, + ike_sa_t *ike_sa, message_t *message) +{ + if (this->dir && + (this->mid == -1 || message->get_message_id(message) == this->mid)) + { + identification_t *id; + auth_cfg_t *auth; + char path[PATH_MAX]; + chunk_t data; + struct stat sb; + void *addr; + int fd; + + auth = ike_sa->get_auth_cfg(ike_sa, TRUE); + id = auth->get(auth, AUTH_RULE_EAP_IDENTITY); + if (!id) + { + id = ike_sa->get_my_id(ike_sa); + } + + snprintf(path, sizeof(path), "%s/%Y", this->dir, id); + fd = open(path, O_RDONLY); + if (fd != -1) + { + if (fstat(fd, &sb) != -1) + { + if (sb.st_size <= MAX_ATTR_SIZE) + { + addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr != MAP_FAILED) + { + data = chunk_create(addr, sb.st_size); + if (data.len >= 2) + { + DBG1(DBG_CFG, "adding RADIUS %N attribute", + radius_attribute_type_names, data.ptr[0]); + message->add_notify(message, FALSE, + RADIUS_ATTRIBUTE, data); + } + munmap(addr, sb.st_size); + } + else + { + DBG1(DBG_CFG, "mapping RADIUS attribute '%s' failed: %s", + path, strerror(errno)); + } + } + else + { + DBG1(DBG_CFG, "RADIUS attribute '%s' exceeds size limit", + path); + } + } + else + { + DBG1(DBG_CFG, "fstat RADIUS attribute '%s' failed: %s", + path, strerror(errno)); + } + close(fd); + } + else + { + DBG1(DBG_CFG, "reading RADIUS attribute '%s' failed: %s", + path, strerror(errno)); + } + } +} + +METHOD(listener_t, message, bool, + private_radattr_listener_t *this, + ike_sa_t *ike_sa, message_t *message, bool incoming) +{ + if (ike_sa->supports_extension(ike_sa, EXT_STRONGSWAN) && + message->get_exchange_type(message) == IKE_AUTH && + message->get_payload(message, EXTENSIBLE_AUTHENTICATION)) + { + if (incoming) + { + print_radius_attributes(this, message); + } + else + { + add_radius_attribute(this, ike_sa, message); + } + } + return TRUE; +} + + +METHOD(radattr_listener_t, destroy, void, + private_radattr_listener_t *this) +{ + free(this); +} + +/** + * See header + */ +radattr_listener_t *radattr_listener_create() +{ + private_radattr_listener_t *this; + + INIT(this, + .public = { + .listener = { + .message = _message, + }, + .destroy = _destroy, + }, + .dir = lib->settings->get_str(lib->settings, + "charon.plugins.radattr.dir", NULL), + .mid = lib->settings->get_int(lib->settings, + "charon.plugins.radattr.message_id", -1), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/radattr/radattr_listener.h b/src/libcharon/plugins/radattr/radattr_listener.h new file mode 100644 index 000000000..e61c441bf --- /dev/null +++ b/src/libcharon/plugins/radattr/radattr_listener.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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 radattr_listener radattr_listener + * @{ @ingroup radattr + */ + +#ifndef RADATTR_LISTENER_H_ +#define RADATTR_LISTENER_H_ + +#include <bus/listeners/listener.h> + +typedef struct radattr_listener_t radattr_listener_t; + +/** + * Output received RADIUS attributes, inject custom attributes. + */ +struct radattr_listener_t { + + /** + * Implements a listener. + */ + listener_t listener; + + /** + * Destroy a radattr_listener_t. + */ + void (*destroy)(radattr_listener_t *this); +}; + +/** + * Create a radattr_listener instance. + */ +radattr_listener_t *radattr_listener_create(); + +#endif /** RADATTR_LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/radattr/radattr_plugin.c b/src/libcharon/plugins/radattr/radattr_plugin.c new file mode 100644 index 000000000..85ea326ac --- /dev/null +++ b/src/libcharon/plugins/radattr/radattr_plugin.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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. + */ + +#include "radattr_plugin.h" + +#include "radattr_listener.h" + +#include <daemon.h> + +typedef struct private_radattr_plugin_t private_radattr_plugin_t; + +/** + * private data of radattr plugin + */ +struct private_radattr_plugin_t { + + /** + * implements plugin interface + */ + radattr_plugin_t public; + + /** + * Listener acting on messages + */ + radattr_listener_t *listener; +}; + +METHOD(plugin_t, get_name, char*, + private_radattr_plugin_t *this) +{ + return "radattr"; +} + +METHOD(plugin_t, destroy, void, + private_radattr_plugin_t *this) +{ + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); + free(this); +} + +/** + * Plugin constructor + */ +plugin_t *radattr_plugin_create() +{ + private_radattr_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .reload = (void*)return_false, + .destroy = _destroy, + }, + }, + .listener = radattr_listener_create(), + ); + + charon->bus->add_listener(charon->bus, &this->listener->listener); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/radattr/radattr_plugin.h b/src/libcharon/plugins/radattr/radattr_plugin.h new file mode 100644 index 000000000..c3bad5a3a --- /dev/null +++ b/src/libcharon/plugins/radattr/radattr_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * 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 radattr radattr + * @ingroup cplugins + * + * @defgroup radattr_plugin radattr_plugin + * @{ @ingroup radattr + */ + +#ifndef RADATTR_PLUGIN_H_ +#define RADATTR_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct radattr_plugin_t radattr_plugin_t; + +/** + * Plugin to inject/process custom RADIUS attributes. + */ +struct radattr_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** RADATTR_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in index e36fa6bb4..59a560b86 100644 --- a/src/libcharon/plugins/smp/Makefile.in +++ b/src/libcharon/plugins/smp/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/smp/smp.c b/src/libcharon/plugins/smp/smp.c index d20f32248..2b830012d 100644 --- a/src/libcharon/plugins/smp/smp.c +++ b/src/libcharon/plugins/smp/smp.c @@ -208,12 +208,13 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer /* <ikesalist> */ xmlTextWriterStartElement(writer, "ikesalist"); - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { ike_sa_id_t *id; host_t *local, *remote; - iterator_t *children; + enumerator_t *children; child_sa_t *child_sa; id = ike_sa->get_id(ike_sa); @@ -263,8 +264,8 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer /* <childsalist> */ xmlTextWriterStartElement(writer, "childsalist"); - children = ike_sa->create_child_sa_iterator(ike_sa); - while (children->iterate(children, (void**)&child_sa)) + children = ike_sa->create_child_sa_enumerator(ike_sa); + while (children->enumerate(children, (void**)&child_sa)) { write_child(writer, child_sa); } @@ -394,7 +395,8 @@ static void request_control_terminate(xmlTextReaderPtr reader, enumerator_t *enumerator; ike_sa_t *ike_sa; - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { if (streq(str, ike_sa->get_name(ike_sa))) @@ -419,14 +421,14 @@ static void request_control_terminate(xmlTextReaderPtr reader, if (ike) { status = charon->controller->terminate_ike( - charon->controller, id, - (controller_cb_t)xml_callback, writer); + charon->controller, id, + (controller_cb_t)xml_callback, writer, 0); } else { status = charon->controller->terminate_child( - charon->controller, id, - (controller_cb_t)xml_callback, writer); + charon->controller, id, + (controller_cb_t)xml_callback, writer, 0); } /* </log> */ xmlTextWriterEndElement(writer); @@ -459,17 +461,21 @@ static void request_control_initiate(xmlTextReaderPtr reader, /* <log> */ xmlTextWriterStartElement(writer, "log"); - peer = charon->backends->get_peer_cfg_by_name(charon->backends, (char*)str); + peer = charon->backends->get_peer_cfg_by_name(charon->backends, + (char*)str); if (peer) { enumerator = peer->create_child_cfg_enumerator(peer); if (ike) { - if (!enumerator->enumerate(enumerator, &child)) + if (enumerator->enumerate(enumerator, &child)) + { + child->get_ref(child); + } + else { child = NULL; } - child->get_ref(child); } else { @@ -488,7 +494,7 @@ static void request_control_initiate(xmlTextReaderPtr reader, { status = charon->controller->initiate(charon->controller, peer, child, (controller_cb_t)xml_callback, - writer); + writer, 0); } else { @@ -625,7 +631,7 @@ static job_requeue_t process(int *fdp) int fd = *fdp; bool oldstate; char buffer[4096]; - size_t len; + ssize_t len; xmlTextReaderPtr reader; char *id = NULL, *type = NULL; @@ -640,7 +646,7 @@ static job_requeue_t process(int *fdp) DBG2(DBG_CFG, "SMP XML connection closed"); return JOB_REQUEUE_NONE; } - DBG3(DBG_CFG, "got XML request: %b", buffer, len); + DBG3(DBG_CFG, "got XML request: %b", buffer, (u_int)len); reader = xmlReaderForMemory(buffer, len, NULL, NULL, 0); if (reader == NULL) @@ -772,7 +778,8 @@ plugin_t *smp_plugin_create() return NULL; } - this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)dispatch, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public.plugin; diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in index 95cb04d14..9c4e5e7b4 100644 --- a/src/libcharon/plugins/socket_default/Makefile.in +++ b/src/libcharon/plugins/socket_default/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/socket_default/socket_default_plugin.c b/src/libcharon/plugins/socket_default/socket_default_plugin.c index 1bc8244d5..01d9473bf 100644 --- a/src/libcharon/plugins/socket_default/socket_default_plugin.c +++ b/src/libcharon/plugins/socket_default/socket_default_plugin.c @@ -43,11 +43,20 @@ METHOD(plugin_t, get_name, char*, METHOD(plugin_t, destroy, void, private_socket_default_plugin_t *this) { - charon->socket->remove_socket(charon->socket, - (socket_constructor_t)socket_default_socket_create); free(this); } +METHOD(plugin_t, get_features, int, + private_socket_default_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(socket_register, socket_default_socket_create), + PLUGIN_PROVIDE(CUSTOM, "socket"), + }; + *features = f; + return countof(f); +} + /* * see header file */ @@ -59,15 +68,11 @@ plugin_t *socket_default_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - charon->socket->add_socket(charon->socket, - (socket_constructor_t)socket_default_socket_create); - return &this->public.plugin; } - diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c index e95646643..76ca1df42 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -461,15 +461,15 @@ static int open_socket(private_socket_default_socket_t *this, int skt; memset(&addr, 0, sizeof(addr)); + addr.ss_family = family; /* precalculate constants depending on address family */ switch (family) { case AF_INET: { struct sockaddr_in *sin = (struct sockaddr_in *)&addr; - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = INADDR_ANY; - sin->sin_port = htons(port); + htoun32(&sin->sin_addr.s_addr, INADDR_ANY); + htoun16(&sin->sin_port, port); addrlen = sizeof(struct sockaddr_in); sol = SOL_IP; #ifdef IP_PKTINFO @@ -482,9 +482,8 @@ static int open_socket(private_socket_default_socket_t *this, case AF_INET6: { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr; - sin6->sin6_family = AF_INET6; memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any)); - sin6->sin6_port = htons(port); + htoun16(&sin6->sin6_port, port); addrlen = sizeof(struct sockaddr_in6); sol = SOL_IPV6; pktinfo = IPV6_RECVPKTINFO; diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in index 97e3a713d..f45e3d255 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.in +++ b/src/libcharon/plugins/socket_dynamic/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c index c5ea37a10..c21d5240e 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c @@ -34,6 +34,17 @@ struct private_socket_dynamic_plugin_t { socket_dynamic_plugin_t public; }; +METHOD(plugin_t, get_features, int, + private_socket_dynamic_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(socket_register, socket_dynamic_socket_create), + PLUGIN_PROVIDE(CUSTOM, "socket"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, get_name, char*, private_socket_dynamic_plugin_t *this) { @@ -43,8 +54,6 @@ METHOD(plugin_t, get_name, char*, METHOD(plugin_t, destroy, void, private_socket_dynamic_plugin_t *this) { - charon->socket->remove_socket(charon->socket, - (socket_constructor_t)socket_dynamic_socket_create); free(this); } @@ -59,15 +68,12 @@ plugin_t *socket_dynamic_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - charon->socket->add_socket(charon->socket, - (socket_constructor_t)socket_dynamic_socket_create); - return &this->public.plugin; } diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c index 74dba82cc..eee3814a8 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c @@ -235,7 +235,7 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this, DBG1(DBG_NET, "receive buffer too small, packet discarded"); return NULL; } - DBG3(DBG_NET, "received packet %b", buffer, len); + DBG3(DBG_NET, "received packet %b", buffer, (u_int)len); if (len < MARKER_LEN) { diff --git a/src/libcharon/plugins/socket_raw/Makefile.in b/src/libcharon/plugins/socket_raw/Makefile.in index 6f1a09c88..5abceb6c3 100644 --- a/src/libcharon/plugins/socket_raw/Makefile.in +++ b/src/libcharon/plugins/socket_raw/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c index 5bd28bd42..1299c30ca 100644 --- a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c +++ b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c @@ -40,11 +40,20 @@ METHOD(plugin_t, get_name, char*, return "socket-raw"; } +METHOD(plugin_t, get_features, int, + private_socket_raw_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(socket_register, socket_raw_socket_create), + PLUGIN_PROVIDE(CUSTOM, "socket"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_socket_raw_plugin_t *this) { - charon->socket->remove_socket(charon->socket, - (socket_constructor_t)socket_raw_socket_create); free(this); } @@ -59,15 +68,12 @@ plugin_t *socket_raw_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - charon->socket->add_socket(charon->socket, - (socket_constructor_t)socket_raw_socket_create); - return &this->public.plugin; } diff --git a/src/libcharon/plugins/socket_raw/socket_raw_socket.c b/src/libcharon/plugins/socket_raw/socket_raw_socket.c index f6e87a86f..ae37d8f2b 100644 --- a/src/libcharon/plugins/socket_raw/socket_raw_socket.c +++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.c @@ -31,7 +31,6 @@ #include <sys/ioctl.h> #include <netinet/in.h> #include <netinet/ip.h> -#include <netinet/ip6.h> #include <netinet/udp.h> #include <linux/types.h> #include <linux/filter.h> @@ -259,6 +258,8 @@ METHOD(socket_t, receiver, status_t, DBG1(DBG_NET, "error reading IPv6 ancillary data"); return FAILED; } + +#ifdef HAVE_IN6_PKTINFO if (cmsgptr->cmsg_level == SOL_IPV6 && cmsgptr->cmsg_type == IPV6_2292PKTINFO) { @@ -273,6 +274,7 @@ METHOD(socket_t, receiver, status_t, src.sin6_port = udp->source; dest = host_create_from_sockaddr((sockaddr_t*)&dst); } +#endif /* HAVE_IN6_PKTINFO */ } /* ancillary data missing? */ if (dest == NULL) @@ -397,6 +399,7 @@ METHOD(socket_t, sender, status_t, sin = (struct sockaddr_in*)src->get_sockaddr(src); memcpy(&pktinfo->ipi_spec_dst, &sin->sin_addr, sizeof(struct in_addr)); } +#ifdef HAVE_IN6_PKTINFO else { char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; @@ -414,6 +417,7 @@ METHOD(socket_t, sender, status_t, sin = (struct sockaddr_in6*)src->get_sockaddr(src); memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr)); } +#endif /* HAVE_IN6_PKTINFO */ } bytes_sent = sendmsg(skt, &msg, 0); @@ -435,29 +439,25 @@ static int open_send_socket(private_socket_raw_socket_t *this, int on = TRUE; int type = UDP_ENCAP_ESPINUDP; struct sockaddr_storage addr; - u_int sol; int skt; memset(&addr, 0, sizeof(addr)); + addr.ss_family = family; /* precalculate constants depending on address family */ switch (family) { case AF_INET: { struct sockaddr_in *sin = (struct sockaddr_in *)&addr; - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = INADDR_ANY; - sin->sin_port = htons(port); - sol = SOL_IP; + htoun32(&sin->sin_addr.s_addr, INADDR_ANY); + htoun16(&sin->sin_port, port); break; } case AF_INET6: { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr; - sin6->sin6_family = AF_INET6; memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any)); - sin6->sin6_port = htons(port); - sol = SOL_IPV6; + htoun16(&sin6->sin6_port, port); break; } default: @@ -514,18 +514,16 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family) { int skt; int on = TRUE; - u_int proto_offset, ip_len, sol, udp_header, ike_header; + u_int ip_len, sol, udp_header, ike_header; /* precalculate constants depending on address family */ switch (family) { case AF_INET: - proto_offset = IP_PROTO_OFFSET; ip_len = IP_LEN; sol = SOL_IP; break; case AF_INET6: - proto_offset = IP6_PROTO_OFFSET; ip_len = 0; /* IPv6 raw sockets contain no IP header */ sol = SOL_IPV6; break; diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in index d7b43dcc9..d04c7f6c9 100644 --- a/src/libcharon/plugins/sql/Makefile.in +++ b/src/libcharon/plugins/sql/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/sql/sql_logger.c b/src/libcharon/plugins/sql/sql_logger.c index d350c4c3d..10ceacb00 100644 --- a/src/libcharon/plugins/sql/sql_logger.c +++ b/src/libcharon/plugins/sql/sql_logger.c @@ -47,11 +47,9 @@ struct private_sql_logger_t { bool recursive; }; -/** - * Implementation of bus_listener_t.log. - */ -static bool log_(private_sql_logger_t *this, debug_t group, level_t level, - int thread, ike_sa_t* ike_sa, char *format, va_list args) +METHOD(listener_t, log_, bool, + private_sql_logger_t *this, debug_t group, level_t level, int thread, + ike_sa_t* ike_sa, char *format, va_list args) { if (this->recursive) { @@ -115,10 +113,8 @@ static bool log_(private_sql_logger_t *this, debug_t group, level_t level, return TRUE; } -/** - * Implementation of sql_logger_t.destroy. - */ -static void destroy(private_sql_logger_t *this) +METHOD(sql_logger_t, destroy, void, + private_sql_logger_t *this) { free(this); } @@ -128,17 +124,19 @@ static void destroy(private_sql_logger_t *this) */ sql_logger_t *sql_logger_create(database_t *db) { - private_sql_logger_t *this = malloc_thing(private_sql_logger_t); - - memset(&this->public.listener, 0, sizeof(listener_t)); - this->public.listener.log = (bool(*)(listener_t*,debug_t,level_t,int,ike_sa_t*,char*,va_list))log_; - this->public.destroy = (void(*)(sql_logger_t*))destroy; - - this->db = db; - this->recursive = FALSE; - - this->level = lib->settings->get_int(lib->settings, - "charon.plugins.sql.loglevel", -1); + private_sql_logger_t *this; + + INIT(this, + .public = { + .listener = { + .log = _log_, + }, + .destroy = _destroy, + }, + .db = db, + .level = lib->settings->get_int(lib->settings, + "charon.plugins.sql.loglevel", -1), + ); return &this->public; } diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in index fd859daeb..60f5f535a 100644 --- a/src/libcharon/plugins/stroke/Makefile.in +++ b/src/libcharon/plugins/stroke/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c index 69e13deb9..bec35a661 100644 --- a/src/libcharon/plugins/stroke/stroke_ca.c +++ b/src/libcharon/plugins/stroke/stroke_ca.c @@ -319,7 +319,7 @@ static void list_uris(linked_list_t *list, char *label, FILE *out) { if (first) { - fprintf(out, label); + fprintf(out, "%s", label); first = FALSE; } else diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 2b3164384..483e3d253 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -263,7 +264,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, { identification_t *identity; certificate_t *certificate; - char *auth, *id, *cert, *ca; + char *auth, *id, *pubkey, *cert, *ca; stroke_end_t *end, *other_end; auth_cfg_t *cfg; char eap_buf[32]; @@ -328,6 +329,9 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, case AUTH_CLASS_EAP: auth = "eap"; break; + case AUTH_CLASS_ANY: + auth = "any"; + break; } } else @@ -396,6 +400,18 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, } cfg->add(cfg, AUTH_RULE_IDENTITY, identity); + /* add raw RSA public key */ + pubkey = end->rsakey; + if (pubkey && !streq(pubkey, "") && !streq(pubkey, "%cert")) + { + certificate = this->cred->load_pubkey(this->cred, KEY_RSA, pubkey, + identity); + if (certificate) + { + cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate); + } + } + /* CA constraint */ if (ca) { @@ -775,13 +791,28 @@ static void add_ts(private_stroke_config_t *this, } /** + * map starter magic values to our action type + */ +static action_t map_action(int starter_action) +{ + switch (starter_action) + { + case 2: /* =hold */ + return ACTION_ROUTE; + case 3: /* =restart */ + return ACTION_RESTART; + default: + return ACTION_NONE; + } +} + +/** * build a child config from the stroke message */ static child_cfg_t *build_child_cfg(private_stroke_config_t *this, stroke_msg_t *msg) { child_cfg_t *child_cfg; - action_t dpd; lifetime_cfg_t lifetime = { .time = { .life = msg->add_conn.rekey.ipsec_lifetime, @@ -808,23 +839,11 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this, .mask = msg->add_conn.mark_out.mask }; - switch (msg->add_conn.dpd.action) - { /* map startes magic values to our action type */ - case 2: /* =hold */ - dpd = ACTION_ROUTE; - break; - case 3: /* =restart */ - dpd = ACTION_RESTART; - break; - default: - dpd = ACTION_NONE; - break; - } - child_cfg = child_cfg_create( - msg->add_conn.name, &lifetime, - msg->add_conn.me.updown, msg->add_conn.me.hostaccess, - msg->add_conn.mode, ACTION_NONE, dpd, dpd, msg->add_conn.ipcomp, + msg->add_conn.name, &lifetime, msg->add_conn.me.updown, + msg->add_conn.me.hostaccess, msg->add_conn.mode, ACTION_NONE, + map_action(msg->add_conn.dpd.action), + map_action(msg->add_conn.close_action), msg->add_conn.ipcomp, msg->add_conn.inactivity, msg->add_conn.reqid, &mark_in, &mark_out, msg->add_conn.tfc); child_cfg->set_mipv6_options(child_cfg, msg->add_conn.proxy_mode, @@ -950,6 +969,175 @@ METHOD(stroke_config_t, del, void, } } +METHOD(stroke_config_t, set_user_credentials, void, + private_stroke_config_t *this, stroke_msg_t *msg, FILE *prompt) +{ + enumerator_t *enumerator, *children, *remote_auth; + peer_cfg_t *peer, *found = NULL; + auth_cfg_t *auth_cfg, *remote_cfg; + auth_class_t auth_class; + child_cfg_t *child; + identification_t *id, *identity, *gw = NULL; + shared_key_type_t type = SHARED_ANY; + chunk_t password = chunk_empty; + + this->mutex->lock(this->mutex); + enumerator = this->list->create_enumerator(this->list); + while (enumerator->enumerate(enumerator, (void**)&peer)) + { /* find the peer (or child) config with the given name */ + if (streq(peer->get_name(peer), msg->user_creds.name)) + { + found = peer; + } + else + { + children = peer->create_child_cfg_enumerator(peer); + while (children->enumerate(children, &child)) + { + if (streq(child->get_name(child), msg->user_creds.name)) + { + found = peer; + break; + } + } + children->destroy(children); + } + + if (found) + { + break; + } + } + enumerator->destroy(enumerator); + + if (!found) + { + DBG1(DBG_CFG, " no config named '%s'", msg->user_creds.name); + fprintf(prompt, "no config named '%s'\n", msg->user_creds.name); + this->mutex->unlock(this->mutex); + return; + } + + id = identification_create_from_string(msg->user_creds.username); + if (strlen(msg->user_creds.username) == 0 || + !id || id->get_type(id) == ID_ANY) + { + DBG1(DBG_CFG, " invalid username '%s'", msg->user_creds.username); + fprintf(prompt, "invalid username '%s'\n", msg->user_creds.username); + this->mutex->unlock(this->mutex); + DESTROY_IF(id); + return; + } + + /* replace/set the username in the first EAP auth_cfg, also look for a + * suitable remote ID. + * note that adding the identity here is not fully thread-safe as the + * peer_cfg and in turn the auth_cfg could be in use. for the default use + * case (setting user credentials before upping the connection) this will + * not be a problem, though. */ + enumerator = found->create_auth_cfg_enumerator(found, TRUE); + remote_auth = found->create_auth_cfg_enumerator(found, FALSE); + while (enumerator->enumerate(enumerator, (void**)&auth_cfg)) + { + if (remote_auth->enumerate(remote_auth, (void**)&remote_cfg)) + { /* fall back on rightid, in case aaa_identity is not specified */ + identity = remote_cfg->get(remote_cfg, AUTH_RULE_IDENTITY); + if (identity && identity->get_type(identity) != ID_ANY) + { + gw = identity; + } + } + + auth_class = (uintptr_t)auth_cfg->get(auth_cfg, AUTH_RULE_AUTH_CLASS); + if (auth_class == AUTH_CLASS_EAP) + { + auth_cfg->add(auth_cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id)); + /* if aaa_identity is specified use that as remote ID */ + identity = auth_cfg->get(auth_cfg, AUTH_RULE_AAA_IDENTITY); + if (identity && identity->get_type(identity) != ID_ANY) + { + gw = identity; + } + DBG1(DBG_CFG, " configured EAP-Identity %Y", id); + type = SHARED_EAP; + break; + } + } + enumerator->destroy(enumerator); + remote_auth->destroy(remote_auth); + /* clone the gw ID before unlocking the mutex */ + if (gw) + { + gw = gw->clone(gw); + } + this->mutex->unlock(this->mutex); + + if (type == SHARED_ANY) + { + DBG1(DBG_CFG, " config '%s' unsuitable for user credentials", + msg->user_creds.name); + fprintf(prompt, "config '%s' unsuitable for user credentials\n", + msg->user_creds.name); + id->destroy(id); + DESTROY_IF(gw); + return; + } + + if (msg->user_creds.password) + { + char *pass; + + pass = msg->user_creds.password; + password = chunk_clone(chunk_create(pass, strlen(pass))); + memwipe(pass, strlen(pass)); + } + else + { /* prompt the user for the password */ + char buf[256]; + + fprintf(prompt, "Password:\n"); + if (fgets(buf, sizeof(buf), prompt)) + { + password = chunk_clone(chunk_create(buf, strlen(buf))); + if (password.len > 0) + { /* trim trailing \n */ + password.len--; + } + memwipe(buf, sizeof(buf)); + } + } + + if (password.len) + { + shared_key_t *shared; + linked_list_t *owners; + + shared = shared_key_create(type, password); + + owners = linked_list_create(); + owners->insert_last(owners, id->clone(id)); + if (gw && gw->get_type(gw) != ID_ANY) + { + owners->insert_last(owners, gw->clone(gw)); + DBG1(DBG_CFG, " added %N secret for %Y %Y", shared_key_type_names, + type, id, gw); + } + else + { + DBG1(DBG_CFG, " added %N secret for %Y", shared_key_type_names, + type, id); + } + this->cred->add_shared(this->cred, shared, owners); + DBG4(DBG_CFG, " secret: %#B", &password); + } + else + { /* in case a user answers the password prompt by just pressing enter */ + chunk_clear(&password); + } + id->destroy(id); + DESTROY_IF(gw); +} + METHOD(stroke_config_t, destroy, void, private_stroke_config_t *this) { @@ -974,6 +1162,7 @@ stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred) }, .add = _add, .del = _del, + .set_user_credentials = _set_user_credentials, .destroy = _destroy, }, .list = linked_list_create(), diff --git a/src/libcharon/plugins/stroke/stroke_config.h b/src/libcharon/plugins/stroke/stroke_config.h index 05e4665ca..450d517f3 100644 --- a/src/libcharon/plugins/stroke/stroke_config.h +++ b/src/libcharon/plugins/stroke/stroke_config.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -53,6 +54,15 @@ struct stroke_config_t { void (*del)(stroke_config_t *this, stroke_msg_t *msg); /** + * Set the username and password for a connection in this backend. + * + * @param msg received stroke message + * @param prompt I/O channel to prompt for the password + */ + void (*set_user_credentials)(stroke_config_t *this, stroke_msg_t *msg, + FILE *prompt); + + /** * Destroy a stroke_config instance. */ void (*destroy)(stroke_config_t *this); diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c index 4943ee670..729e9d757 100644 --- a/src/libcharon/plugins/stroke/stroke_control.c +++ b/src/libcharon/plugins/stroke/stroke_control.c @@ -15,7 +15,9 @@ #include "stroke_control.h" +#include <hydra.h> #include <daemon.h> + #include <processing/jobs/delete_ike_sa_job.h> #include <processing/jobs/rekey_ike_sa_job.h> #include <processing/jobs/rekey_child_sa_job.h> @@ -101,14 +103,14 @@ static void charon_initiate(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, if (msg->output_verbosity < 0) { charon->controller->initiate(charon->controller, peer_cfg, child_cfg, - NULL, NULL); + NULL, NULL, 0); } else { stroke_log_info_t info = { msg->output_verbosity, out }; charon->controller->initiate(charon->controller, peer_cfg, child_cfg, - (controller_cb_t)stroke_log, &info); + (controller_cb_t)stroke_log, &info, 0); } } @@ -275,28 +277,29 @@ METHOD(stroke_control_t, terminate, void, if (child) { charon->controller->terminate_child(charon->controller, id, - (controller_cb_t)stroke_log, &info); + (controller_cb_t)stroke_log, &info, 0); } else { charon->controller->terminate_ike(charon->controller, id, - (controller_cb_t)stroke_log, &info); + (controller_cb_t)stroke_log, &info, 0); } return; } ike_list = linked_list_create(); child_list = linked_list_create(); - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { child_sa_t *child_sa; - iterator_t *children; + enumerator_t *children; if (child) { - children = ike_sa->create_child_sa_iterator(ike_sa); - while (children->iterate(children, (void**)&child_sa)) + children = ike_sa->create_child_sa_enumerator(ike_sa); + while (children->enumerate(children, (void**)&child_sa)) { if (streq(name, child_sa->get_name(child_sa))) { @@ -330,7 +333,7 @@ METHOD(stroke_control_t, terminate, void, while (enumerator->enumerate(enumerator, &del)) { charon->controller->terminate_child(charon->controller, del, - (controller_cb_t)stroke_log, &info); + (controller_cb_t)stroke_log, &info, 0); } enumerator->destroy(enumerator); @@ -338,7 +341,7 @@ METHOD(stroke_control_t, terminate, void, while (enumerator->enumerate(enumerator, &del)) { charon->controller->terminate_ike(charon->controller, del, - (controller_cb_t)stroke_log, &info); + (controller_cb_t)stroke_log, &info, 0); } enumerator->destroy(enumerator); @@ -366,16 +369,17 @@ METHOD(stroke_control_t, rekey, void, DBG1(DBG_CFG, "error parsing specifier string"); return; } - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { child_sa_t *child_sa; - iterator_t *children; + enumerator_t *children; if (child) { - children = ike_sa->create_child_sa_iterator(ike_sa); - while (children->iterate(children, (void**)&child_sa)) + children = ike_sa->create_child_sa_enumerator(ike_sa); + while (children->enumerate(children, (void**)&child_sa)) { if ((name && streq(name, child_sa->get_name(child_sa))) || (id && id == child_sa->get_reqid(child_sa))) @@ -442,7 +446,8 @@ METHOD(stroke_control_t, terminate_srcip, void, chunk_end = end->get_address(end); } - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { vip = ike_sa->get_virtual_ip(ike_sa, FALSE); @@ -481,8 +486,7 @@ METHOD(stroke_control_t, terminate_srcip, void, METHOD(stroke_control_t, purge_ike, void, private_stroke_control_t *this, stroke_msg_t *msg, FILE *out) { - enumerator_t *enumerator; - iterator_t *iterator; + enumerator_t *enumerator, *children; ike_sa_t *ike_sa; child_sa_t *child_sa; linked_list_t *list; @@ -493,16 +497,17 @@ METHOD(stroke_control_t, purge_ike, void, info.level = msg->output_verbosity; list = linked_list_create(); - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { - iterator = ike_sa->create_child_sa_iterator(ike_sa); - if (!iterator->iterate(iterator, (void**)&child_sa)) + children = ike_sa->create_child_sa_enumerator(ike_sa); + if (!children->enumerate(children, (void**)&child_sa)) { list->insert_last(list, (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa)); } - iterator->destroy(iterator); + children->destroy(children); } enumerator->destroy(enumerator); @@ -510,25 +515,44 @@ METHOD(stroke_control_t, purge_ike, void, while (enumerator->enumerate(enumerator, &del)) { charon->controller->terminate_ike(charon->controller, del, - (controller_cb_t)stroke_log, &info); + (controller_cb_t)stroke_log, &info, 0); } enumerator->destroy(enumerator); list->destroy(list); } /** - * call charon to install a trap + * call charon to install a shunt or trap */ static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, char *name, FILE *out) { - if (charon->traps->install(charon->traps, peer_cfg, child_cfg)) + ipsec_mode_t mode; + + mode = child_cfg->get_mode(child_cfg); + if (mode == MODE_PASS || mode == MODE_DROP) { - fprintf(out, "'%s' routed\n", name); + if (charon->shunts->install(charon->shunts, child_cfg)) + { + fprintf(out, "'%s' shunt %N policy installed\n", + name, ipsec_mode_names, mode); + } + else + { + fprintf(out, "'%s' shunt %N policy installation failed\n", + name, ipsec_mode_names, mode); + } } else { - fprintf(out, "routing '%s' failed\n", name); + if (charon->traps->install(charon->traps, peer_cfg, child_cfg)) + { + fprintf(out, "'%s' routed\n", name); + } + else + { + fprintf(out, "routing '%s' failed\n", name); + } } } @@ -609,7 +633,13 @@ METHOD(stroke_control_t, unroute, void, { child_sa_t *child_sa; enumerator_t *enumerator; - u_int32_t id; + u_int32_t id = 0; + + if (charon->shunts->uninstall(charon->shunts, msg->unroute.name)) + { + fprintf(out, "shunt policy '%s' uninstalled\n", msg->unroute.name); + return; + } enumerator = charon->traps->create_enumerator(charon->traps); while (enumerator->enumerate(enumerator, NULL, &child_sa)) @@ -617,14 +647,20 @@ METHOD(stroke_control_t, unroute, void, if (streq(msg->unroute.name, child_sa->get_name(child_sa))) { id = child_sa->get_reqid(child_sa); - enumerator->destroy(enumerator); - charon->traps->uninstall(charon->traps, id); - fprintf(out, "configuration '%s' unrouted\n", msg->unroute.name); - return; + break; } } enumerator->destroy(enumerator); - fprintf(out, "configuration '%s' not found\n", msg->unroute.name); + + if (id) + { + charon->traps->uninstall(charon->traps, id); + fprintf(out, "configuration '%s' unrouted\n", msg->unroute.name); + } + else + { + fprintf(out, "configuration '%s' not found\n", msg->unroute.name); + } } METHOD(stroke_control_t, destroy, void, diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c index baf02a6da..a2a6d6d9f 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.c +++ b/src/libcharon/plugins/stroke/stroke_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2010 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -17,13 +17,16 @@ #include <sys/types.h> #include <sys/stat.h> #include <limits.h> -#include <glob.h> #include <libgen.h> #include <sys/mman.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> +#ifdef HAVE_GLOB_H +#include <glob.h> +#endif + #include "stroke_cred.h" #include <credentials/certificates/x509.h> @@ -68,15 +71,19 @@ struct private_stroke_cred_t { mem_cred_t *creds; /** + * ignore missing CA basic constraint (i.e. treat all certificates in + * ipsec.conf ca sections and ipsec.d/cacert as CA certificates) + */ + bool force_ca_cert; + + /** * cache CRLs to disk? */ bool cachecrl; }; -/** - * Implementation of stroke_cred_t.load_ca. - */ -static certificate_t* load_ca(private_stroke_cred_t *this, char *filename) +METHOD(stroke_cred_t, load_ca, certificate_t*, + private_stroke_cred_t *this, char *filename) { certificate_t *cert; char path[PATH_MAX]; @@ -90,10 +97,21 @@ static certificate_t* load_ca(private_stroke_cred_t *this, char *filename) snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename); } - cert = lib->creds->create(lib->creds, + if (this->force_ca_cert) + { /* we treat this certificate as a CA certificate even if it has no + * CA basic constraint */ + cert = lib->creds->create(lib->creds, + CRED_CERTIFICATE, CERT_X509, + BUILD_FROM_FILE, path, BUILD_X509_FLAG, X509_CA, + BUILD_END); + } + else + { + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, path, BUILD_END); + } if (cert) { x509_t *x509 = (x509_t*)cert; @@ -110,10 +128,8 @@ static certificate_t* load_ca(private_stroke_cred_t *this, char *filename) return NULL; } -/** - * Implementation of stroke_cred_t.load_peer. - */ -static certificate_t* load_peer(private_stroke_cred_t *this, char *filename) +METHOD(stroke_cred_t, load_peer, certificate_t*, + private_stroke_cred_t *this, char *filename) { certificate_t *cert; char path[PATH_MAX]; @@ -142,6 +158,78 @@ static certificate_t* load_peer(private_stroke_cred_t *this, char *filename) return NULL; } +METHOD(stroke_cred_t, load_pubkey, certificate_t*, + private_stroke_cred_t *this, key_type_t type, char *filename, + identification_t *identity) +{ + certificate_t *cert; + char path[PATH_MAX]; + + if (streq(filename, "%dns")) + { + + } + else if (strncaseeq(filename, "0x", 2) || strncaseeq(filename, "0s", 2)) + { + chunk_t printable_key, rfc3110_key; + public_key_t *key; + + printable_key = chunk_create(filename + 2, strlen(filename) - 2); + rfc3110_key = strncaseeq(filename, "0x", 2) ? + chunk_from_hex(printable_key, NULL) : + chunk_from_base64(printable_key, NULL); + key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, + BUILD_BLOB_DNSKEY, rfc3110_key, + BUILD_END); + free(rfc3110_key.ptr); + if (key) + { + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, + CERT_TRUSTED_PUBKEY, + BUILD_PUBLIC_KEY, key, + BUILD_SUBJECT, identity, + BUILD_END); + key->destroy(key); + if (cert) + { + cert = this->creds->add_cert_ref(this->creds, TRUE, cert); + DBG1(DBG_CFG, " loaded %N public key for \"%Y\"", + key_type_names, type, identity); + return cert; + } + } + DBG1(DBG_CFG, " loading %N public key for \"%Y\" failed", + key_type_names, type, identity); + } + else + { + if (*filename == '/') + { + snprintf(path, sizeof(path), "%s", filename); + } + else + { + snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename); + } + + cert = lib->creds->create(lib->creds, + CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY, + BUILD_FROM_FILE, path, + BUILD_SUBJECT, identity, + BUILD_END); + if (cert) + { + cert = this->creds->add_cert_ref(this->creds, TRUE, cert); + DBG1(DBG_CFG, " loaded %N public key for \"%Y\" from '%s'", + key_type_names, type, identity, filename); + return cert; + } + DBG1(DBG_CFG, " loading %N public key for \"%Y\" from '%s' failed", + key_type_names, type, identity, filename); + } + return NULL; +} + /** * load trusted certificates from a directory */ @@ -172,11 +260,21 @@ static void load_certdir(private_stroke_cred_t *this, char *path, { case CERT_X509: if (flag & X509_CA) - { /* for CA certificates, we strictly require - * the CA basic constraint to be set */ - cert = lib->creds->create(lib->creds, + { + if (this->force_ca_cert) + { /* treat this certificate as CA cert even it has no + * CA basic constraint */ + cert = lib->creds->create(lib->creds, + CRED_CERTIFICATE, CERT_X509, + BUILD_FROM_FILE, file, BUILD_X509_FLAG, + X509_CA, BUILD_END); + } + else + { + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_FROM_FILE, file, BUILD_END); + } if (cert) { x509_t *x509 = (x509_t*)cert; @@ -262,10 +360,8 @@ static void load_certdir(private_stroke_cred_t *this, char *path, enumerator->destroy(enumerator); } -/** - * Implementation of credential_set_t.cache_cert. - */ -static void cache_cert(private_stroke_cred_t *this, certificate_t *cert) +METHOD(stroke_cred_t, cache_cert, void, + private_stroke_cred_t *this, certificate_t *cert) { if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl) { @@ -292,10 +388,8 @@ static void cache_cert(private_stroke_cred_t *this, certificate_t *cert) } } -/** - * Implementation of stroke_cred_t.cachecrl. - */ -static void cachecrl(private_stroke_cred_t *this, bool enabled) +METHOD(stroke_cred_t, cachecrl, void, + private_stroke_cred_t *this, bool enabled) { DBG1(DBG_CFG, "crl caching to %s %s", CRL_DIR, enabled ? "enabled" : "disabled"); @@ -852,7 +946,6 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, if (line.len > strlen("include ") && strneq(line.ptr, "include ", strlen("include "))) { - glob_t buf; char **expanded, *dir, pattern[PATH_MAX]; u_char *pos; @@ -894,18 +987,27 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, dir, (int)line.len, line.ptr); free(dir); } - if (glob(pattern, GLOB_ERR, NULL, &buf) != 0) +#ifdef HAVE_GLOB_H { - DBG1(DBG_CFG, "expanding file expression '%s' failed", pattern); - } - else - { - for (expanded = buf.gl_pathv; *expanded != NULL; expanded++) + glob_t buf; + if (glob(pattern, GLOB_ERR, NULL, &buf) != 0) { - load_secrets(this, *expanded, level + 1, prompt); + DBG1(DBG_CFG, "expanding file expression '%s' failed", + pattern); } + else + { + for (expanded = buf.gl_pathv; *expanded != NULL; expanded++) + { + load_secrets(this, *expanded, level + 1, prompt); + } + } + globfree(&buf); } - globfree(&buf); +#else /* HAVE_GLOB_H */ + /* if glob(3) is not available, try to load pattern directly */ + load_secrets(this, pattern, level + 1, prompt); +#endif /* HAVE_GLOB_H */ continue; } @@ -994,10 +1096,8 @@ static void load_certs(private_stroke_cred_t *this) load_certdir(this, CRL_DIR, CERT_X509_CRL, 0); } -/** - * Implementation of stroke_cred_t.reread. - */ -static void reread(private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt) +METHOD(stroke_cred_t, reread, void, + private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt) { if (msg->reread.flags & REREAD_SECRETS) { @@ -1037,10 +1137,14 @@ static void reread(private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt) } } -/** - * Implementation of stroke_cred_t.destroy - */ -static void destroy(private_stroke_cred_t *this) +METHOD(stroke_cred_t, add_shared, void, + private_stroke_cred_t *this, shared_key_t *shared, linked_list_t *owners) +{ + this->creds->add_shared_list(this->creds, shared, owners); +} + +METHOD(stroke_cred_t, destroy, void, + private_stroke_cred_t *this) { lib->credmgr->remove_set(lib->credmgr, &this->creds->set); this->creds->destroy(this->creds); @@ -1052,27 +1156,36 @@ static void destroy(private_stroke_cred_t *this) */ stroke_cred_t *stroke_cred_create() { - private_stroke_cred_t *this = malloc_thing(private_stroke_cred_t); - - this->public.set.create_private_enumerator = (void*)return_null; - this->public.set.create_cert_enumerator = (void*)return_null; - this->public.set.create_shared_enumerator = (void*)return_null; - this->public.set.create_cdp_enumerator = (void*)return_null; - this->public.set.cache_cert = (void*)cache_cert; - this->public.reread = (void(*)(stroke_cred_t*, stroke_msg_t *msg, FILE*))reread; - this->public.load_ca = (certificate_t*(*)(stroke_cred_t*, char *filename))load_ca; - this->public.load_peer = (certificate_t*(*)(stroke_cred_t*, char *filename))load_peer; - this->public.cachecrl = (void(*)(stroke_cred_t*, bool enabled))cachecrl; - this->public.destroy = (void(*)(stroke_cred_t*))destroy; - - this->creds = mem_cred_create(); + private_stroke_cred_t *this; + + INIT(this, + .public = { + .set = { + .create_private_enumerator = (void*)return_null, + .create_cert_enumerator = (void*)return_null, + .create_shared_enumerator = (void*)return_null, + .create_cdp_enumerator = (void*)return_null, + .cache_cert = (void*)_cache_cert, + }, + .reread = _reread, + .load_ca = _load_ca, + .load_peer = _load_peer, + .load_pubkey = _load_pubkey, + .add_shared = _add_shared, + .cachecrl = _cachecrl, + .destroy = _destroy, + }, + .creds = mem_cred_create(), + ); + lib->credmgr->add_set(lib->credmgr, &this->creds->set); + this->force_ca_cert = lib->settings->get_bool(lib->settings, + "charon.plugins.stroke.ignore_missing_ca_basic_constraint", FALSE); + load_certs(this); load_secrets(this, SECRETS_FILE, 0, NULL); - this->cachecrl = FALSE; - return &this->public; } diff --git a/src/libcharon/plugins/stroke/stroke_cred.h b/src/libcharon/plugins/stroke/stroke_cred.h index ccee7d87c..83e648819 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.h +++ b/src/libcharon/plugins/stroke/stroke_cred.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -26,6 +27,7 @@ #include <stroke_msg.h> #include <credentials/credential_set.h> #include <credentials/certificates/certificate.h> +#include <utils/linked_list.h> typedef struct stroke_cred_t stroke_cred_t; @@ -56,7 +58,7 @@ struct stroke_cred_t { certificate_t* (*load_ca)(stroke_cred_t *this, char *filename); /** - * Load a peer certificate and serve it rhrough the credential_set. + * Load a peer certificate and serve it through the credential_set. * * @param filename file to load peer cert from * @return reference to loaded certificate, or NULL @@ -64,6 +66,26 @@ struct stroke_cred_t { certificate_t* (*load_peer)(stroke_cred_t *this, char *filename); /** + * Load a raw public key and serve it through the credential_set. + * + * @param type type of the raw public key (RSA or ECDSA) + * @param filename file to load raw public key from + * @param identity identity of the raw public key owner + * @return reference to loaded raw public key, or NULL + */ + certificate_t* (*load_pubkey)(stroke_cred_t *this, key_type_t type, + char *filename, identification_t *identity); + + /** + * Add a shared secret to serve through the credential_set. + * + * @param shared shared key to add, gets owned + * @param owners list of owners (identification_t*), gets owned + */ + void (*add_shared)(stroke_cred_t *this, shared_key_t *shared, + linked_list_t *owners); + + /** * Enable/Disable CRL caching to disk. * * @param enabled TRUE to enable, FALSE to disable diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index 6c42f8f8a..514a91e2b 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -15,6 +15,7 @@ #include "stroke_list.h" +#include <inttypes.h> #include <time.h> #ifdef HAVE_MALLINFO @@ -24,6 +25,7 @@ #include <hydra.h> #include <daemon.h> #include <utils/linked_list.h> +#include <plugins/plugin.h> #include <credentials/certificates/x509.h> #include <credentials/certificates/ac.h> #include <credentials/certificates/crl.h> @@ -116,7 +118,7 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all) ike_proposal = ike_sa->get_proposal(ike_sa); - fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s", + fprintf(out, "%12s[%d]: IKE SPIs: %.16"PRIx64"_i%s %.16"PRIx64"_r%s", ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa), id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "", id->get_responder_spi(id), id->is_initiator(id) ? "" : "*"); @@ -221,11 +223,14 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) { u_int16_t encr_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED; u_int16_t encr_size = 0, int_size = 0; + u_int16_t esn = NO_EXT_SEQ_NUMBERS; proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &encr_alg, &encr_size); proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_alg, &int_size); + proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, + &esn, NULL); if (encr_alg != ENCR_UNDEFINED) { @@ -243,21 +248,25 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) fprintf(out, "_%u", int_size); } } + if (esn == EXT_SEQ_NUMBERS) + { + fprintf(out, "/ESN"); + } } now = time_monotonic(NULL); child_sa->get_usestats(child_sa, TRUE, &use_in, &bytes_in); - fprintf(out, ", %llu bytes_i", bytes_in); + fprintf(out, ", %" PRIu64 " bytes_i", bytes_in); if (use_in) { - fprintf(out, " (%ds ago)", now - use_in); + fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_in)); } child_sa->get_usestats(child_sa, FALSE, &use_out, &bytes_out); - fprintf(out, ", %llu bytes_o", bytes_out); + fprintf(out, ", %" PRIu64 " bytes_o", bytes_out); if (use_out) { - fprintf(out, " (%ds ago)", now - use_out); + fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_out)); } fprintf(out, ", rekeying "); @@ -324,7 +333,7 @@ static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local) { if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR)) { - fprintf(out, "EAP_%d-%d authentication", + fprintf(out, "EAP_%" PRIuPTR "-%" PRIuPTR " authentication", (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE), (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR)); } @@ -389,25 +398,27 @@ static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local) } METHOD(stroke_list_t, status, void, - private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all) + private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, + bool all, bool wait) { enumerator_t *enumerator, *children; ike_cfg_t *ike_cfg; child_cfg_t *child_cfg; child_sa_t *child_sa; ike_sa_t *ike_sa; + linked_list_t *my_ts, *other_ts; bool first, found = FALSE; char *name = msg->status.name; + u_int half_open; if (all) { peer_cfg_t *peer_cfg; - plugin_t *plugin; char *pool; host_t *host; u_int32_t dpd; time_t since, now; - u_int size, online, offline; + u_int size, online, offline, i; now = time_monotonic(NULL); since = time(NULL) - (now - this->uptime); @@ -421,21 +432,24 @@ METHOD(stroke_list_t, status, void, mi.arena, mi.hblkhd, mi.uordblks, mi.fordblks); } #endif /* HAVE_MALLINFO */ - fprintf(out, " worker threads: %d idle of %d,", + fprintf(out, " worker threads: %d of %d idle, ", lib->processor->get_idle_threads(lib->processor), lib->processor->get_total_threads(lib->processor)); - fprintf(out, " job queue load: %d,", - lib->processor->get_job_load(lib->processor)); - fprintf(out, " scheduled events: %d\n", - lib->scheduler->get_job_load(lib->scheduler)); - fprintf(out, " loaded plugins: "); - enumerator = lib->plugins->create_plugin_enumerator(lib->plugins); - while (enumerator->enumerate(enumerator, &plugin)) + for (i = 0; i < JOB_PRIO_MAX; i++) { - fprintf(out, "%s ", plugin->get_name(plugin)); + fprintf(out, "%s%d", i == 0 ? "" : "/", + lib->processor->get_working_threads(lib->processor, i)); } - enumerator->destroy(enumerator); - fprintf(out, "\n"); + fprintf(out, " working, job queue: "); + for (i = 0; i < JOB_PRIO_MAX; i++) + { + fprintf(out, "%s%d", i == 0 ? "" : "/", + lib->processor->get_job_load(lib->processor, i)); + } + fprintf(out, ", scheduled: %d\n", + lib->scheduler->get_job_load(lib->scheduler)); + fprintf(out, " loaded plugins: %s\n", + lib->plugins->loaded_plugins(lib->plugins)); first = TRUE; enumerator = this->attribute->create_pool_enumerator(this->attribute); @@ -491,12 +505,11 @@ METHOD(stroke_list_t, status, void, children = peer_cfg->create_child_cfg_enumerator(peer_cfg); while (children->enumerate(children, &child_cfg)) { - linked_list_t *my_ts, *other_ts; - my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL); other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL); - fprintf(out, "%12s: child: %#R=== %#R", child_cfg->get_name(child_cfg), - my_ts, other_ts); + fprintf(out, "%12s: child: %#R=== %#R%N", + child_cfg->get_name(child_cfg), my_ts, other_ts, + ipsec_mode_names, child_cfg->get_mode(child_cfg)); my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); @@ -512,10 +525,39 @@ METHOD(stroke_list_t, status, void, enumerator->destroy(enumerator); } + /* Enumerate shunt policies */ + first = TRUE; + enumerator = charon->shunts->create_enumerator(charon->shunts); + while (enumerator->enumerate(enumerator, &child_cfg)) + { + if (name && !streq(name, child_cfg->get_name(child_cfg))) + { + continue; + } + if (first) + { + fprintf(out, "Shunted Connections:\n"); + first = FALSE; + } + my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL); + other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL); + fprintf(out, "%12s: %#R=== %#R%N\n", + child_cfg->get_name(child_cfg), my_ts, other_ts, + ipsec_mode_names, child_cfg->get_mode(child_cfg)); + my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); + other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); + } + enumerator->destroy(enumerator); + + /* Enumerate traps */ first = TRUE; enumerator = charon->traps->create_enumerator(charon->traps); while (enumerator->enumerate(enumerator, NULL, &child_sa)) { + if (name && !streq(name, child_sa->get_name(child_sa))) + { + continue; + } if (first) { fprintf(out, "Routed Connections:\n"); @@ -525,12 +567,17 @@ METHOD(stroke_list_t, status, void, } enumerator->destroy(enumerator); - fprintf(out, "Security Associations:\n"); - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + half_open = charon->ike_sa_manager->get_half_open_count( + charon->ike_sa_manager, NULL); + fprintf(out, "Security Associations (%u up, %u connecting):\n", + charon->ike_sa_manager->get_count(charon->ike_sa_manager) - half_open, + half_open); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, wait); while (enumerator->enumerate(enumerator, &ike_sa)) { bool ike_printed = FALSE; - iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa); + enumerator_t *children = ike_sa->create_child_sa_enumerator(ike_sa); if (name == NULL || streq(name, ike_sa->get_name(ike_sa))) { @@ -539,7 +586,7 @@ METHOD(stroke_list_t, status, void, ike_printed = TRUE; } - while (children->iterate(children, (void**)&child_sa)) + while (children->enumerate(children, (void**)&child_sa)) { if (name == NULL || streq(name, child_sa->get_name(child_sa))) { @@ -582,35 +629,30 @@ static linked_list_t* create_unique_cert_list(certificate_type_t type) while (enumerator->enumerate(enumerator, (void**)&cert)) { - iterator_t *iterator = list->create_iterator(list, TRUE); + enumerator_t *added = list->create_enumerator(list); identification_t *issuer = cert->get_issuer(cert); - bool previous_same, same = FALSE, last = TRUE; + bool previous_same, same = FALSE, found = FALSE; certificate_t *list_cert; - while (iterator->iterate(iterator, (void**)&list_cert)) + while (added->enumerate(added, (void**)&list_cert)) { - /* exit if we have a duplicate? */ if (list_cert->equals(list_cert, cert)) - { - last = FALSE; + { /* stop if we found a duplicate*/ + found = TRUE; break; } - /* group certificates with same issuer */ previous_same = same; same = list_cert->has_issuer(list_cert, issuer); if (previous_same && !same) - { - iterator->insert_before(iterator, (void *)cert->get_ref(cert)); - last = FALSE; + { /* group certificates with same issuer */ break; } } - iterator->destroy(iterator); - - if (last) + if (!found) { - list->insert_last(list, (void *)cert->get_ref(cert)); + list->insert_before(list, added, cert->get_ref(cert)); } + added->destroy(added); } enumerator->destroy(enumerator); return list; @@ -657,12 +699,14 @@ static void list_public_key(public_key_t *public, FILE *out) static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out) { bool first = TRUE; - - enumerator_t *enumerator = list->create_enumerator(list); + time_t now = time(NULL), notBefore, notAfter; + enumerator_t *enumerator; certificate_t *cert; + enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, (void**)&cert)) { + identification_t *subject = cert->get_subject(cert); public_key_t *public = cert->get_public_key(cert); if (public) @@ -675,6 +719,41 @@ static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out) } fprintf(out, "\n"); + /* list subject if available */ + if (subject->get_type(subject) != ID_KEY_ID) + { + fprintf(out, " subject: %#Y\n", subject); + } + + /* list validity if available*/ + cert->get_validity(cert, &now, ¬Before, ¬After); + if (notBefore != UNDEFINED_TIME && notAfter != UNDEFINED_TIME) + { + fprintf(out, " validity: not before %T, ", ¬Before, utc); + if (now < notBefore) + { + fprintf(out, "not valid yet (valid in %V)\n", &now, ¬Before); + } + else + { + fprintf(out, "ok\n"); + } + fprintf(out, " not after %T, ", ¬After, utc); + if (now > notAfter) + { + fprintf(out, "expired (%V ago)\n", &now, ¬After); + } + else + { + fprintf(out, "ok"); + if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24) + { + fprintf(out, " (expires in %V)", &now, ¬After); + } + fprintf(out, " \n"); + } + } + list_public_key(public, out); public->destroy(public); } @@ -791,7 +870,7 @@ static void stroke_list_certs(linked_list_t *list, char *label, fprintf(out, " subject: \"%Y\"\n", cert->get_subject(cert)); fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); - serial = x509->get_serial(x509); + serial = chunk_skip_zero(x509->get_serial(x509)); fprintf(out, " serial: %#B\n", &serial); /* list validity */ @@ -904,7 +983,7 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out) { fprintf(out, " hissuer: \"%Y\"\n", id); } - chunk = ac->get_holderSerial(ac); + chunk = chunk_skip_zero(ac->get_holderSerial(ac)); if (chunk.ptr) { fprintf(out, " hserial: %#B\n", &chunk); @@ -916,7 +995,7 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out) groups->destroy(groups); } fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); - chunk = ac->get_serial(ac); + chunk = chunk_skip_zero(ac->get_serial(ac)); fprintf(out, " serial: %#B\n", &chunk); /* list validity */ @@ -973,13 +1052,14 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out) fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); /* list optional crlNumber */ - chunk = crl->get_serial(crl); + chunk = chunk_skip_zero(crl->get_serial(crl)); if (chunk.ptr) { fprintf(out, " serial: %#B\n", &chunk); } if (crl->is_delta_crl(crl, &chunk)) { + chunk = chunk_skip_zero(chunk); fprintf(out, " delta for: %#B\n", &chunk); } @@ -1157,6 +1237,58 @@ static void list_algs(FILE *out) fprintf(out, "\n"); } +/** + * List loaded plugin information + */ +static void list_plugins(FILE *out) +{ + plugin_feature_t *features, *fp; + enumerator_t *enumerator; + linked_list_t *list; + plugin_t *plugin; + int count, i; + bool loaded; + char *str; + + fprintf(out, "\n"); + fprintf(out, "List of loaded Plugins:\n"); + fprintf(out, "\n"); + + enumerator = lib->plugins->create_plugin_enumerator(lib->plugins); + while (enumerator->enumerate(enumerator, &plugin, &list)) + { + fprintf(out, "%s:\n", plugin->get_name(plugin)); + if (plugin->get_features) + { + count = plugin->get_features(plugin, &features); + for (i = 0; i < count; i++) + { + str = plugin_feature_get_string(&features[i]); + switch (features[i].kind) + { + case FEATURE_PROVIDE: + fp = &features[i]; + loaded = list->find_first(list, NULL, + (void**)&fp) == SUCCESS; + fprintf(out, " %s%s\n", + str, loaded ? "" : " (not loaded)"); + break; + case FEATURE_DEPENDS: + fprintf(out, " %s\n", str); + break; + case FEATURE_SDEPEND: + fprintf(out, " %s(soft)\n", str); + break; + default: + break; + } + free(str); + } + } + } + enumerator->destroy(enumerator); +} + METHOD(stroke_list_t, list, void, private_stroke_list_t *this, stroke_msg_t *msg, FILE *out) { @@ -1228,6 +1360,10 @@ METHOD(stroke_list_t, list, void, { list_algs(out); } + if (msg->list.flags & LIST_PLUGINS) + { + list_plugins(out); + } } /** diff --git a/src/libcharon/plugins/stroke/stroke_list.h b/src/libcharon/plugins/stroke/stroke_list.h index b5bedc6c2..a0d2d18cc 100644 --- a/src/libcharon/plugins/stroke/stroke_list.h +++ b/src/libcharon/plugins/stroke/stroke_list.h @@ -47,8 +47,10 @@ struct stroke_list_t { * @param msg stroke message * @param out stroke console stream * @param all TRUE for "statusall" + * @param wait TRUE to wait for IKE_SA entries, FALSE to skip if locked */ - void (*status)(stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all); + void (*status)(stroke_list_t *this, stroke_msg_t *msg, FILE *out, + bool all, bool wait); /** * Log pool leases to stroke console. diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 88d0270d8..57648feb8 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2011-2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -20,13 +21,15 @@ #include <sys/stat.h> #include <sys/socket.h> #include <sys/un.h> -#include <sys/fcntl.h> #include <unistd.h> #include <errno.h> #include <hydra.h> #include <daemon.h> +#include <threading/mutex.h> #include <threading/thread.h> +#include <threading/condvar.h> +#include <utils/linked_list.h> #include <processing/jobs/callback_job.h> #include "stroke_config.h" @@ -36,6 +39,12 @@ #include "stroke_attribute.h" #include "stroke_list.h" +/** + * To avoid clogging the thread pool with (blocking) jobs, we limit the number + * of concurrently handled stroke commands. + */ +#define MAX_CONCURRENT_DEFAULT 4 + typedef struct stroke_job_context_t stroke_job_context_t; typedef struct private_stroke_socket_t private_stroke_socket_t; @@ -57,7 +66,37 @@ struct private_stroke_socket_t { /** * job accepting stroke messages */ - callback_job_t *job; + callback_job_t *receiver; + + /** + * job handling stroke messages + */ + callback_job_t *handler; + + /** + * queued stroke commands + */ + linked_list_t *commands; + + /** + * lock for command list + */ + mutex_t *mutex; + + /** + * condvar to signal the arrival or completion of commands + */ + condvar_t *condvar; + + /** + * the number of currently handled commands + */ + u_int handling; + + /** + * the maximum number of concurrently handled commands + */ + u_int max_concurrent; /** * configuration backend @@ -85,7 +124,7 @@ struct private_stroke_socket_t { stroke_ca_t *ca; /** - * Status information logging + * status information logging */ stroke_list_t *list; }; @@ -146,6 +185,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end) pop_string(msg, &end->auth2); pop_string(msg, &end->id); pop_string(msg, &end->id2); + pop_string(msg, &end->rsakey); pop_string(msg, &end->cert); pop_string(msg, &end->cert2); pop_string(msg, &end->ca); @@ -161,6 +201,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end) DBG2(DBG_CFG, " %sauth2=%s", label, end->auth2); DBG2(DBG_CFG, " %sid=%s", label, end->id); DBG2(DBG_CFG, " %sid2=%s", label, end->id2); + DBG2(DBG_CFG, " %srsakey=%s", label, end->rsakey); DBG2(DBG_CFG, " %scert=%s", label, end->cert); DBG2(DBG_CFG, " %scert2=%s", label, end->cert2); DBG2(DBG_CFG, " %sca=%s", label, end->ca); @@ -190,6 +231,9 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg) DBG2(DBG_CFG, " aaa_identity=%s", msg->add_conn.aaa_identity); DBG2(DBG_CFG, " ike=%s", msg->add_conn.algorithms.ike); DBG2(DBG_CFG, " esp=%s", msg->add_conn.algorithms.esp); + DBG2(DBG_CFG, " dpddelay=%d", msg->add_conn.dpd.delay); + DBG2(DBG_CFG, " dpdaction=%d", msg->add_conn.dpd.action); + DBG2(DBG_CFG, " closeaction=%d", msg->add_conn.close_action); DBG2(DBG_CFG, " mediation=%s", msg->add_conn.ikeme.mediation ? "yes" : "no"); DBG2(DBG_CFG, " mediated_by=%s", msg->add_conn.ikeme.mediated_by); DBG2(DBG_CFG, " me_peerid=%s", msg->add_conn.ikeme.peerid); @@ -322,11 +366,11 @@ static void stroke_del_ca(private_stroke_socket_t *this, * show status of daemon */ static void stroke_status(private_stroke_socket_t *this, - stroke_msg_t *msg, FILE *out, bool all) + stroke_msg_t *msg, FILE *out, bool all, bool wait) { pop_string(msg, &(msg->status.name)); - this->list->status(this->list, msg, out, all); + this->list->status(this->list, msg, out, all, wait); } /** @@ -382,7 +426,7 @@ static void stroke_export(private_stroke_socket_t *this, { pop_string(msg, &msg->export.selector); - if (msg->purge.flags & EXPORT_X509) + if (msg->export.flags & EXPORT_X509) { enumerator_t *enumerator; identification_t *id; @@ -418,6 +462,33 @@ static void stroke_leases(private_stroke_socket_t *this, } /** + * Show memory usage + */ +static void stroke_memusage(private_stroke_socket_t *this, + stroke_msg_t *msg, FILE *out) +{ + if (lib->leak_detective) + { + lib->leak_detective->usage(lib->leak_detective, out); + } +} + +/** + * Set username and password for a connection + */ +static void stroke_user_creds(private_stroke_socket_t *this, + stroke_msg_t *msg, FILE *out) +{ + pop_string(msg, &msg->user_creds.name); + pop_string(msg, &msg->user_creds.username); + pop_string(msg, &msg->user_creds.password); + + DBG1(DBG_CFG, "received stroke: user-creds '%s'", msg->user_creds.name); + + this->config->set_user_credentials(this->config, msg, out); +} + +/** * set the verbosity debug output */ static void stroke_loglevel(private_stroke_socket_t *this, @@ -433,7 +504,7 @@ static void stroke_loglevel(private_stroke_socket_t *this, msg->loglevel.level, msg->loglevel.type); group = enum_from_name(debug_names, msg->loglevel.type); - if (group < 0) + if ((int)group < 0) { fprintf(out, "invalid type (%s)!\n", msg->loglevel.type); return; @@ -475,6 +546,18 @@ static void stroke_job_context_destroy(stroke_job_context_t *this) } /** + * called to signal the completion of a command + */ +static inline job_requeue_t job_processed(private_stroke_socket_t *this) +{ + this->mutex->lock(this->mutex); + this->handling--; + this->condvar->signal(this->condvar); + this->mutex->unlock(this->mutex); + return JOB_REQUEUE_NONE; +} + +/** * process a stroke request from the socket pointed by "fd" */ static job_requeue_t process(stroke_job_context_t *ctx) @@ -492,7 +575,7 @@ static job_requeue_t process(stroke_job_context_t *ctx) { DBG1(DBG_CFG, "reading length of stroke message failed: %s", strerror(errno)); - return JOB_REQUEUE_NONE; + return job_processed(this); } /* read message */ @@ -501,14 +584,14 @@ static job_requeue_t process(stroke_job_context_t *ctx) if (bytes_read != msg_length) { DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno)); - return JOB_REQUEUE_NONE; + return job_processed(this); } out = fdopen(strokefd, "w+"); if (out == NULL) { DBG1(DBG_CFG, "opening stroke output channel failed: %s", strerror(errno)); - return JOB_REQUEUE_NONE; + return job_processed(this); } DBG3(DBG_CFG, "stroke message %b", (void*)msg, msg_length); @@ -534,10 +617,13 @@ static job_requeue_t process(stroke_job_context_t *ctx) stroke_rekey(this, msg, out); break; case STR_STATUS: - stroke_status(this, msg, out, FALSE); + stroke_status(this, msg, out, FALSE, TRUE); break; case STR_STATUS_ALL: - stroke_status(this, msg, out, TRUE); + stroke_status(this, msg, out, TRUE, TRUE); + break; + case STR_STATUS_ALL_NOBLK: + stroke_status(this, msg, out, TRUE, FALSE); break; case STR_ADD_CONN: stroke_add_conn(this, msg); @@ -572,6 +658,12 @@ static job_requeue_t process(stroke_job_context_t *ctx) case STR_LEASES: stroke_leases(this, msg, out); break; + case STR_MEMUSAGE: + stroke_memusage(this, msg, out); + break; + case STR_USER_CREDS: + stroke_user_creds(this, msg, out); + break; default: DBG1(DBG_CFG, "received unknown stroke"); break; @@ -579,11 +671,38 @@ static job_requeue_t process(stroke_job_context_t *ctx) fclose(out); /* fclose() closes underlying FD */ ctx->fd = 0; - return JOB_REQUEUE_NONE; + return job_processed(this); +} + +/** + * Handle queued stroke commands + */ +static job_requeue_t handle(private_stroke_socket_t *this) +{ + stroke_job_context_t *ctx; + callback_job_t *job; + bool oldstate; + + this->mutex->lock(this->mutex); + thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex); + oldstate = thread_cancelability(TRUE); + while (this->commands->get_count(this->commands) == 0 || + this->handling >= this->max_concurrent) + { + this->condvar->wait(this->condvar, this->mutex); + } + thread_cancelability(oldstate); + this->commands->remove_first(this->commands, (void**)&ctx); + this->handling++; + thread_cleanup_pop(TRUE); + job = callback_job_create_with_prio((callback_job_cb_t)process, ctx, + (void*)stroke_job_context_destroy, this->handler, JOB_PRIO_HIGH); + lib->processor->queue_job(lib->processor, (job_t*)job); + return JOB_REQUEUE_DIRECT; } /** - * Implementation of private_stroke_socket_t.stroke_receive. + * Accept stroke commands and queue them to be handled */ static job_requeue_t receive(private_stroke_socket_t *this) { @@ -591,7 +710,6 @@ static job_requeue_t receive(private_stroke_socket_t *this) int strokeaddrlen = sizeof(strokeaddr); int strokefd; bool oldstate; - callback_job_t *job; stroke_job_context_t *ctx; oldstate = thread_cancelability(TRUE); @@ -604,17 +722,18 @@ static job_requeue_t receive(private_stroke_socket_t *this) return JOB_REQUEUE_FAIR; } - ctx = malloc_thing(stroke_job_context_t); - ctx->fd = strokefd; - ctx->this = this; - job = callback_job_create((callback_job_cb_t)process, - ctx, (void*)stroke_job_context_destroy, this->job); - lib->processor->queue_job(lib->processor, (job_t*)job); + INIT(ctx, + .fd = strokefd, + .this = this, + ); + this->mutex->lock(this->mutex); + this->commands->insert_last(this->commands, ctx); + this->condvar->signal(this->condvar); + this->mutex->unlock(this->mutex); return JOB_REQUEUE_FAIR; } - /** * initialize and open stroke socket */ @@ -659,12 +778,14 @@ static bool open_socket(private_stroke_socket_t *this) return TRUE; } -/** - * Implementation of stroke_socket_t.destroy - */ -static void destroy(private_stroke_socket_t *this) +METHOD(stroke_socket_t, destroy, void, + private_stroke_socket_t *this) { - this->job->cancel(this->job); + this->handler->cancel(this->handler); + this->receiver->cancel(this->receiver); + this->commands->destroy_function(this->commands, (void*)stroke_job_context_destroy); + this->condvar->destroy(this->condvar); + this->mutex->destroy(this->mutex); lib->credmgr->remove_set(lib->credmgr, &this->ca->set); lib->credmgr->remove_set(lib->credmgr, &this->cred->set); charon->backends->remove_backend(charon->backends, &this->config->backend); @@ -683,9 +804,13 @@ static void destroy(private_stroke_socket_t *this) */ stroke_socket_t *stroke_socket_create() { - private_stroke_socket_t *this = malloc_thing(private_stroke_socket_t); + private_stroke_socket_t *this; - this->public.destroy = (void(*)(stroke_socket_t*))destroy; + INIT(this, + .public = { + .destroy = _destroy, + }, + ); if (!open_socket(this)) { @@ -700,14 +825,24 @@ stroke_socket_t *stroke_socket_create() this->control = stroke_control_create(); this->list = stroke_list_create(this->attribute); + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT); + this->commands = linked_list_create(); + this->max_concurrent = lib->settings->get_int(lib->settings, + "charon.plugins.stroke.max_concurrent", MAX_CONCURRENT_DEFAULT); + lib->credmgr->add_set(lib->credmgr, &this->ca->set); lib->credmgr->add_set(lib->credmgr, &this->cred->set); charon->backends->add_backend(charon->backends, &this->config->backend); hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider); - this->job = callback_job_create((callback_job_cb_t)receive, - this, NULL, NULL); - lib->processor->queue_job(lib->processor, (job_t*)this->job); + this->receiver = callback_job_create_with_prio((callback_job_cb_t)receive, + this, NULL, NULL, JOB_PRIO_CRITICAL); + lib->processor->queue_job(lib->processor, (job_t*)this->receiver); + + this->handler = callback_job_create_with_prio((callback_job_cb_t)handle, + this, NULL, NULL, JOB_PRIO_CRITICAL); + lib->processor->queue_job(lib->processor, (job_t*)this->handler); return &this->public; } diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.am b/src/libcharon/plugins/tnc_ifmap/Makefile.am new file mode 100644 index 000000000..b8a57b119 --- /dev/null +++ b/src/libcharon/plugins/tnc_ifmap/Makefile.am @@ -0,0 +1,21 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon ${axis2c_CFLAGS} + +AM_CFLAGS = -rdynamic + +libstrongswan_tnc_ifmap_la_LIBADD = ${axis2c_LIBS} -laxutil -laxis2_engine -laxis2_http_sender + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-tnc-ifmap.la +else +plugin_LTLIBRARIES = libstrongswan-tnc-ifmap.la +endif + +libstrongswan_tnc_ifmap_la_SOURCES = \ + tnc_ifmap_plugin.h tnc_ifmap_plugin.c \ + tnc_ifmap_listener.h tnc_ifmap_listener.c \ + tnc_ifmap_soap.h tnc_ifmap_soap.c + +libstrongswan_tnc_ifmap_la_LDFLAGS = -module -avoid-version + diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in new file mode 100644 index 000000000..54deb7cd7 --- /dev/null +++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in @@ -0,0 +1,620 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libcharon/plugins/tnc_ifmap +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libstrongswan_tnc_ifmap_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libstrongswan_tnc_ifmap_la_OBJECTS = tnc_ifmap_plugin.lo \ + tnc_ifmap_listener.lo tnc_ifmap_soap.lo +libstrongswan_tnc_ifmap_la_OBJECTS = \ + $(am_libstrongswan_tnc_ifmap_la_OBJECTS) +libstrongswan_tnc_ifmap_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_tnc_ifmap_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_tnc_ifmap_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_tnc_ifmap_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstrongswan_tnc_ifmap_la_SOURCES) +DIST_SOURCES = $(libstrongswan_tnc_ifmap_la_SOURCES) +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@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +default_pkcs11 = @default_pkcs11@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +oldincludedir = @oldincludedir@ +openac_plugins = @openac_plugins@ +p_plugins = @p_plugins@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pluto_plugins = @pluto_plugins@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon ${axis2c_CFLAGS} + +AM_CFLAGS = -rdynamic +libstrongswan_tnc_ifmap_la_LIBADD = ${axis2c_LIBS} -laxutil -laxis2_engine -laxis2_http_sender +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-ifmap.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-ifmap.la +libstrongswan_tnc_ifmap_la_SOURCES = \ + tnc_ifmap_plugin.h tnc_ifmap_plugin.c \ + tnc_ifmap_listener.h tnc_ifmap_listener.c \ + tnc_ifmap_soap.h tnc_ifmap_soap.c + +libstrongswan_tnc_ifmap_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_ifmap/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_ifmap/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libstrongswan-tnc-ifmap.la: $(libstrongswan_tnc_ifmap_la_OBJECTS) $(libstrongswan_tnc_ifmap_la_DEPENDENCIES) + $(libstrongswan_tnc_ifmap_la_LINK) $(am_libstrongswan_tnc_ifmap_la_rpath) $(libstrongswan_tnc_ifmap_la_OBJECTS) $(libstrongswan_tnc_ifmap_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_ifmap_listener.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_ifmap_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_ifmap_soap.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c new file mode 100644 index 000000000..4fd33696c --- /dev/null +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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. + */ + +#include "tnc_ifmap_listener.h" +#include "tnc_ifmap_soap.h" + +#include <daemon.h> +#include <hydra.h> +#include <debug.h> + +typedef struct private_tnc_ifmap_listener_t private_tnc_ifmap_listener_t; + +/** + * Private data of an tnc_ifmap_listener_t object. + */ +struct private_tnc_ifmap_listener_t { + + /** + * Public tnc_ifmap_listener_t interface. + */ + tnc_ifmap_listener_t public; + + /** + * TNC IF-MAP 2.0 SOAP interface + */ + tnc_ifmap_soap_t *ifmap; + +}; + +/** + * Publish PEP device-ip metadata + */ +static bool publish_device_ip_addresses(private_tnc_ifmap_listener_t *this) +{ + enumerator_t *enumerator; + host_t *host; + bool success = TRUE; + + enumerator = hydra->kernel_interface->create_address_enumerator( + hydra->kernel_interface, FALSE, FALSE); + while (enumerator->enumerate(enumerator, &host)) + { + if (!this->ifmap->publish_device_ip(this->ifmap, host)) + { + success = FALSE; + break; + } + } + enumerator->destroy(enumerator); + + return success; +} + +/** + * Publish all IKE_SA metadata + */ +static bool reload_metadata(private_tnc_ifmap_listener_t *this) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + bool success = TRUE; + + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, FALSE); + while (enumerator->enumerate(enumerator, &ike_sa)) + { + if (ike_sa->get_state(ike_sa) != IKE_ESTABLISHED) + { + continue; + } + if (!this->ifmap->publish_ike_sa(this->ifmap, ike_sa, TRUE)) + { + success = FALSE; + break; + } + } + enumerator->destroy(enumerator); + + return success; +} + +METHOD(listener_t, ike_updown, bool, + private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, bool up) +{ + if (ike_sa->get_state(ike_sa) != IKE_CONNECTING) + { + this->ifmap->publish_ike_sa(this->ifmap, ike_sa, up); + } + return TRUE; +} + +METHOD(listener_t, alert, bool, + private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, alert_t alert, + va_list args) +{ + if (alert == ALERT_PEER_AUTH_FAILED) + { + this->ifmap->publish_enforcement_report(this->ifmap, + ike_sa->get_other_host(ike_sa), + "block", "authentication failed"); + } + return TRUE; +} + +METHOD(tnc_ifmap_listener_t, destroy, void, + private_tnc_ifmap_listener_t *this) +{ + DESTROY_IF(this->ifmap); + free(this); +} + +/** + * See header + */ +tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload) +{ + private_tnc_ifmap_listener_t *this; + + INIT(this, + .public = { + .listener = { + .ike_updown = _ike_updown, + .alert = _alert, + }, + .destroy = _destroy, + }, + .ifmap = tnc_ifmap_soap_create(), + ); + + if (!this->ifmap) + { + destroy(this); + return NULL; + } + if (!this->ifmap->newSession(this->ifmap)) + { + destroy(this); + return NULL; + } + if (!this->ifmap->purgePublisher(this->ifmap)) + { + destroy(this); + return NULL; + } + if (!publish_device_ip_addresses(this)) + { + destroy(this); + return NULL; + } + if (reload) + { + if (!reload_metadata(this)) + { + destroy(this); + return NULL; + } + } + + return &this->public; +} + diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h new file mode 100644 index 000000000..878505b38 --- /dev/null +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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 tnc_ifmap_listener tnc_ifmap_listener + * @{ @ingroup tnc_ifmap + */ + +#ifndef TNC_IFMAP_LISTENER_H_ +#define TNC_IFMAP_LISTENER_H_ + +#include <bus/bus.h> + +typedef struct tnc_ifmap_listener_t tnc_ifmap_listener_t; + +/** + * Listener which collects information on IKE_SAs + */ +struct tnc_ifmap_listener_t { + + /** + * Implements listener_t. + */ + listener_t listener; + + /** + * Destroy a tnc_ifmap_listener_t. + */ + void (*destroy)(tnc_ifmap_listener_t *this); +}; + +/** + * Create a tnc_ifmap_listener instance. + * + * @param reload reload all IKE_SA metadata + */ +tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload); + +#endif /** TNC_IFMAP_LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c new file mode 100644 index 000000000..de4d12e0b --- /dev/null +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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. + */ + +#include "tnc_ifmap_plugin.h" +#include "tnc_ifmap_listener.h" + +#include <daemon.h> + +typedef struct private_tnc_ifmap_plugin_t private_tnc_ifmap_plugin_t; + +/** + * private data of tnc_ifmap plugin + */ +struct private_tnc_ifmap_plugin_t { + + /** + * implements plugin interface + */ + tnc_ifmap_plugin_t public; + + /** + * Listener interface, listens to CHILD_SA state changes + */ + tnc_ifmap_listener_t *listener; +}; + +METHOD(plugin_t, get_name, char*, + private_tnc_ifmap_plugin_t *this) +{ + return "tnc-ifmap"; +} + +METHOD(plugin_t, reload, bool, + private_tnc_ifmap_plugin_t *this) +{ + if (this->listener) + { + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); + } + + this->listener = tnc_ifmap_listener_create(TRUE); + if (!this->listener) + { + return FALSE; + } + + charon->bus->add_listener(charon->bus, &this->listener->listener); + return TRUE; +} + +METHOD(plugin_t, destroy, void, + private_tnc_ifmap_plugin_t *this) +{ + if (this->listener) + { + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); + } + free(this); +} + +/* + * see header file + */ +plugin_t *tnc_ifmap_plugin_create() +{ + private_tnc_ifmap_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .reload = _reload, + .destroy = _destroy, + }, + }, + .listener = tnc_ifmap_listener_create(FALSE), + ); + + if (this->listener) + { + charon->bus->add_listener(charon->bus, &this->listener->listener); + } + return &this->public.plugin; +} + diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h new file mode 100644 index 000000000..8172be7c9 --- /dev/null +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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 tnc_ifmap tnc_ifmap + * @ingroup cplugins + * + * @defgroup tnc_ifmap_plugin tnc_ifmap_plugin + * @{ @ingroup tnc_ifmap + */ + +#ifndef TNC_IFMAP_PLUGIN_H_ +#define TNC_IFMAP_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct tnc_ifmap_plugin_t tnc_ifmap_plugin_t; + +/** + * TNC IF-MAP plugin + */ +struct tnc_ifmap_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** TNC_IFMAP_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c new file mode 100644 index 000000000..913cdab12 --- /dev/null +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c @@ -0,0 +1,859 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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. + */ + +#include "tnc_ifmap_soap.h" + +#include <debug.h> + +#include <axis2_util.h> +#include <axis2_client.h> +#include <axis2_http_transport.h> +#include <axis2_http_transport_sender.h> +#include <axiom_soap.h> + +#define IFMAP_NS "http://www.trustedcomputinggroup.org/2010/IFMAP/2" +#define IFMAP_META_NS "http://www.trustedcomputinggroup.org/2010/IFMAP-METADATA/2" +#define IFMAP_LOGFILE "strongswan_ifmap.log" +#define IFMAP_SERVER "https://localhost:8443/" + +typedef struct private_tnc_ifmap_soap_t private_tnc_ifmap_soap_t; + +/** + * Private data of an tnc_ifmap_soap_t object. + */ +struct private_tnc_ifmap_soap_t { + + /** + * Public tnc_ifmap_soap_t interface. + */ + tnc_ifmap_soap_t public; + + /** + * Axis2/C environment + */ + axutil_env_t *env; + + /** + * Axis2 service client + */ + axis2_svc_client_t* svc_client; + + /** + * SOAP Session ID + */ + char *session_id; + + /** + * IF-MAP Publisher ID + */ + char *ifmap_publisher_id; + + /** + * PEP and PDP device name + */ + char *device_name; + +}; + +/** + * Send request and receive result via SOAP + */ +static axiom_element_t* send_receive(private_tnc_ifmap_soap_t *this, + char *request_qname, axiom_node_t *request, + char *receipt_qname, axiom_node_t **result) + +{ + axiom_node_t *parent, *node; + axiom_element_t *parent_el, *el; + axutil_qname_t *qname; + + /* send request and receive result */ + DBG2(DBG_TNC, "sending ifmap %s", request_qname); + + parent = axis2_svc_client_send_receive(this->svc_client, this->env, request); + if (!parent) + { + DBG1(DBG_TNC, "no ifmap %s received from MAP server", receipt_qname); + return NULL; + } + DBG2(DBG_TNC, "received ifmap %s", receipt_qname); + + /* extract the parent element */ + parent_el = (axiom_element_t*)axiom_node_get_data_element(parent, this->env); + + /* look for a child node with the given receipt qname */ + qname = axutil_qname_create_from_string(this->env, strdup(receipt_qname)); + el = axiom_element_get_first_child_with_qname(parent_el, this->env, qname, + parent, &node); + axutil_qname_free(qname, this->env); + + if (el) + { + if (result) + { + *result = parent; + } + else + { + /* no further processing requested */ + axiom_node_free_tree(parent, this->env); + } + return el; + } + DBG1(DBG_TNC, "child node with qname '%s' not found", receipt_qname); + + /* free parent in the error case */ + axiom_node_free_tree(parent, this->env); + + return NULL; +} + +METHOD(tnc_ifmap_soap_t, newSession, bool, + private_tnc_ifmap_soap_t *this) +{ + axiom_node_t *request, *result; + axiom_element_t *el; + axiom_namespace_t *ns; + axis2_char_t *value; + + + /* build newSession request */ + ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap"); + el = axiom_element_create(this->env, NULL, "newSession", ns, &request); + + /* send newSession request and receive newSessionResult */ + el = send_receive(this, "newSession", request, "newSessionResult", &result); + if (!el) + { + return FALSE; + } + + /* get session-id */ + value = axiom_element_get_attribute_value_by_name(el, this->env, + "session-id"); + this->session_id = strdup(value); + + /* get ifmap-publisher-id */ + value = axiom_element_get_attribute_value_by_name(el, this->env, + "ifmap-publisher-id"); + this->ifmap_publisher_id = strdup(value); + + DBG1(DBG_TNC, "session-id: %s, ifmap-publisher-id: %s", + this->session_id, this->ifmap_publisher_id); + + /* set PEP and PDP device name (defaults to IF-MAP Publisher ID) */ + this->device_name = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-ifmap.device_name", + this->ifmap_publisher_id); + this->device_name = strdup(this->device_name); + + /* free result */ + axiom_node_free_tree(result, this->env); + + return this->session_id && this->ifmap_publisher_id; +} + +METHOD(tnc_ifmap_soap_t, purgePublisher, bool, + private_tnc_ifmap_soap_t *this) +{ + axiom_node_t *request; + axiom_element_t *el; + axiom_namespace_t *ns; + axiom_attribute_t *attr; + + /* build purgePublisher request */ + ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap"); + el = axiom_element_create(this->env, NULL, "purgePublisher", ns, &request); + attr = axiom_attribute_create(this->env, "session-id", + this->session_id, NULL); + axiom_element_add_attribute(el, this->env, attr, request); + attr = axiom_attribute_create(this->env, "ifmap-publisher-id", + this->ifmap_publisher_id, NULL); + axiom_element_add_attribute(el, this->env, attr, request); + + /* send purgePublisher request and receive purgePublisherReceived */ + return send_receive(this, "purgePublisher", request, + "purgePublisherReceived", NULL); +} + +/** + * Create an access-request based on device_name and ike_sa_id + */ +static axiom_node_t* create_access_request(private_tnc_ifmap_soap_t *this, + u_int32_t id) +{ + axiom_element_t *el; + axiom_node_t *node; + axiom_attribute_t *attr; + char buf[BUF_LEN]; + + el = axiom_element_create(this->env, NULL, "access-request", NULL, &node); + + snprintf(buf, BUF_LEN, "%s:%d", this->device_name, id); + attr = axiom_attribute_create(this->env, "name", buf, NULL); + axiom_element_add_attribute(el, this->env, attr, node); + + return node; +} + +/** + * Create an identity + */ +static axiom_node_t* create_identity(private_tnc_ifmap_soap_t *this, + identification_t *id, bool is_user) +{ + axiom_element_t *el; + axiom_node_t *node; + axiom_attribute_t *attr; + char buf[BUF_LEN], *id_type; + + el = axiom_element_create(this->env, NULL, "identity", NULL, &node); + + snprintf(buf, BUF_LEN, "%Y", id); + attr = axiom_attribute_create(this->env, "name", buf, NULL); + axiom_element_add_attribute(el, this->env, attr, node); + + switch (id->get_type(id)) + { + case ID_IPV4_ADDR: + id_type = "other"; + attr = axiom_attribute_create(this->env, "other-type-definition", + "36906:ipv4-address", NULL); + axiom_element_add_attribute(el, this->env, attr, node); + break; + case ID_FQDN: + id_type = is_user ? "username" : "dns-name"; + break; + case ID_RFC822_ADDR: + id_type = "email-address"; + break; + case ID_IPV6_ADDR: + id_type = "other"; + attr = axiom_attribute_create(this->env, "other-type-definition", + "36906:ipv6-address", NULL); + axiom_element_add_attribute(el, this->env, attr, node); + break; + case ID_DER_ASN1_DN: + id_type = "distinguished-name"; + break; + case ID_KEY_ID: + id_type = "other"; + attr = axiom_attribute_create(this->env, "other-type-definition", + "36906:key-id", NULL); + axiom_element_add_attribute(el, this->env, attr, node); + break; + default: + id_type = "other"; + attr = axiom_attribute_create(this->env, "other-type-definition", + "36906:other", NULL); + axiom_element_add_attribute(el, this->env, attr, node); + } + attr = axiom_attribute_create(this->env, "type", id_type, NULL); + axiom_element_add_attribute(el, this->env, attr, node); + + return node; +} + +/** + * Create an ip-address + */ +static axiom_node_t* create_ip_address(private_tnc_ifmap_soap_t *this, + host_t *host) +{ + axiom_element_t *el; + axiom_node_t *node; + axiom_attribute_t *attr; + char buf[BUF_LEN]; + + el = axiom_element_create(this->env, NULL, "ip-address", NULL, &node); + + if (host->get_family(host) == AF_INET6) + { + chunk_t address; + int len, written, i; + char *pos; + bool first = TRUE; + + /* output IPv6 address in canonical IF-MAP 2.0 format */ + address = host->get_address(host); + pos = buf; + len = sizeof(buf); + + for (i = 0; i < address.len; i = i + 2) + { + written = snprintf(pos, len, "%s%x", first ? "" : ":", + 256*address.ptr[i] + address.ptr[i+1]); + if (written < 0 || written > len) + { + break; + } + pos += written; + len -= written; + first = FALSE; + } + } + else + { + snprintf(buf, BUF_LEN, "%H", host); + } + attr = axiom_attribute_create(this->env, "value", buf, NULL); + axiom_element_add_attribute(el, this->env, attr, node); + + attr = axiom_attribute_create(this->env, "type", + host->get_family(host) == AF_INET ? "IPv4" : "IPv6", NULL); + axiom_element_add_attribute(el, this->env, attr, node); + + return node; +} + +/** + * Create a device + */ +static axiom_node_t* create_device(private_tnc_ifmap_soap_t *this) +{ + axiom_element_t *el; + axiom_node_t *node, *node2, *node3; + axiom_text_t *text; + + el = axiom_element_create(this->env, NULL, "device", NULL, &node); + el = axiom_element_create(this->env, NULL, "name", NULL, &node2); + axiom_node_add_child(node, this->env, node2); + text = axiom_text_create(this->env, node2, this->device_name, &node3); + + return node; +} + +/** + * Create metadata + */ +static axiom_node_t* create_metadata(private_tnc_ifmap_soap_t *this, + char *metadata) +{ + axiom_element_t *el; + axiom_node_t *node, *node2; + axiom_attribute_t *attr; + axiom_namespace_t *ns_meta; + + el = axiom_element_create(this->env, NULL, "metadata", NULL, &node); + ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta"); + + el = axiom_element_create(this->env, NULL, metadata, ns_meta, &node2); + axiom_node_add_child(node, this->env, node2); + attr = axiom_attribute_create(this->env, "ifmap-cardinality", "singleValue", + NULL); + axiom_element_add_attribute(el, this->env, attr, node2); + + return node; +} + +/** + * Create capability metadata + */ +static axiom_node_t* create_capability(private_tnc_ifmap_soap_t *this, + identification_t *name) +{ + axiom_element_t *el; + axiom_node_t *node, *node2, *node3; + axiom_namespace_t *ns_meta; + axiom_attribute_t *attr; + axiom_text_t *text; + char buf[BUF_LEN]; + + ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta"); + el = axiom_element_create(this->env, NULL, "capability", ns_meta, &node); + attr = axiom_attribute_create(this->env, "ifmap-cardinality", "multiValue", + NULL); + axiom_element_add_attribute(el, this->env, attr, node); + + el = axiom_element_create(this->env, NULL, "name", NULL, &node2); + axiom_node_add_child(node, this->env, node2); + snprintf(buf, BUF_LEN, "%Y", name); + text = axiom_text_create(this->env, node2, buf, &node3); + + el = axiom_element_create(this->env, NULL, "administrative-domain", NULL, &node2); + axiom_node_add_child(node, this->env, node2); + text = axiom_text_create(this->env, node2, "strongswan", &node3); + + return node; +} + +/** + * Create enforcement-report metadata + */ +static axiom_node_t* create_enforcement_report(private_tnc_ifmap_soap_t *this, + char *action, char *reason) +{ + axiom_element_t *el; + axiom_node_t *node, *node2, *node3, *node4; + axiom_namespace_t *ns_meta; + axiom_attribute_t *attr; + axiom_text_t *text; + + el = axiom_element_create(this->env, NULL, "metadata", NULL, &node); + + ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta"); + el = axiom_element_create(this->env, NULL, "enforcement-report", ns_meta, + &node2); + attr = axiom_attribute_create(this->env, "ifmap-cardinality", + "multiValue", NULL); + axiom_element_add_attribute(el, this->env, attr, node2); + axiom_node_add_child(node, this->env, node2); + + el = axiom_element_create(this->env, NULL, "enforcement-action", NULL, + &node3); + axiom_node_add_child(node2, this->env, node3); + text = axiom_text_create(this->env, node3, action, &node4); + + el = axiom_element_create(this->env, NULL, "enforcement-reason", NULL, + &node3); + axiom_node_add_child(node2, this->env, node3); + text = axiom_text_create(this->env, node3, reason, &node4); + + return node; +} + +/** + * Create delete filter + */ +static axiom_node_t* create_delete_filter(private_tnc_ifmap_soap_t *this, + char *metadata) +{ + axiom_element_t *el; + axiom_node_t *node; + axiom_attribute_t *attr; + char buf[BUF_LEN]; + + el = axiom_element_create(this->env, NULL, "delete", NULL, &node); + + snprintf(buf, BUF_LEN, "meta:%s[@ifmap-publisher-id='%s']", + metadata, this->ifmap_publisher_id); + attr = axiom_attribute_create(this->env, "filter", buf, NULL); + axiom_element_add_attribute(el, this->env, attr, node); + + return node; +} + +/** + * Create a publish request + */ +static axiom_node_t* create_publish_request(private_tnc_ifmap_soap_t *this) +{ + axiom_element_t *el; + axiom_node_t *request; + axiom_namespace_t *ns, *ns_meta; + axiom_attribute_t *attr; + + ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap"); + el = axiom_element_create(this->env, NULL, "publish", ns, &request); + ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta"); + axiom_element_declare_namespace(el, this->env, request, ns_meta); + attr = axiom_attribute_create(this->env, "session-id", this->session_id, + NULL); + axiom_element_add_attribute(el, this->env, attr, request); + + return request; +} + +METHOD(tnc_ifmap_soap_t, publish_ike_sa, bool, + private_tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, bool up) +{ + axiom_node_t *request, *node, *node2; + axiom_element_t *el; + + enumerator_t *e1, *e2; + auth_rule_t type; + identification_t *id, *eap_id, *group; + host_t *host; + auth_cfg_t *auth; + u_int32_t ike_sa_id; + bool is_user = FALSE, first = TRUE; + + /* extract relevant data from IKE_SA*/ + ike_sa_id = ike_sa->get_unique_id(ike_sa); + id = ike_sa->get_other_id(ike_sa); + eap_id = ike_sa->get_other_eap_id(ike_sa); + host = ike_sa->get_other_host(ike_sa); + + /* in the presence of an EAP Identity, treat it as a username */ + if (!id->equals(id, eap_id)) + { + is_user = TRUE; + id = eap_id; + } + + /* build publish request */ + request = create_publish_request(this); + + /* delete any existing enforcement reports */ + if (up) + { + node = create_delete_filter(this, "enforcement-report"); + axiom_node_add_child(request, this->env, node); + axiom_node_add_child(node, this->env, + create_ip_address(this, host)); + axiom_node_add_child(node, this->env, + create_device(this)); + } + + /** + * update or delete authenticated-as metadata + */ + if (up) + { + el = axiom_element_create(this->env, NULL, "update", NULL, &node); + } + else + { + node = create_delete_filter(this, "authenticated-as"); + } + axiom_node_add_child(request, this->env, node); + + /* add access-request, identity and [if up] metadata */ + axiom_node_add_child(node, this->env, + create_access_request(this, ike_sa_id)); + axiom_node_add_child(node, this->env, + create_identity(this, id, is_user)); + if (up) + { + axiom_node_add_child(node, this->env, + create_metadata(this, "authenticated-as")); + } + + /** + * update or delete access-request-ip metadata + */ + if (up) + { + el = axiom_element_create(this->env, NULL, "update", NULL, &node); + } + else + { + node = create_delete_filter(this, "access-request-ip"); + } + axiom_node_add_child(request, this->env, node); + + /* add access-request, ip-address and [if up] metadata */ + axiom_node_add_child(node, this->env, + create_access_request(this, ike_sa_id)); + axiom_node_add_child(node, this->env, + create_ip_address(this, host)); + if (up) + { + axiom_node_add_child(node, this->env, + create_metadata(this, "access-request-ip")); + } + + /** + * update or delete authenticated-by metadata + */ + if (up) + { + el = axiom_element_create(this->env, NULL, "update", NULL, &node); + } + else + { + node = create_delete_filter(this, "authenticated-by"); + } + axiom_node_add_child(request, this->env, node); + + /* add access-request, device and [if up] metadata */ + axiom_node_add_child(node, this->env, + create_access_request(this, ike_sa_id)); + axiom_node_add_child(node, this->env, + create_device(this)); + if (up) + { + axiom_node_add_child(node, this->env, + create_metadata(this, "authenticated-by")); + } + + /** + * update or delete capability metadata + */ + e1 = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE); + while (e1->enumerate(e1, &auth)) + { + e2 = auth->create_enumerator(auth); + while (e2->enumerate(e2, &type, &group)) + { + /* look for group memberships */ + if (type == AUTH_RULE_GROUP) + { + if (first) + { + first = FALSE; + + if (up) + { + el = axiom_element_create(this->env, NULL, "update", + NULL, &node); + } + else + { + node = create_delete_filter(this, "capability"); + } + axiom_node_add_child(request, this->env, node); + + /* add access-request */ + axiom_node_add_child(node, this->env, + create_access_request(this, ike_sa_id)); + if (!up) + { + break; + } + el = axiom_element_create(this->env, NULL, "metadata", NULL, + &node2); + axiom_node_add_child(node, this->env, node2); + } + axiom_node_add_child(node2, this->env, + create_capability(this, group)); + } + if (!first && !up) + { + break; + } + } + e2->destroy(e2); + } + e1->destroy(e1); + + /* send publish request and receive publishReceived */ + return send_receive(this, "publish", request, "publishReceived", NULL); +} + +METHOD(tnc_ifmap_soap_t, publish_device_ip, bool, + private_tnc_ifmap_soap_t *this, host_t *host) +{ + axiom_node_t *request, *node; + axiom_element_t *el; + + /* build publish update request */ + request = create_publish_request(this); + el = axiom_element_create(this->env, NULL, "update", NULL, &node); + axiom_node_add_child(request, this->env, node); + + /* add device, ip-address and metadata */ + axiom_node_add_child(node, this->env, + create_device(this)); + axiom_node_add_child(node, this->env, + create_ip_address(this, host)); + axiom_node_add_child(node, this->env, + create_metadata(this, "device-ip")); + + /* send publish request and receive publishReceived */ + return send_receive(this, "publish", request, "publishReceived", NULL); +} + +METHOD(tnc_ifmap_soap_t, publish_enforcement_report, bool, + private_tnc_ifmap_soap_t *this, host_t *host, char *action, char *reason) +{ + axiom_node_t *request, *node; + axiom_element_t *el; + + /* build publish update request */ + request = create_publish_request(this); + el = axiom_element_create(this->env, NULL, "update", NULL, &node); + axiom_node_add_child(request, this->env, node); + + /* add ip-address and metadata */ + axiom_node_add_child(node, this->env, + create_ip_address(this, host)); + axiom_node_add_child(node, this->env, + create_device(this)); + axiom_node_add_child(node, this->env, + create_enforcement_report(this, action, reason)); + + /* send publish request and receive publishReceived */ + return send_receive(this, "publish", request, "publishReceived", NULL); +} + +METHOD(tnc_ifmap_soap_t, endSession, bool, + private_tnc_ifmap_soap_t *this) +{ + axiom_node_t *request; + axiom_element_t *el; + axiom_namespace_t *ns; + axiom_attribute_t *attr; + + /* build endSession request */ + ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap"); + el = axiom_element_create(this->env, NULL, "endSession", ns, &request); + attr = axiom_attribute_create(this->env, "session-id", this->session_id, NULL); + axiom_element_add_attribute(el, this->env, attr, request); + + /* send endSession request and receive end SessionResult */ + return send_receive(this, "endSession", request, "endSessionResult", NULL); +} + +METHOD(tnc_ifmap_soap_t, destroy, void, + private_tnc_ifmap_soap_t *this) +{ + if (this->session_id) + { + endSession(this); + free(this->session_id); + free(this->ifmap_publisher_id); + free(this->device_name); + } + if (this->svc_client) + { + axis2_svc_client_free(this->svc_client, this->env); + } + if (this->env) + { + axutil_env_free(this->env); + } + free(this); +} + +static bool axis2c_init(private_tnc_ifmap_soap_t *this) +{ + axis2_char_t *server, *server_cert, *key_file, *client_home; + axis2_char_t *ssl_passphrase, *username, *password; + axis2_endpoint_ref_t* endpoint_ref = NULL; + axis2_options_t *options = NULL; + axis2_transport_in_desc_t *transport_in; + axis2_transport_out_desc_t *transport_out; + axis2_transport_sender_t *transport_sender; + axutil_property_t* property; + + /* Getting configuration parameters from strongswan.conf */ + client_home = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-ifmap.client_home", + AXIS2_GETENV("AXIS2C_HOME")); + server = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-ifmap.server", IFMAP_SERVER); + server_cert = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-ifmap.server_cert", NULL); + key_file = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-ifmap.key_file", NULL); + ssl_passphrase = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-ifmap.ssl_passphrase", NULL); + username = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-ifmap.username", NULL); + password = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-ifmap.password", NULL); + + if (!server_cert) + { + DBG1(DBG_TNC, "MAP server certificate not defined"); + return FALSE; + } + + if (!key_file && (!username || !password)) + { + DBG1(DBG_TNC, "MAP client keyfile or %s%s%s not defined", + (!username) ? "username" : "", + (!username && ! password) ? " and " : "", + (!password) ? "password" : ""); + return FALSE; + } + + /* Create Axis2/C environment and options */ + this->env = axutil_env_create_all(IFMAP_LOGFILE, AXIS2_LOG_LEVEL_TRACE); + options = axis2_options_create(this->env); + + /* Set path to the MAP server certificate */ + property =axutil_property_create_with_args(this->env, 0, 0, 0, + server_cert); + axis2_options_set_property(options, this->env, + AXIS2_SSL_SERVER_CERT, property); + + if (key_file) + { + /* Set path to the MAP client certificate */ + property =axutil_property_create_with_args(this->env, 0, 0, 0, + key_file); + axis2_options_set_property(options, this->env, + AXIS2_SSL_KEY_FILE, property); + if (ssl_passphrase) + { + /* Provide SSL passphrase */ + property =axutil_property_create_with_args(this->env, 0, 0, 0, + ssl_passphrase); + axis2_options_set_property(options, this->env, + AXIS2_SSL_PASSPHRASE, property); + } + } + else + { + /* Set up HTTP Basic MAP client authentication */ + axis2_options_set_http_auth_info(options, this->env, + username, password, "Basic"); + } + + /* Define the MAP server as the to endpoint reference */ + endpoint_ref = axis2_endpoint_ref_create(this->env, server); + axis2_options_set_to(options, this->env, endpoint_ref); + + /* Set up https transport */ + transport_in = axis2_transport_in_desc_create(this->env, + AXIS2_TRANSPORT_ENUM_HTTPS); + transport_out = axis2_transport_out_desc_create(this->env, + AXIS2_TRANSPORT_ENUM_HTTPS); + transport_sender = axis2_http_transport_sender_create(this->env); + axis2_transport_out_desc_set_sender(transport_out, this->env, + transport_sender); + axis2_options_set_transport_in(options, this->env, transport_in); + axis2_options_set_transport_out(options, this->env, transport_out); + + /* Create the axis2 service client */ + this->svc_client = axis2_svc_client_create(this->env, client_home); + if (!this->svc_client) + { + DBG1(DBG_TNC, "could not create axis2 service client"); + AXIS2_LOG_ERROR(this->env->log, AXIS2_LOG_SI, + "Stub invoke FAILED: Error code: %d :: %s", + this->env->error->error_number, + AXIS2_ERROR_GET_MESSAGE(this->env->error)); + destroy(this); + return FALSE; + } + + axis2_svc_client_set_options(this->svc_client, this->env, options); + DBG1(DBG_TNC, "connecting as MAP client '%s' to MAP server at '%s'", + username, server); + + return TRUE; +} + +/** + * See header + */ +tnc_ifmap_soap_t *tnc_ifmap_soap_create() +{ + private_tnc_ifmap_soap_t *this; + + INIT(this, + .public = { + .newSession = _newSession, + .purgePublisher = _purgePublisher, + .publish_ike_sa = _publish_ike_sa, + .publish_device_ip = _publish_device_ip, + .publish_enforcement_report = _publish_enforcement_report, + .endSession = _endSession, + .destroy = _destroy, + }, + ); + + if (!axis2c_init(this)) + { + destroy(this); + return NULL; + } + + return &this->public; +} + diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h new file mode 100644 index 000000000..4bf421e33 --- /dev/null +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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 tnc_ifmap_soap tnc_ifmap_soap + * @{ @ingroup tnc_ifmap + */ + +#ifndef TNC_IFMAP_SOAP_H_ +#define TNC_IFMAP_SOAP_H_ + +#include <library.h> +#include <utils/host.h> +#include <sa/ike_sa.h> + +typedef struct tnc_ifmap_soap_t tnc_ifmap_soap_t; + +/** + * Implements the TNC IF-MAP 2.0 SOAP Binding + */ +struct tnc_ifmap_soap_t { + + /** + * Creates a new IF-MAP session + * + * @return TRUE if command was successful + */ + bool (*newSession)(tnc_ifmap_soap_t *this); + + /** + * Purges all metadata published by this publisher + * + * @return TRUE if command was successful + */ + bool (*purgePublisher)(tnc_ifmap_soap_t *this); + + /** + * Publish metadata about established/deleted IKE_SAs + * + * @param ike_sa IKE_SA for which metadate is published + * @param up TRUE if IKE_SEA is up, FALSE if down + * @return TRUE if command was successful + */ + bool (*publish_ike_sa)(tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, bool up); + + /** + * Publish PEP device-ip metadata + * + * @param host IP address of local endpoint + * @return TRUE if command was successful + */ + bool (*publish_device_ip)(tnc_ifmap_soap_t *this, host_t *host); + + /** + * Publish enforcement-report metadata + * + * @param host Host to be enforced + * @param action Enforcement action ("block" or "quarantine") + * @param reason Enforcement reason + * @return TRUE if command was successful + */ + bool (*publish_enforcement_report)(tnc_ifmap_soap_t *this, host_t *host, + char *action, char *reason); + + /** + * Ends an IF-MAP session + * + * @return TRUE if command was successful + */ + bool (*endSession)(tnc_ifmap_soap_t *this); + + /** + * Destroy a tnc_ifmap_soap_t. + */ + void (*destroy)(tnc_ifmap_soap_t *this); +}; + +/** + * Create a tnc_ifmap_soap instance. + */ +tnc_ifmap_soap_t *tnc_ifmap_soap_create(); + +#endif /** TNC_IFMAP_SOAP_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_imc/Makefile.am b/src/libcharon/plugins/tnc_imc/Makefile.am index 2c551813e..fc1979525 100644 --- a/src/libcharon/plugins/tnc_imc/Makefile.am +++ b/src/libcharon/plugins/tnc_imc/Makefile.am @@ -1,6 +1,8 @@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @@ -8,6 +10,9 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-tnc-imc.la else plugin_LTLIBRARIES = libstrongswan-tnc-imc.la +libstrongswan_tnc_imc_la_LIBADD = \ + $(top_builddir)/src/libtncif/libtncif.la \ + $(top_builddir)/src/libtnccs/libtnccs.la endif libstrongswan_tnc_imc_la_SOURCES = \ diff --git a/src/libcharon/plugins/tnc_imc/Makefile.in b/src/libcharon/plugins/tnc_imc/Makefile.in index c2bc35dc5..550c0516c 100644 --- a/src/libcharon/plugins/tnc_imc/Makefile.in +++ b/src/libcharon/plugins/tnc_imc/Makefile.in @@ -74,7 +74,9 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_tnc_imc_la_LIBADD = +@MONOLITHIC_FALSE@libstrongswan_tnc_imc_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la am_libstrongswan_tnc_imc_la_OBJECTS = tnc_imc_plugin.lo tnc_imc.lo \ tnc_imc_manager.lo tnc_imc_bind_function.lo libstrongswan_tnc_imc_la_OBJECTS = \ @@ -194,6 +196,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +207,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +224,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +274,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -276,12 +285,18 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imc.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imc.la +@MONOLITHIC_FALSE@libstrongswan_tnc_imc_la_LIBADD = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la + libstrongswan_tnc_imc_la_SOURCES = \ tnc_imc_plugin.h tnc_imc_plugin.c tnc_imc.h tnc_imc.c \ tnc_imc_manager.h tnc_imc_manager.c tnc_imc_bind_function.c diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc.c b/src/libcharon/plugins/tnc_imc/tnc_imc.c index d7fc2c65d..a1f2d770f 100644 --- a/src/libcharon/plugins/tnc_imc/tnc_imc.c +++ b/src/libcharon/plugins/tnc_imc/tnc_imc.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Mike McCauley - * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2010-2011 Andreas Steffen, + * HSR 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 @@ -17,8 +18,11 @@ #include <dlfcn.h> +#include <tncif_pa_subtypes.h> + #include <debug.h> #include <library.h> +#include <utils/linked_list.h> #include <threading/mutex.h> typedef struct private_tnc_imc_t private_tnc_imc_t; @@ -54,9 +58,19 @@ struct private_tnc_imc_t { TNC_IMCID id; /** - * List of message types supported by IMC + * list of additional IMC IDs */ - TNC_MessageTypeList supported_types; + linked_list_t *additional_ids; + + /** + * List of message types supported by IMC - Vendor ID part + */ + TNC_VendorIDList supported_vids; + + /** + * List of message types supported by IMC - Subtype part + */ + TNC_MessageSubtypeList supported_subtypes; /** * Number of supported message types @@ -81,6 +95,54 @@ METHOD(imc_t, get_id, TNC_IMCID, return this->id; } +METHOD(imc_t, add_id, void, + private_tnc_imc_t *this, TNC_IMCID id) +{ + void *pointer; + + /* store the scalar value in the pointer */ + pointer = (void*)id; + this->additional_ids->insert_last(this->additional_ids, pointer); +} + +METHOD(imc_t, has_id, bool, + private_tnc_imc_t *this, TNC_IMCID id) +{ + enumerator_t *enumerator; + TNC_IMCID additional_id; + void *pointer; + bool found = FALSE; + + /* check primary IMC ID */ + if (id == this->id) + { + return TRUE; + } + + /* return if there are no additional IMC IDs */ + if (this->additional_ids->get_count(this->additional_ids) == 0) + { + return FALSE; + } + + /* check additional IMC IDs */ + enumerator = this->additional_ids->create_enumerator(this->additional_ids); + while (enumerator->enumerate(enumerator, &pointer)) + { + /* interpret pointer as scalar value */ + additional_id = (TNC_UInt32)pointer; + + if (id == additional_id) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + return found; +} + METHOD(imc_t, get_name, char*, private_tnc_imc_t *this) { @@ -91,66 +153,150 @@ METHOD(imc_t, set_message_types, void, private_tnc_imc_t *this, TNC_MessageTypeList supported_types, TNC_UInt32 type_count) { - char buf[512]; + char buf[BUF_LEN]; char *pos = buf; int len = sizeof(buf); - int written; + int i, written; + size_t size; + TNC_VendorID vid; + TNC_MessageSubtype subtype; + enum_name_t *pa_subtype_names; /* lock the imc_t instance */ this->mutex->lock(this->mutex); - /* Free an existing MessageType list */ - free(this->supported_types); - this->supported_types = NULL; + /* Free existing VendorID and MessageSubtype lists */ + free(this->supported_vids); + this->supported_vids = NULL; + free(this->supported_subtypes); + this->supported_subtypes = NULL; /* Store the new MessageType list */ this->type_count = type_count; if (type_count && supported_types) { - size_t size = type_count * sizeof(TNC_MessageType); - int i; + size = type_count * sizeof(TNC_VendorID); + this->supported_vids = malloc(size); + size = type_count * sizeof(TNC_MessageSubtype); + this->supported_subtypes = malloc(size); for (i = 0; i < type_count; i++) { - written = snprintf(pos, len, " 0x%08x", supported_types[i]); + vid = (supported_types[i] >> 8) & TNC_VENDORID_ANY; + subtype = supported_types[i] & TNC_SUBTYPE_ANY; + + pa_subtype_names = get_pa_subtype_names(vid); + if (pa_subtype_names) + { + written = snprintf(pos, len," '%N/%N' 0x%06x/0x%02x", + pen_names, vid, pa_subtype_names, subtype, + vid, subtype); + } + else + { + written = snprintf(pos, len," '%N' 0x%06x/0x%02x", + pen_names, vid, vid, subtype); + } if (written >= len) { break; } pos += written; len -= written; + + this->supported_vids[i] = vid; + this->supported_subtypes[i] = subtype; } - this->supported_types = malloc(size); - memcpy(this->supported_types, supported_types, size); } *pos = '\0'; - DBG2(DBG_TNC, "IMC %u supports %u message types:%s", - this->id, type_count, buf); + DBG2(DBG_TNC, "IMC %u supports %u message type%s:%s", + this->id, type_count, (type_count == 1) ? "":"s", buf); + + /* unlock the imc_t instance */ + this->mutex->unlock(this->mutex); +} + +METHOD(imc_t, set_message_types_long, void, + private_tnc_imc_t *this, TNC_VendorIDList supported_vids, + TNC_MessageSubtypeList supported_subtypes, TNC_UInt32 type_count) +{ + char buf[BUF_LEN]; + char *pos = buf; + int len = sizeof(buf); + int i, written; + size_t size; + TNC_VendorID vid; + TNC_MessageSubtype subtype; + enum_name_t *pa_subtype_names; /* lock the imc_t instance */ + this->mutex->lock(this->mutex); + + /* Free existing VendorID and MessageSubtype lists */ + free(this->supported_vids); + this->supported_vids = NULL; + free(this->supported_subtypes); + this->supported_subtypes = NULL; + + /* Store the new MessageType list */ + this->type_count = type_count; + if (type_count && supported_vids && supported_subtypes) + { + size = type_count * sizeof(TNC_VendorID); + this->supported_vids = malloc(size); + memcpy(this->supported_vids, supported_vids, size); + size = type_count * sizeof(TNC_MessageSubtype); + this->supported_subtypes = malloc(size); + memcpy(this->supported_subtypes, supported_subtypes, size); + + for (i = 0; i < type_count; i++) + { + vid = supported_vids[i]; + subtype = supported_subtypes[i]; + + pa_subtype_names = get_pa_subtype_names(vid); + if (pa_subtype_names) + { + written = snprintf(pos, len," '%N/%N' 0x%06x/0x%08x", + pen_names, vid, pa_subtype_names, subtype, + vid, subtype); + } + else + { + written = snprintf(pos, len," '%N' 0x%06x/0x%08x", + pen_names, vid, vid, subtype); + } + if (written >= len) + { + break; + } + pos += written; + len -= written; + } + } + *pos = '\0'; + DBG2(DBG_TNC, "IMC %u supports %u message type%s:%s", + this->id, type_count, (type_count == 1) ? "":"s", buf); + + /* unlock the imc_t instance */ this->mutex->unlock(this->mutex); } METHOD(imc_t, type_supported, bool, - private_tnc_imc_t *this, TNC_MessageType message_type) + private_tnc_imc_t *this, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype) { - TNC_VendorID msg_vid, vid; - TNC_MessageSubtype msg_subtype, subtype; + TNC_VendorID vid; + TNC_MessageSubtype subtype; int i; - msg_vid = (message_type >> 8) & TNC_VENDORID_ANY; - msg_subtype = message_type & TNC_SUBTYPE_ANY; - for (i = 0; i < this->type_count; i++) { - vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY; - subtype = this->supported_types[i] & TNC_SUBTYPE_ANY; - - if (this->supported_types[i] == message_type - || (subtype == TNC_SUBTYPE_ANY - && (msg_vid == vid || vid == TNC_VENDORID_ANY)) - || (vid == TNC_VENDORID_ANY - && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY))) + vid = this->supported_vids[i]; + subtype = this->supported_subtypes[i]; + + if ((vid == TNC_VENDORID_ANY && subtype == TNC_SUBTYPE_ANY) || + (vid == msg_vid && (subtype == TNC_SUBTYPE_ANY || + subtype == msg_subtype))) { return TRUE; } @@ -163,7 +309,9 @@ METHOD(imc_t, destroy, void, { dlclose(this->handle); this->mutex->destroy(this->mutex); - free(this->supported_types); + this->additional_ids->destroy(this->additional_ids); + free(this->supported_vids); + free(this->supported_subtypes); free(this->name); free(this->path); free(this); @@ -180,13 +328,17 @@ imc_t* tnc_imc_create(char *name, char *path) .public = { .set_id = _set_id, .get_id = _get_id, + .add_id = _add_id, + .has_id = _has_id, .get_name = _get_name, .set_message_types = _set_message_types, + .set_message_types_long = _set_message_types_long, .type_supported = _type_supported, .destroy = _destroy, }, .name = name, .path = path, + .additional_ids = linked_list_create(), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), ); @@ -220,6 +372,8 @@ imc_t* tnc_imc_create(char *name, char *path) } this->public.receive_message = dlsym(this->handle, "TNC_IMC_ReceiveMessage"); + this->public.receive_message_long = + dlsym(this->handle, "TNC_IMC_ReceiveMessageLong"); this->public.batch_ending = dlsym(this->handle, "TNC_IMC_BatchEnding"); this->public.terminate = diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c index 25a6a1cc4..90a607ccc 100644 --- a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c +++ b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c @@ -13,12 +13,11 @@ * for more details. */ -#include "tnc_imc.h" +#include <tnc/tnc.h> +#include <tnc/imc/imc_manager.h> +#include <tnc/tnccs/tnccs_manager.h> #include <debug.h> -#include <daemon.h> - -#define TNC_IMVID_ANY 0xffff /** * Called by the IMC to inform a TNCC about the set of message types the IMC @@ -28,14 +27,33 @@ TNC_Result TNC_TNCC_ReportMessageTypes(TNC_IMCID imc_id, TNC_MessageTypeList supported_types, TNC_UInt32 type_count) { - if (!charon->imcs->is_registered(charon->imcs, imc_id)) + if (!tnc->imcs->is_registered(tnc->imcs, imc_id)) { DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMC %u", imc_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->imcs->set_message_types(charon->imcs, imc_id, - supported_types, type_count); + return tnc->imcs->set_message_types(tnc->imcs, imc_id, supported_types, + type_count); +} + +/** + * Called by the IMC to inform a TNCC about the set of message types the IMC + * is able to receive. This function supports long message types. + */ +TNC_Result TNC_TNCC_ReportMessageTypesLong(TNC_IMCID imc_id, + TNC_VendorIDList supported_vids, + TNC_MessageSubtypeList supported_subtypes, + TNC_UInt32 type_count) +{ + if (!tnc->imcs->is_registered(tnc->imcs, imc_id)) + { + DBG1(DBG_TNC, "ignoring ReportMessageTypesLong() from unregistered IMC %u", + imc_id); + return TNC_RESULT_INVALID_PARAMETER; + } + return tnc->imcs->set_message_types_long(tnc->imcs, imc_id, supported_vids, + supported_subtypes, type_count); } /** @@ -45,14 +63,14 @@ TNC_Result TNC_TNCC_RequestHandshakeRetry(TNC_IMCID imc_id, TNC_ConnectionID connection_id, TNC_RetryReason reason) { - if (!charon->imcs->is_registered(charon->imcs, imc_id)) + if (!tnc->imcs->is_registered(tnc->imcs, imc_id)) { DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMC %u", imc_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->tnccs->request_handshake_retry(charon->tnccs, TRUE, imc_id, - connection_id, reason); + return tnc->tnccs->request_handshake_retry(tnc->tnccs, TRUE, imc_id, + connection_id, reason); } /** @@ -64,14 +82,97 @@ TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id, TNC_UInt32 msg_len, TNC_MessageType msg_type) { - if (!charon->imcs->is_registered(charon->imcs, imc_id)) + TNC_VendorID msg_vid; + TNC_MessageSubtype msg_subtype; + + if (!tnc->imcs->is_registered(tnc->imcs, imc_id)) + { + DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u", + imc_id); + return TNC_RESULT_INVALID_PARAMETER; + } + msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY; + msg_subtype = msg_type & TNC_SUBTYPE_ANY; + + return tnc->tnccs->send_message(tnc->tnccs, imc_id, TNC_IMVID_ANY, + connection_id, 0, msg, msg_len, msg_vid, msg_subtype); +} + +/** + * Called by the IMC when an IMC-IMV message is to be sent over IF-TNCCS 2.0 + */ +TNC_Result TNC_TNCC_SendMessageLong(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_UInt32 msg_flags, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype, + TNC_UInt32 imv_id) +{ + if (!tnc->imcs->is_registered(tnc->imcs, imc_id)) { DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u", imc_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->tnccs->send_message(charon->tnccs, imc_id, TNC_IMVID_ANY, - connection_id, msg, msg_len, msg_type); + return tnc->tnccs->send_message(tnc->tnccs, imc_id, imv_id, connection_id, + msg_flags, msg, msg_len, msg_vid, msg_subtype); +} + +/** + * Called by the IMC to get the value of an attribute associated with a + * connection or with the TNCC as a whole. + */ +TNC_Result TNC_TNCC_GetAttribute(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_AttributeID attribute_id, + TNC_UInt32 buffer_len, + TNC_BufferReference buffer, + TNC_UInt32 *out_value_len) +{ + if (!tnc->imcs->is_registered(tnc->imcs, imc_id)) + { + DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMC %u", + imc_id); + return TNC_RESULT_INVALID_PARAMETER; + } + return tnc->tnccs->get_attribute(tnc->tnccs, TRUE, imc_id, connection_id, + attribute_id, buffer_len, buffer, out_value_len); +} + +/** + * Called by the IMC to set the value of an attribute associated with a + * connection or with the TNCC as a whole. + */ +TNC_Result TNC_TNCC_SetAttribute(TNC_IMCID imc_id, + TNC_ConnectionID connection_id, + TNC_AttributeID attribute_id, + TNC_UInt32 buffer_len, + TNC_BufferReference buffer) +{ + if (!tnc->imcs->is_registered(tnc->imcs, imc_id)) + { + DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMC %u", + imc_id); + return TNC_RESULT_INVALID_PARAMETER; + } + return tnc->tnccs->set_attribute(tnc->tnccs, TRUE, imc_id, connection_id, + attribute_id, buffer_len, buffer); +} + +/** + * Called by the IMC when it wants to reserve an additional IMC ID for itself + */ +TNC_Result TNC_TNCC_ReserveAdditionalIMCID(TNC_IMCID imc_id, TNC_UInt32 *new_id) +{ + if (tnc->imcs->reserve_id(tnc->imcs, imc_id, new_id)) + { + return TNC_RESULT_SUCCESS; + } + DBG1(DBG_TNC, "ignoring ReserveAdditionalIMCID() from unregistered IMC %u", + imc_id); + return TNC_RESULT_INVALID_PARAMETER; } /** @@ -85,6 +186,10 @@ TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id, { *function_pointer = (void*)TNC_TNCC_ReportMessageTypes; } + else if (streq(function_name, "TNC_TNCC_ReportMessageTypesLong")) + { + *function_pointer = (void*)TNC_TNCC_ReportMessageTypesLong; + } else if (streq(function_name, "TNC_TNCC_RequestHandshakeRetry")) { *function_pointer = (void*)TNC_TNCC_RequestHandshakeRetry; @@ -93,6 +198,22 @@ TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id, { *function_pointer = (void*)TNC_TNCC_SendMessage; } + else if (streq(function_name, "TNC_TNCC_SendMessageLong")) + { + *function_pointer = (void*)TNC_TNCC_SendMessageLong; + } + else if (streq(function_name, "TNC_TNCC_GetAttribute")) + { + *function_pointer = (void*)TNC_TNCC_GetAttribute; + } + else if (streq(function_name, "TNC_TNCC_SetAttribute")) + { + *function_pointer = (void*)TNC_TNCC_SetAttribute; + } + else if (streq(function_name, "TNC_TNCC_ReserveAdditionalIMCID")) + { + *function_pointer = (void*)TNC_TNCC_ReserveAdditionalIMCID; + } else { return TNC_RESULT_INVALID_PARAMETER; diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c index ccf6aea67..e101cf974 100644 --- a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c +++ b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Mike McCauley - * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2010-2011 Andreas Steffen + * HSR 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 @@ -14,13 +15,12 @@ */ #include "tnc_imc_manager.h" +#include "tnc_imc.h" -#include <tnc/imc/imc_manager.h> -#include <tnc/tncifimc.h> +#include <tncifimc.h> -#include <debug.h> -#include <library.h> #include <utils/linked_list.h> +#include <debug.h> typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t; @@ -94,6 +94,33 @@ METHOD(imc_manager_t, remove_, imc_t*, return removed_imc; } +METHOD(imc_manager_t, load, bool, + private_tnc_imc_manager_t *this, char *name, char *path) +{ + imc_t *imc; + + imc = tnc_imc_create(name, path); + if (!imc) + { + free(name); + free(path); + return FALSE; + } + if (!add(this, imc)) + { + if (imc->terminate && + imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS) + { + DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully", + imc->get_name(imc)); + } + imc->destroy(imc); + return FALSE; + } + DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc), name, path); + return TRUE; +} + METHOD(imc_manager_t, is_registered, bool, private_tnc_imc_manager_t *this, TNC_IMCID id) { @@ -104,9 +131,34 @@ METHOD(imc_manager_t, is_registered, bool, enumerator = this->imcs->create_enumerator(this->imcs); while (enumerator->enumerate(enumerator, &imc)) { - if (id == imc->get_id(imc)) + if (imc->has_id(imc, id)) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + return found; +} + +METHOD(imc_manager_t, reserve_id, bool, + private_tnc_imc_manager_t *this, TNC_IMCID id, TNC_UInt32 *new_id) +{ + enumerator_t *enumerator; + imc_t *imc; + bool found = FALSE; + + enumerator = this->imcs->create_enumerator(this->imcs); + while (enumerator->enumerate(enumerator, &imc)) + { + if (imc->get_id(imc)) { found = TRUE; + *new_id = this->next_imc_id++; + imc->add_id(imc, *new_id); + DBG2(DBG_TNC, "additional ID %u reserved for IMC with primary ID %u", + *new_id, id); break; } } @@ -177,30 +229,77 @@ METHOD(imc_manager_t, set_message_types, TNC_Result, return result; } +METHOD(imc_manager_t, set_message_types_long, TNC_Result, + private_tnc_imc_manager_t *this, TNC_IMCID id, + TNC_VendorIDList supported_vids, + TNC_MessageSubtypeList supported_subtypes, + TNC_UInt32 type_count) +{ + enumerator_t *enumerator; + imc_t *imc; + TNC_Result result = TNC_RESULT_FATAL; + + enumerator = this->imcs->create_enumerator(this->imcs); + while (enumerator->enumerate(enumerator, &imc)) + { + if (id == imc->get_id(imc)) + { + imc->set_message_types_long(imc, supported_vids, supported_subtypes, + type_count); + result = TNC_RESULT_SUCCESS; + break; + } + } + enumerator->destroy(enumerator); + return result; +} + METHOD(imc_manager_t, receive_message, void, private_tnc_imc_manager_t *this, TNC_ConnectionID connection_id, - TNC_BufferReference message, - TNC_UInt32 message_len, - TNC_MessageType message_type) + bool excl, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype, + TNC_UInt32 src_imv_id, + TNC_UInt32 dst_imc_id) { bool type_supported = FALSE; + TNC_MessageType msg_type; + TNC_UInt32 msg_flags; enumerator_t *enumerator; imc_t *imc; enumerator = this->imcs->create_enumerator(this->imcs); while (enumerator->enumerate(enumerator, &imc)) { - if (imc->receive_message && imc->type_supported(imc, message_type)) + if (imc->type_supported(imc, msg_vid, msg_subtype) && + (!excl || (excl && imc->has_id(imc, dst_imc_id)) )) { - type_supported = TRUE; - imc->receive_message(imc->get_id(imc), connection_id, - message, message_len, message_type); + if (imc->receive_message_long && src_imv_id) + { + type_supported = TRUE; + msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0; + imc->receive_message_long(imc->get_id(imc), connection_id, + msg_flags, msg, msg_len, msg_vid, msg_subtype, + src_imv_id, dst_imc_id); + + } + else if (imc->receive_message && msg_vid <= TNC_VENDORID_ANY && + msg_subtype <= TNC_SUBTYPE_ANY) + { + type_supported = TRUE; + msg_type = (msg_vid << 8) | msg_subtype; + imc->receive_message(imc->get_id(imc), connection_id, + msg, msg_len, msg_type); + } } } enumerator->destroy(enumerator); if (!type_supported) { - DBG2(DBG_TNC, "message type 0x%08x not supported by any IMC", message_type); + DBG2(DBG_TNC, "message type 0x%06x/0x%08x not supported by any IMC", + msg_vid, msg_subtype); } } @@ -251,11 +350,14 @@ imc_manager_t* tnc_imc_manager_create(void) .public = { .add = _add, .remove = _remove_, /* avoid name conflict with stdio.h */ + .load = _load, .is_registered = _is_registered, + .reserve_id = _reserve_id, .get_preferred_language = _get_preferred_language, .notify_connection_change = _notify_connection_change, .begin_handshake = _begin_handshake, .set_message_types = _set_message_types, + .set_message_types_long = _set_message_types_long, .receive_message = _receive_message, .batch_ending = _batch_ending, .destroy = _destroy, diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c index bc13b8735..a25b1843c 100644 --- a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c +++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010-2011 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,180 +15,63 @@ #include "tnc_imc_plugin.h" #include "tnc_imc_manager.h" -#include "tnc_imc.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> +#include <tnc/tnc.h> -#include <daemon.h> -#include <utils/lexparser.h> +typedef struct private_tnc_imc_plugin_t private_tnc_imc_plugin_t; /** - * load IMCs from a configuration file + * Private data of a tnc_imc_plugin_t object. */ -static bool load_imcs(char *filename) -{ - int fd, line_nr = 0; - chunk_t src, line; - struct stat sb; - void *addr; - - DBG1(DBG_TNC, "loading IMCs from '%s'", filename); - fd = open(filename, O_RDONLY); - if (fd == -1) - { - DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename, - strerror(errno)); - return FALSE; - } - if (fstat(fd, &sb) == -1) - { - DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename, - strerror(errno)); - close(fd); - return FALSE; - } - addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (addr == MAP_FAILED) - { - DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno)); - close(fd); - return FALSE; - } - src = chunk_create(addr, sb.st_size); - - while (fetchline(&src, &line)) - { - char *name, *path; - chunk_t token; - imc_t *imc; - - line_nr++; - - /* skip comments or empty lines */ - if (*line.ptr == '#' || !eat_whitespace(&line)) - { - continue; - } - - /* determine keyword */ - if (!extract_token(&token, ' ', &line)) - { - DBG1(DBG_TNC, "line %d: keyword must be followed by a space", - line_nr); - return FALSE; - } - - /* only interested in IMCs */ - if (!match("IMC", &token)) - { - continue; - } - - /* advance to the IMC name and extract it */ - if (!extract_token(&token, '"', &line) || - !extract_token(&token, '"', &line)) - { - DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes", - line_nr); - return FALSE; - } +struct private_tnc_imc_plugin_t { - /* copy the IMC name */ - name = malloc(token.len + 1); - memcpy(name, token.ptr, token.len); - name[token.len] = '\0'; - - /* advance to the IMC path and extract it */ - if (!eat_whitespace(&line)) - { - DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr); - free(name); - return FALSE; - } - if (!extract_token(&token, ' ', &line)) - { - token = line; - } - - /* copy the IMC path */ - path = malloc(token.len + 1); - memcpy(path, token.ptr, token.len); - path[token.len] = '\0'; - - /* load and register IMC instance */ - imc = tnc_imc_create(name, path); - if (!imc) - { - free(name); - free(path); - return FALSE; - } - if (!charon->imcs->add(charon->imcs, imc)) - { - if (imc->terminate && - imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS) - { - DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully", - imc->get_name(imc)); - } - imc->destroy(imc); - return FALSE; - } - DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc), - name, path); - } - munmap(addr, sb.st_size); - close(fd); - return TRUE; -} + /** + * Public interface. + */ + tnc_imc_plugin_t public; +}; METHOD(plugin_t, get_name, char*, - tnc_imc_plugin_t *this) + private_tnc_imc_plugin_t *this) { return "tnc-imc"; } +METHOD(plugin_t, get_features, int, + private_tnc_imc_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(tnc_manager_register, tnc_imc_manager_create), + PLUGIN_PROVIDE(CUSTOM, "imc-manager"), + PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, - tnc_imc_plugin_t *this) + private_tnc_imc_plugin_t *this) { - charon->imcs->destroy(charon->imcs); free(this); } /* * see header file */ -plugin_t *tnc_imc_plugin_create() +plugin_t *tnc_imc_plugin_create(void) { - char *tnc_config; - tnc_imc_plugin_t *this; + private_tnc_imc_plugin_t *this; INIT(this, - .plugin = { - .get_name = _get_name, - .reload = (void*)return_false, - .destroy = _destroy, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, }, ); - /* Create IMC manager */ - charon->imcs = tnc_imc_manager_create(); - - /* Load IMCs and abort if not all instances initalize successfully */ - tnc_config = lib->settings->get_str(lib->settings, - "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config"); - if (!load_imcs(tnc_config)) - { - charon->imcs->destroy(charon->imcs); - charon->imcs = NULL; - free(this); - return NULL; - } - return &this->plugin; + return &this->public.plugin; } diff --git a/src/libcharon/plugins/tnc_imv/Makefile.am b/src/libcharon/plugins/tnc_imv/Makefile.am index 3ba283bb7..eca3b377b 100644 --- a/src/libcharon/plugins/tnc_imv/Makefile.am +++ b/src/libcharon/plugins/tnc_imv/Makefile.am @@ -1,6 +1,10 @@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @@ -8,6 +12,9 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-tnc-imv.la else plugin_LTLIBRARIES = libstrongswan-tnc-imv.la +libstrongswan_tnc_imv_la_LIBADD = \ + $(top_builddir)/src/libtncif/libtncif.la \ + $(top_builddir)/src/libtnccs/libtnccs.la endif libstrongswan_tnc_imv_la_SOURCES = \ diff --git a/src/libcharon/plugins/tnc_imv/Makefile.in b/src/libcharon/plugins/tnc_imv/Makefile.in index fb96150f4..cf58f0dc3 100644 --- a/src/libcharon/plugins/tnc_imv/Makefile.in +++ b/src/libcharon/plugins/tnc_imv/Makefile.in @@ -74,7 +74,9 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_tnc_imv_la_LIBADD = +@MONOLITHIC_FALSE@libstrongswan_tnc_imv_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la am_libstrongswan_tnc_imv_la_OBJECTS = tnc_imv_plugin.lo tnc_imv.lo \ tnc_imv_manager.lo tnc_imv_bind_function.lo \ tnc_imv_recommendations.lo @@ -195,6 +197,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +208,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +225,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +275,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -277,12 +286,20 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imv.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imv.la +@MONOLITHIC_FALSE@libstrongswan_tnc_imv_la_LIBADD = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la + libstrongswan_tnc_imv_la_SOURCES = \ tnc_imv_plugin.h tnc_imv_plugin.c tnc_imv.h tnc_imv.c \ tnc_imv_manager.h tnc_imv_manager.c tnc_imv_bind_function.c \ diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv.c b/src/libcharon/plugins/tnc_imv/tnc_imv.c index fe628ee7e..f0b150743 100644 --- a/src/libcharon/plugins/tnc_imv/tnc_imv.c +++ b/src/libcharon/plugins/tnc_imv/tnc_imv.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Mike McCauley - * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2010-2011 Andreas Steffen, + * HSR 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 @@ -17,8 +18,11 @@ #include <dlfcn.h> +#include <tncif_pa_subtypes.h> + #include <debug.h> #include <library.h> +#include <utils/linked_list.h> #include <threading/mutex.h> typedef struct private_tnc_imv_t private_tnc_imv_t; @@ -54,9 +58,19 @@ struct private_tnc_imv_t { TNC_IMVID id; /** - * List of message types supported by IMC + * List of additional IMV IDs */ - TNC_MessageTypeList supported_types; + linked_list_t *additional_ids; + + /** + * List of message types supported by IMV - Vendor ID part + */ + TNC_VendorIDList supported_vids; + + /** + * List of message types supported by IMV - Subtype part + */ + TNC_MessageSubtypeList supported_subtypes; /** * Number of supported message types @@ -81,6 +95,50 @@ METHOD(imv_t, get_id, TNC_IMVID, return this->id; } +METHOD(imv_t, add_id, void, + private_tnc_imv_t *this, TNC_IMVID id) +{ + TNC_IMVID *new_id; + + new_id = malloc_thing(TNC_IMVID); + *new_id = id; + this->additional_ids->insert_last(this->additional_ids, new_id); +} + +METHOD(imv_t, has_id, bool, + private_tnc_imv_t *this, TNC_IMVID id) +{ + enumerator_t *enumerator; + TNC_IMVID *additional_id; + bool found = FALSE; + + /* check primary IMV ID */ + if (id == this->id) + { + return TRUE; + } + + /* return if there are no additional IMV IDs */ + if (this->additional_ids->get_count(this->additional_ids) == 0) + { + return FALSE; + } + + /* check additional IMV IDs */ + enumerator = this->additional_ids->create_enumerator(this->additional_ids); + while (enumerator->enumerate(enumerator, &additional_id)) + { + if (id == *additional_id) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + return found; +} + METHOD(imv_t, get_name, char*, private_tnc_imv_t *this) { @@ -91,67 +149,150 @@ METHOD(imv_t, set_message_types, void, private_tnc_imv_t *this, TNC_MessageTypeList supported_types, TNC_UInt32 type_count) { - char buf[512]; + char buf[BUF_LEN]; char *pos = buf; int len = sizeof(buf); - int written; + int i, written; + size_t size; + TNC_VendorID vid; + TNC_MessageSubtype subtype; + enum_name_t *pa_subtype_names; /* lock the imv_t instance */ this->mutex->lock(this->mutex); - /* Free an existing MessageType list */ - free(this->supported_types); - this->supported_types = NULL; + /* Free existing VendorID and MessageSubtype lists */ + free(this->supported_vids); + this->supported_vids = NULL; + free(this->supported_subtypes); + this->supported_subtypes = NULL; /* Store the new MessageType list */ this->type_count = type_count; if (type_count && supported_types) { - size_t size = type_count * sizeof(TNC_MessageType); - - int i; + size = type_count * sizeof(TNC_VendorID); + this->supported_vids = malloc(size); + size = type_count * sizeof(TNC_MessageSubtype); + this->supported_subtypes = malloc(size); for (i = 0; i < type_count; i++) { - written = snprintf(pos, len, " 0x%08x", supported_types[i]); + vid = (supported_types[i] >> 8) & TNC_VENDORID_ANY; + subtype = supported_types[i] & TNC_SUBTYPE_ANY; + + pa_subtype_names = get_pa_subtype_names(vid); + if (pa_subtype_names) + { + written = snprintf(pos, len," '%N/%N' 0x%06x/0x%02x", + pen_names, vid, pa_subtype_names, subtype, + vid, subtype); + } + else + { + written = snprintf(pos, len," '%N' 0x%06x/0x%02x", + pen_names, vid, vid, subtype); + } if (written >= len) { break; } pos += written; len -= written; + + this->supported_vids[i] = vid; + this->supported_subtypes[i] = subtype; } - this->supported_types = malloc(size); - memcpy(this->supported_types, supported_types, size); } *pos = '\0'; - DBG2(DBG_TNC, "IMV %u supports %u message types:%s", - this->id, type_count, buf); + DBG2(DBG_TNC, "IMV %u supports %u message type%s:%s", + this->id, type_count, (type_count == 1) ? "":"s", buf); + + /* unlock the imv_t instance */ + this->mutex->unlock(this->mutex); +} + +METHOD(imv_t, set_message_types_long, void, + private_tnc_imv_t *this, TNC_VendorIDList supported_vids, + TNC_MessageSubtypeList supported_subtypes, TNC_UInt32 type_count) +{ + char buf[BUF_LEN]; + char *pos = buf; + int len = sizeof(buf); + int i, written; + size_t size; + TNC_VendorID vid; + TNC_MessageSubtype subtype; + enum_name_t *pa_subtype_names; /* lock the imv_t instance */ + this->mutex->lock(this->mutex); + + /* Free existing VendorID and MessageSubtype lists */ + free(this->supported_vids); + this->supported_vids = NULL; + free(this->supported_subtypes); + this->supported_subtypes = NULL; + + /* Store the new MessageType list */ + this->type_count = type_count; + if (type_count && supported_vids && supported_subtypes) + { + size = type_count * sizeof(TNC_VendorID); + this->supported_vids = malloc(size); + memcpy(this->supported_vids, supported_vids, size); + size = type_count * sizeof(TNC_MessageSubtype); + this->supported_subtypes = malloc(size); + memcpy(this->supported_subtypes, supported_subtypes, size); + + for (i = 0; i < type_count; i++) + { + vid = supported_vids[i]; + subtype = supported_subtypes[i]; + + pa_subtype_names = get_pa_subtype_names(vid); + if (pa_subtype_names) + { + written = snprintf(pos, len," '%N/%N' 0x%06x/0x%08x", + pen_names, vid, pa_subtype_names, subtype, + vid, subtype); + } + else + { + written = snprintf(pos, len," '%N' 0x%06x/0x%08x", + pen_names, vid, vid, subtype); + } + if (written >= len) + { + break; + } + pos += written; + len -= written; + } + } + *pos = '\0'; + DBG2(DBG_TNC, "IMV %u supports %u message type%s:%s", + this->id, type_count, (type_count == 1) ? "":"s", buf); + + /* unlock the imv_t instance */ this->mutex->unlock(this->mutex); } METHOD(imv_t, type_supported, bool, - private_tnc_imv_t *this, TNC_MessageType message_type) + private_tnc_imv_t *this, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype) { - TNC_VendorID msg_vid, vid; - TNC_MessageSubtype msg_subtype, subtype; + TNC_VendorID vid; + TNC_MessageSubtype subtype; int i; - msg_vid = (message_type >> 8) & TNC_VENDORID_ANY; - msg_subtype = message_type & TNC_SUBTYPE_ANY; - for (i = 0; i < this->type_count; i++) { - vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY; - subtype = this->supported_types[i] & TNC_SUBTYPE_ANY; - - if (this->supported_types[i] == message_type - || (subtype == TNC_SUBTYPE_ANY - && (msg_vid == vid || vid == TNC_VENDORID_ANY)) - || (vid == TNC_VENDORID_ANY - && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY))) + vid = this->supported_vids[i]; + subtype = this->supported_subtypes[i]; + + if ((vid == TNC_VENDORID_ANY && subtype == TNC_SUBTYPE_ANY) || + (vid == msg_vid && (subtype == TNC_SUBTYPE_ANY || + subtype == msg_subtype))) { return TRUE; } @@ -164,7 +305,9 @@ METHOD(imv_t, destroy, void, { dlclose(this->handle); this->mutex->destroy(this->mutex); - free(this->supported_types); + this->additional_ids->destroy_function(this->additional_ids, free); + free(this->supported_vids); + free(this->supported_subtypes); free(this->name); free(this->path); free(this); @@ -181,13 +324,17 @@ imv_t* tnc_imv_create(char *name, char *path) .public = { .set_id = _set_id, .get_id = _get_id, + .add_id = _add_id, + .has_id = _has_id, .get_name = _get_name, .set_message_types = _set_message_types, + .set_message_types_long = _set_message_types_long, .type_supported = _type_supported, .destroy = _destroy, }, .name = name, .path = path, + .additional_ids = linked_list_create(), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), ); @@ -222,6 +369,8 @@ imv_t* tnc_imv_create(char *name, char *path) } this->public.receive_message = dlsym(this->handle, "TNC_IMV_ReceiveMessage"); + this->public.receive_message_long = + dlsym(this->handle, "TNC_IMV_ReceiveMessageLong"); this->public.batch_ending = dlsym(this->handle, "TNC_IMV_BatchEnding"); this->public.terminate = diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c index 0ed00b001..dd11c5009 100644 --- a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c +++ b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Mike McCauley - * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2010-2011 Andreas Steffen + * HSR 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 @@ -13,12 +14,11 @@ * for more details. */ -#include "tnc_imv.h" +#include <tnc/tnc.h> +#include <tnc/imv/imv_manager.h> +#include <tnc/tnccs/tnccs_manager.h> #include <debug.h> -#include <daemon.h> - -#define TNC_IMCID_ANY 0xffff /** * Called by the IMV to inform a TNCS about the set of message types the IMV @@ -28,14 +28,33 @@ TNC_Result TNC_TNCS_ReportMessageTypes(TNC_IMVID imv_id, TNC_MessageTypeList supported_types, TNC_UInt32 type_count) { - if (!charon->imvs->is_registered(charon->imvs, imv_id)) + if (!tnc->imvs->is_registered(tnc->imvs, imv_id)) { DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMV %u", imv_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->imvs->set_message_types(charon->imvs, imv_id, - supported_types, type_count); + return tnc->imvs->set_message_types(tnc->imvs, imv_id, supported_types, + type_count); +} + +/** + * Called by the IMV to inform a TNCS about the set of message types the IMV + * is able to receive. This function supports long message types. + */ +TNC_Result TNC_TNCS_ReportMessageTypesLong(TNC_IMVID imv_id, + TNC_VendorIDList supported_vids, + TNC_MessageSubtypeList supported_subtypes, + TNC_UInt32 type_count) +{ + if (!tnc->imvs->is_registered(tnc->imvs, imv_id)) + { + DBG1(DBG_TNC, "ignoring ReportMessageTypesLong() from unregistered IMV %u", + imv_id); + return TNC_RESULT_INVALID_PARAMETER; + } + return tnc->imvs->set_message_types_long(tnc->imvs, imv_id, supported_vids, + supported_subtypes, type_count); } /** @@ -45,14 +64,14 @@ TNC_Result TNC_TNCS_RequestHandshakeRetry(TNC_IMVID imv_id, TNC_ConnectionID connection_id, TNC_RetryReason reason) { - if (!charon->imvs->is_registered(charon->imvs, imv_id)) + if (!tnc->imvs->is_registered(tnc->imvs, imv_id)) { DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMV %u", imv_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->tnccs->request_handshake_retry(charon->tnccs, FALSE, imv_id, - connection_id, reason); + return tnc->tnccs->request_handshake_retry(tnc->tnccs, FALSE, imv_id, + connection_id, reason); } /** @@ -64,14 +83,42 @@ TNC_Result TNC_TNCS_SendMessage(TNC_IMVID imv_id, TNC_UInt32 msg_len, TNC_MessageType msg_type) { - if (!charon->imvs->is_registered(charon->imvs, imv_id)) + TNC_VendorID msg_vid; + TNC_MessageSubtype msg_subtype; + + if (!tnc->imvs->is_registered(tnc->imvs, imv_id)) { DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMV %u", imv_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->tnccs->send_message(charon->tnccs, TNC_IMCID_ANY, imv_id, - connection_id, msg, msg_len, msg_type); + msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY; + msg_subtype = msg_type & TNC_SUBTYPE_ANY; + + return tnc->tnccs->send_message(tnc->tnccs, TNC_IMCID_ANY, imv_id, + connection_id, 0, msg, msg_len, msg_vid, msg_subtype); +} + +/** + * Called by the IMV when an IMV-IMC message is to be sent over IF-TNCCS 2.0 + */ +TNC_Result TNC_TNCS_SendMessageLong(TNC_IMVID imv_id, + TNC_ConnectionID connection_id, + TNC_UInt32 msg_flags, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype, + TNC_UInt32 imc_id) +{ + if (!tnc->imvs->is_registered(tnc->imvs, imv_id)) + { + DBG1(DBG_TNC, "ignoring SendMessageLong() from unregistered IMV %u", + imv_id); + return TNC_RESULT_INVALID_PARAMETER; + } + return tnc->tnccs->send_message(tnc->tnccs, imc_id, imv_id, connection_id, + msg_flags, msg, msg_len, msg_vid, msg_subtype); } /** @@ -83,14 +130,14 @@ TNC_Result TNC_TNCS_ProvideRecommendation(TNC_IMVID imv_id, TNC_IMV_Action_Recommendation recommendation, TNC_IMV_Evaluation_Result evaluation) { - if (!charon->imvs->is_registered(charon->imvs, imv_id)) + if (!tnc->imvs->is_registered(tnc->imvs, imv_id)) { DBG1(DBG_TNC, "ignoring ProvideRecommendation() from unregistered IMV %u", imv_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->tnccs->provide_recommendation(charon->tnccs, imv_id, - connection_id, recommendation, evaluation); + return tnc->tnccs->provide_recommendation(tnc->tnccs, imv_id, connection_id, + recommendation, evaluation); } /** @@ -104,13 +151,13 @@ TNC_Result TNC_TNCS_GetAttribute(TNC_IMVID imv_id, TNC_BufferReference buffer, TNC_UInt32 *out_value_len) { - if (!charon->imvs->is_registered(charon->imvs, imv_id)) + if (!tnc->imvs->is_registered(tnc->imvs, imv_id)) { DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMV %u", imv_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->tnccs->get_attribute(charon->tnccs, imv_id, connection_id, + return tnc->tnccs->get_attribute(tnc->tnccs, FALSE, imv_id, connection_id, attribute_id, buffer_len, buffer, out_value_len); } @@ -124,14 +171,28 @@ TNC_Result TNC_TNCS_SetAttribute(TNC_IMVID imv_id, TNC_UInt32 buffer_len, TNC_BufferReference buffer) { - if (!charon->imvs->is_registered(charon->imvs, imv_id)) + if (!tnc->imvs->is_registered(tnc->imvs, imv_id)) { DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMV %u", imv_id); return TNC_RESULT_INVALID_PARAMETER; } - return charon->tnccs->set_attribute(charon->tnccs, imv_id, connection_id, - attribute_id, buffer_len, buffer); + return tnc->tnccs->set_attribute(tnc->tnccs, FALSE, imv_id, connection_id, + attribute_id, buffer_len, buffer); +} + +/** + * Called by the IMV when it wants to reserve an additional IMV ID for itself + */ +TNC_Result TNC_TNCS_ReserveAdditionalIMVID(TNC_IMVID imv_id, TNC_UInt32 *new_id) +{ + if (tnc->imvs->reserve_id(tnc->imvs, imv_id, new_id)) + { + return TNC_RESULT_SUCCESS; + } + DBG1(DBG_TNC, "ignoring ReserveAdditionalIMVID() from unregistered IMV %u", + imv_id); + return TNC_RESULT_INVALID_PARAMETER; } /** @@ -145,6 +206,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id, { *function_pointer = (void*)TNC_TNCS_ReportMessageTypes; } + else if (streq(function_name, "TNC_TNCS_ReportMessageTypesLong")) + { + *function_pointer = (void*)TNC_TNCS_ReportMessageTypesLong; + } else if (streq(function_name, "TNC_TNCS_RequestHandshakeRetry")) { *function_pointer = (void*)TNC_TNCS_RequestHandshakeRetry; @@ -153,6 +218,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id, { *function_pointer = (void*)TNC_TNCS_SendMessage; } + else if (streq(function_name, "TNC_TNCS_SendMessageLong")) + { + *function_pointer = (void*)TNC_TNCS_SendMessageLong; + } else if (streq(function_name, "TNC_TNCS_ProvideRecommendation")) { *function_pointer = (void*)TNC_TNCS_ProvideRecommendation; @@ -165,6 +234,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id, { *function_pointer = (void*)TNC_TNCS_SetAttribute; } + else if (streq(function_name, "TNC_TNCS_ReserveAdditionalIMVID")) + { + *function_pointer = (void*)TNC_TNCS_ReserveAdditionalIMVID; + } else { return TNC_RESULT_INVALID_PARAMETER; diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c index 579ab06ff..b1da73156 100644 --- a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c +++ b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Mike McCauley - * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2010-2011 Andreas Steffen + * HSR 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 @@ -14,13 +15,22 @@ */ #include "tnc_imv_manager.h" +#include "tnc_imv.h" #include "tnc_imv_recommendations.h" -#include <tnc/imv/imv_manager.h> -#include <tnc/tncifimv.h> +#include <tncifimv.h> +#include <tncif_names.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> -#include <debug.h> #include <daemon.h> +#include <utils/lexparser.h> +#include <debug.h> #include <threading/mutex.h> typedef struct private_tnc_imv_manager_t private_tnc_imv_manager_t; @@ -101,6 +111,33 @@ METHOD(imv_manager_t, remove_, imv_t*, return removed_imv; } +METHOD(imv_manager_t, load, bool, + private_tnc_imv_manager_t *this, char *name, char *path) +{ + imv_t *imv; + + imv = tnc_imv_create(name, path); + if (!imv) + { + free(name); + free(path); + return FALSE; + } + if (!add(this, imv)) + { + if (imv->terminate && + imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS) + { + DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully", + imv->get_name(imv)); + } + imv->destroy(imv); + return FALSE; + } + DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv), name, path); + return TRUE; +} + METHOD(imv_manager_t, is_registered, bool, private_tnc_imv_manager_t *this, TNC_IMVID id) { @@ -111,9 +148,34 @@ METHOD(imv_manager_t, is_registered, bool, enumerator = this->imvs->create_enumerator(this->imvs); while (enumerator->enumerate(enumerator, &imv)) { - if (id == imv->get_id(imv)) + if (imv->has_id(imv, id)) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + return found; +} + +METHOD(imv_manager_t, reserve_id, bool, + private_tnc_imv_manager_t *this, TNC_IMVID id, TNC_UInt32 *new_id) +{ + enumerator_t *enumerator; + imv_t *imv; + bool found = FALSE; + + enumerator = this->imvs->create_enumerator(this->imvs); + while (enumerator->enumerate(enumerator, &imv)) + { + if (imv->get_id(imv)) { found = TRUE; + *new_id = this->next_imv_id++; + imv->add_id(imv, *new_id); + DBG2(DBG_TNC, "additional ID %u reserved for IMV with primary ID %u", + *new_id, id); break; } } @@ -231,6 +293,31 @@ METHOD(imv_manager_t, set_message_types, TNC_Result, return result; } +METHOD(imv_manager_t, set_message_types_long, TNC_Result, + private_tnc_imv_manager_t *this, TNC_IMVID id, + TNC_VendorIDList supported_vids, + TNC_MessageSubtypeList supported_subtypes, + TNC_UInt32 type_count) +{ + enumerator_t *enumerator; + imv_t *imv; + TNC_Result result = TNC_RESULT_FATAL; + + enumerator = this->imvs->create_enumerator(this->imvs); + while (enumerator->enumerate(enumerator, &imv)) + { + if (id == imv->get_id(imv)) + { + imv->set_message_types_long(imv, supported_vids, supported_subtypes, + type_count); + result = TNC_RESULT_SUCCESS; + break; + } + } + enumerator->destroy(enumerator); + return result; +} + METHOD(imv_manager_t, solicit_recommendation, void, private_tnc_imv_manager_t *this, TNC_ConnectionID id) { @@ -247,28 +334,52 @@ METHOD(imv_manager_t, solicit_recommendation, void, METHOD(imv_manager_t, receive_message, void, private_tnc_imv_manager_t *this, TNC_ConnectionID connection_id, - TNC_BufferReference message, - TNC_UInt32 message_len, - TNC_MessageType message_type) + bool excl, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype, + TNC_UInt32 src_imc_id, + TNC_UInt32 dst_imv_id) { bool type_supported = FALSE; + TNC_MessageType msg_type; + TNC_UInt32 msg_flags; enumerator_t *enumerator; imv_t *imv; + msg_type = (msg_vid << 8) | msg_subtype; + enumerator = this->imvs->create_enumerator(this->imvs); while (enumerator->enumerate(enumerator, &imv)) { - if (imv->receive_message && imv->type_supported(imv, message_type)) + if (imv->type_supported(imv, msg_vid, msg_subtype) && + (!excl || (excl && imv->has_id(imv, dst_imv_id)) )) { - type_supported = TRUE; - imv->receive_message(imv->get_id(imv), connection_id, - message, message_len, message_type); + if (imv->receive_message_long && src_imc_id) + { + type_supported = TRUE; + msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0; + imv->receive_message_long(imv->get_id(imv), connection_id, + msg_flags, msg, msg_len, msg_vid, msg_subtype, + src_imc_id, dst_imv_id); + + } + else if (imv->receive_message && msg_vid <= TNC_VENDORID_ANY && + msg_subtype <= TNC_SUBTYPE_ANY) + { + type_supported = TRUE; + msg_type = (msg_vid << 8) | msg_subtype; + imv->receive_message(imv->get_id(imv), connection_id, + msg, msg_len, msg_type); + } } } enumerator->destroy(enumerator); if (!type_supported) { - DBG2(DBG_TNC, "message type 0x%08x not supported by any IMV", message_type); + DBG2(DBG_TNC, "message type 0x%06x/0x%08x not supported by any IMV", + msg_vid, msg_subtype); } } @@ -289,6 +400,7 @@ METHOD(imv_manager_t, batch_ending, void, enumerator->destroy(enumerator); } + METHOD(imv_manager_t, destroy, void, private_tnc_imv_manager_t *this) { @@ -320,12 +432,15 @@ imv_manager_t* tnc_imv_manager_create(void) .public = { .add = _add, .remove = _remove_, /* avoid name conflict with stdio.h */ + .load = _load, .is_registered = _is_registered, + .reserve_id = _reserve_id, .get_recommendation_policy = _get_recommendation_policy, .create_recommendations = _create_recommendations, .enforce_recommendation = _enforce_recommendation, .notify_connection_change = _notify_connection_change, .set_message_types = _set_message_types, + .set_message_types_long = _set_message_types_long, .solicit_recommendation = _solicit_recommendation, .receive_message = _receive_message, .batch_ending = _batch_ending, @@ -334,6 +449,7 @@ imv_manager_t* tnc_imv_manager_create(void) .imvs = linked_list_create(), .next_imv_id = 1, ); + policy = enum_from_name(recommendation_policy_names, lib->settings->get_str(lib->settings, "charon.plugins.tnc-imv.recommendation_policy", "default")); diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c index 45cf95c1b..c16f6b9e1 100644 --- a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c +++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010-2011 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,137 +15,24 @@ #include "tnc_imv_plugin.h" #include "tnc_imv_manager.h" -#include "tnc_imv.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> +#include <tnc/tnc.h> -#include <daemon.h> -#include <utils/lexparser.h> + +typedef struct private_tnc_imv_plugin_t private_tnc_imv_plugin_t; /** - * load IMVs from a configuration file + * Private data of a tnc_imv_plugin_t object. */ -static bool load_imvs(char *filename) -{ - int fd, line_nr = 0; - chunk_t src, line; - struct stat sb; - void *addr; - - DBG1(DBG_TNC, "loading IMVs from '%s'", filename); - fd = open(filename, O_RDONLY); - if (fd == -1) - { - DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename, - strerror(errno)); - return FALSE; - } - if (fstat(fd, &sb) == -1) - { - DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename, - strerror(errno)); - close(fd); - return FALSE; - } - addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (addr == MAP_FAILED) - { - DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno)); - close(fd); - return FALSE; - } - src = chunk_create(addr, sb.st_size); - - while (fetchline(&src, &line)) - { - char *name, *path; - chunk_t token; - imv_t *imv; - - line_nr++; - - /* skip comments or empty lines */ - if (*line.ptr == '#' || !eat_whitespace(&line)) - { - continue; - } - - /* determine keyword */ - if (!extract_token(&token, ' ', &line)) - { - DBG1(DBG_TNC, "line %d: keyword must be followed by a space", - line_nr); - return FALSE; - } - - /* only interested in IMVs */ - if (!match("IMV", &token)) - { - continue; - } - - /* advance to the IMV name and extract it */ - if (!extract_token(&token, '"', &line) || - !extract_token(&token, '"', &line)) - { - DBG1(DBG_TNC, "line %d: IMV name must be set in double quotes", - line_nr); - return FALSE; - } +struct private_tnc_imv_plugin_t { - /* copy the IMV name */ - name = malloc(token.len + 1); - memcpy(name, token.ptr, token.len); - name[token.len] = '\0'; + /** + * Public interface. + */ + tnc_imv_plugin_t public; - /* advance to the IMV path and extract it */ - if (!eat_whitespace(&line)) - { - DBG1(DBG_TNC, "line %d: IMV path is missing", line_nr); - free(name); - return FALSE; - } - if (!extract_token(&token, ' ', &line)) - { - token = line; - } +}; - /* copy the IMV path */ - path = malloc(token.len + 1); - memcpy(path, token.ptr, token.len); - path[token.len] = '\0'; - - /* load and register IMV instance */ - imv = tnc_imv_create(name, path); - if (!imv) - { - free(name); - free(path); - return FALSE; - } - if (!charon->imvs->add(charon->imvs, imv)) - { - if (imv->terminate && - imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS) - { - DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully", - imv->get_name(imv)); - } - imv->destroy(imv); - return FALSE; - } - DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv), - name, path); - } - munmap(addr, sb.st_size); - close(fd); - return TRUE; -} METHOD(plugin_t, get_name, char*, tnc_imv_plugin_t *this) @@ -153,10 +40,21 @@ METHOD(plugin_t, get_name, char*, return "tnc-imv"; } +METHOD(plugin_t, get_features, int, + private_tnc_imv_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(tnc_manager_register, tnc_imv_manager_create), + PLUGIN_PROVIDE(CUSTOM, "imv-manager"), + PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, - tnc_imv_plugin_t *this) + private_tnc_imv_plugin_t *this) { - charon->imvs->destroy(charon->imvs); free(this); } @@ -165,31 +63,18 @@ METHOD(plugin_t, destroy, void, */ plugin_t *tnc_imv_plugin_create() { - char *tnc_config; - tnc_imv_plugin_t *this; + private_tnc_imv_plugin_t *this; INIT(this, - .plugin = { - .get_name = _get_name, - .reload = (void*)return_false, - .destroy = _destroy, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, }, ); - tnc_config = lib->settings->get_str(lib->settings, - "charon.plugins.tnc-imv.tnc_config", "/etc/tnc_config"); - - /* Create IMV manager */ - charon->imvs = tnc_imv_manager_create(); - - /* Load IMVs and abort if not all instances initalize successfully */ - if (!load_imvs(tnc_config)) - { - charon->imvs->destroy(charon->imvs); - charon->imvs = NULL; - free(this); - return NULL; - } - return &this->plugin; + return &this->public.plugin; } diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c index 5cc6b0ced..7843293a1 100644 --- a/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c +++ b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c @@ -12,12 +12,17 @@ * for more details. */ -#include <debug.h> -#include <daemon.h> -#include <tnc/tncifimv.h> +#include <tncifimv.h> +#include <tncif_names.h> + +#include <tnc/tnc.h> #include <tnc/imv/imv.h> +#include <tnc/imv/imv_manager.h> #include <tnc/imv/imv_recommendations.h> +#include <debug.h> +#include <utils/linked_list.h> + typedef struct private_tnc_imv_recommendations_t private_tnc_imv_recommendations_t; typedef struct recommendation_entry_t recommendation_entry_t; @@ -126,7 +131,7 @@ METHOD(recommendations_t, have_recommendation, bool, DBG1(DBG_TNC, "there are no IMVs to make a recommendation"); return TRUE; } - policy = charon->imvs->get_recommendation_policy(charon->imvs); + policy = tnc->imvs->get_recommendation_policy(tnc->imvs); enumerator = this->recs->create_enumerator(this->recs); while (enumerator->enumerate(enumerator, &entry)) @@ -357,6 +362,21 @@ METHOD(recommendations_t, create_reason_enumerator, enumerator_t*, (void*)reason_filter, NULL, NULL); } +METHOD(recommendations_t, clear_reasons, void, + private_tnc_imv_recommendations_t *this) +{ + enumerator_t *enumerator; + recommendation_entry_t *entry; + + enumerator = this->recs->create_enumerator(this->recs); + while (enumerator->enumerate(enumerator, &entry)) + { + chunk_clear(&entry->reason); + chunk_clear(&entry->reason_language); + } + enumerator->destroy(enumerator); +} + METHOD(recommendations_t, destroy, void, private_tnc_imv_recommendations_t *this) { @@ -392,6 +412,7 @@ recommendations_t* tnc_imv_recommendations_create(linked_list_t *imv_list) .set_reason_string = _set_reason_string, .set_reason_language = _set_reason_language, .create_reason_enumerator = _create_reason_enumerator, + .clear_reasons = _clear_reasons, .destroy = _destroy, }, .recs = linked_list_create(), diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.am b/src/libcharon/plugins/tnc_pdp/Makefile.am new file mode 100644 index 000000000..2d4c4d55a --- /dev/null +++ b/src/libcharon/plugins/tnc_pdp/Makefile.am @@ -0,0 +1,24 @@ + +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libradius + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-tnc-pdp.la +else +plugin_LTLIBRARIES = libstrongswan-tnc-pdp.la +libstrongswan_tnc_pdp_la_LIBADD = \ + $(top_builddir)/src/libradius/libradius.la \ + $(top_builddir)/src/libtls/libtls.la \ + $(top_builddir)/src/libtnccs/libtnccs.la +endif + +libstrongswan_tnc_pdp_la_SOURCES = \ + tnc_pdp_plugin.h tnc_pdp_plugin.c \ + tnc_pdp.h tnc_pdp.c tnc_pdp_connections.h tnc_pdp_connections.c + +libstrongswan_tnc_pdp_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in new file mode 100644 index 000000000..70d3d6249 --- /dev/null +++ b/src/libcharon/plugins/tnc_pdp/Makefile.in @@ -0,0 +1,627 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libcharon/plugins/tnc_pdp +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +@MONOLITHIC_FALSE@libstrongswan_tnc_pdp_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libradius/libradius.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la +am_libstrongswan_tnc_pdp_la_OBJECTS = tnc_pdp_plugin.lo tnc_pdp.lo \ + tnc_pdp_connections.lo +libstrongswan_tnc_pdp_la_OBJECTS = \ + $(am_libstrongswan_tnc_pdp_la_OBJECTS) +libstrongswan_tnc_pdp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_tnc_pdp_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_tnc_pdp_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_tnc_pdp_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstrongswan_tnc_pdp_la_SOURCES) +DIST_SOURCES = $(libstrongswan_tnc_pdp_la_SOURCES) +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@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +default_pkcs11 = @default_pkcs11@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +oldincludedir = @oldincludedir@ +openac_plugins = @openac_plugins@ +p_plugins = @p_plugins@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pluto_plugins = @pluto_plugins@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libradius + +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-pdp.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-pdp.la +@MONOLITHIC_FALSE@libstrongswan_tnc_pdp_la_LIBADD = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libradius/libradius.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la + +libstrongswan_tnc_pdp_la_SOURCES = \ + tnc_pdp_plugin.h tnc_pdp_plugin.c \ + tnc_pdp.h tnc_pdp.c tnc_pdp_connections.h tnc_pdp_connections.c + +libstrongswan_tnc_pdp_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_pdp/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_pdp/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libstrongswan-tnc-pdp.la: $(libstrongswan_tnc_pdp_la_OBJECTS) $(libstrongswan_tnc_pdp_la_DEPENDENCIES) + $(libstrongswan_tnc_pdp_la_LINK) $(am_libstrongswan_tnc_pdp_la_rpath) $(libstrongswan_tnc_pdp_la_OBJECTS) $(libstrongswan_tnc_pdp_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_pdp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_pdp_connections.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_pdp_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c new file mode 100644 index 000000000..0625baa90 --- /dev/null +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c @@ -0,0 +1,648 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR 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. + */ + +#include "tnc_pdp.h" +#include "tnc_pdp_connections.h" + +#include <errno.h> +#include <unistd.h> + +#include <radius_message.h> +#include <radius_mppe.h> + +#include <daemon.h> +#include <debug.h> +#include <pen/pen.h> +#include <threading/thread.h> +#include <processing/jobs/callback_job.h> +#include <sa/authenticators/eap/eap_method.h> + +typedef struct private_tnc_pdp_t private_tnc_pdp_t; + +/** + * Maximum size of a RADIUS IP packet + */ +#define MAX_PACKET 4096 + +/** + * private data of tnc_pdp_t + */ +struct private_tnc_pdp_t { + + /** + * implements tnc_pdp_t interface + */ + tnc_pdp_t public; + + /** + * ID of the server + */ + identification_t *server; + + /** + * EAP method type to be used + */ + eap_type_t type; + + /** + * IPv4 RADIUS socket + */ + int ipv4; + + /** + * IPv6 RADIUS socket + */ + int ipv6; + + /** + * Callback job dispatching commands + */ + callback_job_t *job; + + /** + * RADIUS shared secret + */ + chunk_t secret; + + /** + * MD5 hasher + */ + hasher_t *hasher; + + /** + * HMAC MD5 signer, with secret set + */ + signer_t *signer; + + /** + * Random number generator for MS-MPPE salt values + */ + rng_t *rng; + + /** + * List of registered TNC-PDP connections + */ + tnc_pdp_connections_t *connections; +}; + + +/** + * Open IPv4 or IPv6 UDP RADIUS socket + */ +static int open_socket(int family, u_int16_t port) +{ + int on = TRUE; + struct sockaddr_storage addr; + socklen_t addrlen; + int skt; + + memset(&addr, 0, sizeof(addr)); + addr.ss_family = family; + + /* precalculate constants depending on address family */ + switch (family) + { + case AF_INET: + { + struct sockaddr_in *sin = (struct sockaddr_in *)&addr; + + htoun32(&sin->sin_addr.s_addr, INADDR_ANY); + htoun16(&sin->sin_port, port); + addrlen = sizeof(struct sockaddr_in); + break; + } + case AF_INET6: + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr; + + memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any)); + htoun16(&sin6->sin6_port, port); + addrlen = sizeof(struct sockaddr_in6); + break; + } + default: + return 0; + } + + /* open the socket */ + skt = socket(family, SOCK_DGRAM, IPPROTO_UDP); + if (skt < 0) + { + DBG1(DBG_CFG, "opening RADIUS socket failed: %s", strerror(errno)); + return 0; + } + if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0) + { + DBG1(DBG_CFG, "unable to set SO_REUSEADDR on socket: %s", strerror(errno)); + close(skt); + return 0; + } + + /* bind the socket */ + if (bind(skt, (struct sockaddr *)&addr, addrlen) < 0) + { + DBG1(DBG_CFG, "unable to bind RADIUS socket: %s", strerror(errno)); + close(skt); + return 0; + } + + return skt; +} + +/** + * Send a RADIUS message to client + */ +static void send_message(private_tnc_pdp_t *this, radius_message_t *message, + host_t *client) +{ + int fd; + chunk_t data; + + fd = (client->get_family(client) == AF_INET) ? this->ipv4 : this->ipv6; + data = message->get_encoding(message); + + DBG2(DBG_CFG, "sending RADIUS packet to %#H", client); + DBG3(DBG_CFG, "%B", &data); + + if (sendto(fd, data.ptr, data.len, 0, client->get_sockaddr(client), + *client->get_sockaddr_len(client)) != data.len) + { + DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno)); + } +} + +/** + * Encrypt a MS-MPPE-Send/Recv-Key + */ +static chunk_t encrypt_mppe_key(private_tnc_pdp_t *this, u_int8_t type, + chunk_t key, u_int16_t *salt, + radius_message_t *request) +{ + chunk_t a, r, seed, data; + u_char b[HASH_SIZE_MD5], *c; + mppe_key_t *mppe_key; + + /** + * From RFC2548 (encryption): + * b(1) = MD5(S + R + A) c(1) = p(1) xor b(1) C = c(1) + * b(2) = MD5(S + c(1)) c(2) = p(2) xor b(2) C = C + c(2) + * . . . + * b(i) = MD5(S + c(i-1)) c(i) = p(i) xor b(i) C = C + c(i) + */ + + data = chunk_alloc(sizeof(mppe_key_t) + + HASH_SIZE_MD5 * (1 + key.len / HASH_SIZE_MD5)); + memset(data.ptr, 0x00, data.len); + + mppe_key = (mppe_key_t*)data.ptr; + mppe_key->id = htonl(PEN_MICROSOFT); + mppe_key->type = type; + mppe_key->length = data.len - sizeof(mppe_key->id); + mppe_key->key[0] = key.len; + + memcpy(&mppe_key->key[1], key.ptr, key.len); + + /** + * generate a 16 bit unique random salt value for the MPPE stream cipher + * the MSB of the salt MUST be set to 1 + */ + a = chunk_create((u_char*)&(mppe_key->salt), sizeof(mppe_key->salt)); + do + { + this->rng->get_bytes(this->rng, a.len, a.ptr); + *a.ptr |= 0x80; + } + while (mppe_key->salt == *salt); + + /* update the salt value */ + *salt = mppe_key->salt; + + r = chunk_create(request->get_authenticator(request), HASH_SIZE_MD5); + seed = chunk_cata("cc", r, a); + + c = mppe_key->key; + while (c < data.ptr + data.len) + { + /* b(i) = MD5(S + c(i-1)) */ + this->hasher->get_hash(this->hasher, this->secret, NULL); + this->hasher->get_hash(this->hasher, seed, b); + + /* c(i) = b(i) xor p(1) */ + memxor(c, b, HASH_SIZE_MD5); + + /* prepare next round */ + seed = chunk_create(c, HASH_SIZE_MD5); + c += HASH_SIZE_MD5; + } + + return data; +} + +/** + * Send a RADIUS response for a request + */ +static void send_response(private_tnc_pdp_t *this, radius_message_t *request, + radius_message_code_t code, eap_payload_t *eap, + identification_t *group, chunk_t msk, host_t *client) +{ + radius_message_t *response; + chunk_t data, recv, send; + u_int32_t tunnel_type; + u_int16_t salt = 0; + + response = radius_message_create(code); + if (eap) + { + data = eap->get_data(eap); + DBG3(DBG_CFG, "%N payload %B", eap_type_names, this->type, &data); + + /* fragment data suitable for RADIUS */ + while (data.len > MAX_RADIUS_ATTRIBUTE_SIZE) + { + response->add(response, RAT_EAP_MESSAGE, + chunk_create(data.ptr, MAX_RADIUS_ATTRIBUTE_SIZE)); + data = chunk_skip(data, MAX_RADIUS_ATTRIBUTE_SIZE); + } + response->add(response, RAT_EAP_MESSAGE, data); + } + if (group) + { + tunnel_type = RADIUS_TUNNEL_TYPE_ESP; + htoun32(data.ptr, tunnel_type); + data.len = sizeof(tunnel_type); + response->add(response, RAT_TUNNEL_TYPE, data); + response->add(response, RAT_FILTER_ID, group->get_encoding(group)); + } + if (msk.len) + { + recv = chunk_create(msk.ptr, msk.len / 2); + data = encrypt_mppe_key(this, MS_MPPE_RECV_KEY, recv, &salt, request); + response->add(response, RAT_VENDOR_SPECIFIC, data); + chunk_free(&data); + + send = chunk_create(msk.ptr + recv.len, msk.len - recv.len); + data = encrypt_mppe_key(this, MS_MPPE_SEND_KEY, send, &salt, request); + response->add(response, RAT_VENDOR_SPECIFIC, data); + chunk_free(&data); + } + response->set_identifier(response, request->get_identifier(request)); + response->sign(response, request->get_authenticator(request), + this->secret, this->hasher, this->signer, NULL, TRUE); + + DBG1(DBG_CFG, "sending RADIUS %N to client '%H'", radius_message_code_names, + code, client); + send_message(this, response, client); + response->destroy(response); +} + +/** + * Process EAP message + */ +static void process_eap(private_tnc_pdp_t *this, radius_message_t *request, + host_t *source) +{ + enumerator_t *enumerator; + eap_payload_t *in, *out = NULL; + eap_method_t *method; + eap_type_t eap_type; + u_int32_t eap_vendor; + chunk_t data, message = chunk_empty, msk = chunk_empty; + chunk_t user_name = chunk_empty, nas_id = chunk_empty; + identification_t *group = NULL; + radius_message_code_t code = RMC_ACCESS_CHALLENGE; + int type; + + enumerator = request->create_enumerator(request); + while (enumerator->enumerate(enumerator, &type, &data)) + { + switch (type) + { + case RAT_USER_NAME: + user_name = data; + break; + case RAT_NAS_IDENTIFIER: + nas_id = data; + break; + case RAT_EAP_MESSAGE: + if (data.len) + { + message = chunk_cat("mc", message, data); + } + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + if (message.len) + { + in = eap_payload_create_data(message); + + /* apply EAP method selected by RADIUS server */ + eap_type = in->get_type(in, &eap_vendor); + + DBG3(DBG_CFG, "%N payload %B", eap_type_names, eap_type, &message); + + if (eap_type == EAP_IDENTITY) + { + identification_t *peer; + chunk_t eap_identity; + + if (message.len < 5) + { + goto end; + } + eap_identity = chunk_create(message.ptr + 5, message.len - 5); + peer = identification_create_from_data(eap_identity); + method = charon->eap->create_instance(charon->eap, this->type, + 0, EAP_SERVER, this->server, peer); + if (!method) + { + peer->destroy(peer); + goto end; + } + this->connections->add(this->connections, nas_id, user_name, peer, + method); + method->initiate(method, &out); + } + else + { + ike_sa_t *ike_sa; + auth_cfg_t *auth; + auth_rule_t type; + identification_t *data; + enumerator_t *e; + + method = this->connections->get_state(this->connections, nas_id, + user_name, &ike_sa); + if (!method) + { + goto end; + } + charon->bus->set_sa(charon->bus, ike_sa); + + switch (method->process(method, in, &out)) + { + case NEED_MORE: + code = RMC_ACCESS_CHALLENGE; + break; + case SUCCESS: + code = RMC_ACCESS_ACCEPT; + method->get_msk(method, &msk); + auth = ike_sa->get_auth_cfg(ike_sa, FALSE); + e = auth->create_enumerator(auth); + while (e->enumerate(e, &type, &data)) + { + /* look for group memberships */ + if (type == AUTH_RULE_GROUP) + { + group = data; + } + } + e->destroy(e); + + DESTROY_IF(out); + out = eap_payload_create_code(EAP_SUCCESS, + in->get_identifier(in)); + break; + case FAILED: + default: + code = RMC_ACCESS_REJECT; + DESTROY_IF(out); + out = eap_payload_create_code(EAP_FAILURE, + in->get_identifier(in)); + } + charon->bus->set_sa(charon->bus, NULL); + } + + send_response(this, request, code, out, group, msk, source); + out->destroy(out); + + if (code == RMC_ACCESS_ACCEPT || code == RMC_ACCESS_REJECT) + { + this->connections->remove(this->connections, nas_id, user_name); + } + +end: + free(message.ptr); + in->destroy(in); + } +} + +/** + * Process packets received on the RADIUS socket + */ +static job_requeue_t receive(private_tnc_pdp_t *this) +{ + while (TRUE) + { + radius_message_t *request; + char buffer[MAX_PACKET]; + int max_fd = 0, selected = 0, bytes_read = 0; + fd_set rfds; + bool oldstate; + host_t *source; + struct msghdr msg; + struct iovec iov; + union { + struct sockaddr_in in4; + struct sockaddr_in6 in6; + } src; + + FD_ZERO(&rfds); + + if (this->ipv4) + { + FD_SET(this->ipv4, &rfds); + } + if (this->ipv6) + { + FD_SET(this->ipv6, &rfds); + } + max_fd = max(this->ipv4, this->ipv6); + + DBG2(DBG_CFG, "waiting for data on RADIUS sockets"); + oldstate = thread_cancelability(TRUE); + if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0) + { + thread_cancelability(oldstate); + continue; + } + thread_cancelability(oldstate); + + if (FD_ISSET(this->ipv4, &rfds)) + { + selected = this->ipv4; + } + else if (FD_ISSET(this->ipv6, &rfds)) + { + selected = this->ipv6; + } + else + { + /* oops, shouldn't happen */ + continue; + } + + /* read received packet */ + msg.msg_name = &src; + msg.msg_namelen = sizeof(src); + iov.iov_base = buffer; + iov.iov_len = MAX_PACKET; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_flags = 0; + + bytes_read = recvmsg(selected, &msg, 0); + if (bytes_read < 0) + { + DBG1(DBG_CFG, "error reading RADIUS socket: %s", strerror(errno)); + continue; + } + if (msg.msg_flags & MSG_TRUNC) + { + DBG1(DBG_CFG, "receive buffer too small, RADIUS packet discarded"); + continue; + } + source = host_create_from_sockaddr((sockaddr_t*)&src); + DBG2(DBG_CFG, "received RADIUS packet from %#H", source); + DBG3(DBG_CFG, "%b", buffer, bytes_read); + request = radius_message_parse(chunk_create(buffer, bytes_read)); + if (request) + { + DBG1(DBG_CFG, "received RADIUS %N from client '%H'", + radius_message_code_names, request->get_code(request), source); + + if (request->verify(request, NULL, this->secret, this->hasher, + this->signer)) + { + process_eap(this, request, source); + } + request->destroy(request); + + } + else + { + DBG1(DBG_CFG, "received invalid RADIUS message, ignored"); + } + source->destroy(source); + } + return JOB_REQUEUE_FAIR; +} + +METHOD(tnc_pdp_t, destroy, void, + private_tnc_pdp_t *this) +{ + if (this->job) + { + this->job->cancel(this->job); + } + if (this->ipv4) + { + close(this->ipv4); + } + if (this->ipv6) + { + close(this->ipv6); + } + DESTROY_IF(this->server); + DESTROY_IF(this->signer); + DESTROY_IF(this->hasher); + DESTROY_IF(this->rng); + DESTROY_IF(this->connections); + free(this); +} + +/* + * see header file + */ +tnc_pdp_t *tnc_pdp_create(u_int16_t port) +{ + private_tnc_pdp_t *this; + char *secret, *server, *eap_type_str; + + INIT(this, + .public = { + .destroy = _destroy, + }, + .ipv4 = open_socket(AF_INET, port), + .ipv6 = open_socket(AF_INET6, port), + .hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5), + .signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128), + .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK), + .connections = tnc_pdp_connections_create(), + ); + + if (!this->hasher || !this->signer || !this->rng) + { + DBG1(DBG_CFG, "RADIUS initialization failed, HMAC/MD5/RNG required"); + destroy(this); + return NULL; + } + if (!this->ipv4 && !this->ipv6) + { + DBG1(DBG_NET, "could not create any RADIUS sockets"); + destroy(this); + return NULL; + } + if (!this->ipv4) + { + DBG1(DBG_NET, "could not open IPv4 RADIUS socket, IPv4 disabled"); + } + if (!this->ipv6) + { + DBG1(DBG_NET, "could not open IPv6 RADIUS socket, IPv6 disabled"); + } + + server = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-pdp.server", NULL); + if (!server) + { + DBG1(DBG_CFG, "missing PDP server name, PDP disabled"); + destroy(this); + return NULL; + } + this->server = identification_create_from_string(server); + + secret = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-pdp.secret", NULL); + if (!secret) + { + DBG1(DBG_CFG, "missing RADIUS secret, PDP disabled"); + destroy(this); + return NULL; + } + this->secret = chunk_create(secret, strlen(secret)); + this->signer->set_key(this->signer, this->secret); + + eap_type_str = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-pdp.method", "ttls"); + this->type = eap_type_from_string(eap_type_str); + if (this->type == 0) + { + DBG1(DBG_CFG, "unrecognized eap method \"%s\"", eap_type_str); + destroy(this); + return NULL; + } + DBG1(DBG_IKE, "eap method %N selected", eap_type_names, this->type); + + this->job = callback_job_create_with_prio((callback_job_cb_t)receive, + this, NULL, NULL, JOB_PRIO_CRITICAL); + lib->processor->queue_job(lib->processor, (job_t*)this->job); + + return &this->public; +} + diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp.h b/src/libcharon/plugins/tnc_pdp/tnc_pdp.h new file mode 100644 index 000000000..06291220f --- /dev/null +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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 tnc_pdp_t tnc_pdp + * @{ @ingroup tnc_pdp + */ + +#ifndef TNC_PDP_H_ +#define TNC_PDP_H_ + +typedef struct tnc_pdp_t tnc_pdp_t; + +#include <library.h> + +/** + * Public interface of a TNC Policy Decision Point object + */ +struct tnc_pdp_t { + + /** + * implements plugin interface + */ + void (*destroy)(tnc_pdp_t *this); +}; + +/** + * Create a TNC PDP instance + * + * @param port RADIUS port of TNC PDP + */ +tnc_pdp_t* tnc_pdp_create(u_int16_t port); + +#endif /** TNC_PDP_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c new file mode 100644 index 000000000..175a57aba --- /dev/null +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR 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. + */ + +#include "tnc_pdp_connections.h" + +#include <utils/linked_list.h> +#include <debug.h> + +typedef struct private_tnc_pdp_connections_t private_tnc_pdp_connections_t; +typedef struct entry_t entry_t; + +/** + * Private data of tnc_pdp_connections_t + */ +struct private_tnc_pdp_connections_t { + + /** + * Implements tnc_pdp_connections_t interface + */ + tnc_pdp_connections_t public; + + /** + * List of TNC PEP RADIUS Connections + */ + linked_list_t *list; +}; + +/** + * Data entry for a TNC PEP RADIUS connection + */ +struct entry_t { + + /** + * NAS identifier of PEP + */ + chunk_t nas_id; + + /** + * User name of TNC Client + */ + chunk_t user_name; + + /** + * EAP method state + */ + eap_method_t *method; + + /** + * IKE SA used for bus communication + */ + ike_sa_t *ike_sa; +}; + +/** + * Free the memory allocated to a data entry + */ +static void free_entry(entry_t *this) +{ + this->method->destroy(this->method); + this->ike_sa->destroy(this->ike_sa); + free(this->nas_id.ptr); + free(this->user_name.ptr); + free(this); +} + +/** + * Find a matching data entry + */ +static bool equals_entry( entry_t *this, chunk_t nas_id, chunk_t user_name) +{ + bool no_nas_id = !this->nas_id.ptr && !nas_id.ptr; + + return (chunk_equals(this->nas_id, nas_id) || no_nas_id) && + chunk_equals(this->user_name, user_name); +} + +/** + * Find a matching data entry + */ +static void dbg_nas_user(chunk_t nas_id, chunk_t user_name, bool not, char *op) +{ + if (nas_id.len) + { + DBG1(DBG_CFG, "%s RADIUS connection for user '%.*s' NAS '%.*s'", + not ? "could not find" : op, user_name.len, user_name.ptr, + nas_id.len, nas_id.ptr); + } + else + { + DBG1(DBG_CFG, "%s RADIUS connection for user '%.*s'", + not ? "could not find" : op, user_name.len, user_name.ptr); + } +} + +METHOD(tnc_pdp_connections_t, add, void, + private_tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name, + identification_t *peer, eap_method_t *method) +{ + enumerator_t *enumerator; + entry_t *entry; + ike_sa_id_t *ike_sa_id; + ike_sa_t *ike_sa; + bool found = FALSE; + + ike_sa_id = ike_sa_id_create(0, 0, FALSE); + ike_sa = ike_sa_create(ike_sa_id); + ike_sa_id->destroy(ike_sa_id); + ike_sa->set_other_id(ike_sa, peer); + + enumerator = this->list->create_enumerator(this->list); + while (enumerator->enumerate(enumerator, &entry)) + { + if (equals_entry(entry, nas_id, user_name)) + { + found = TRUE; + entry->method->destroy(entry->method); + entry->ike_sa->destroy(entry->ike_sa); + DBG1(DBG_CFG, "removed stale RADIUS connection"); + entry->method = method; + entry->ike_sa = ike_sa; + break; + } + } + enumerator->destroy(enumerator); + + if (!found) + { + entry = malloc_thing(entry_t); + entry->nas_id = chunk_clone(nas_id); + entry->user_name = chunk_clone(user_name); + entry->method = method; + entry->ike_sa = ike_sa; + this->list->insert_last(this->list, entry); + } + dbg_nas_user(nas_id, user_name, FALSE, "created"); +} + +METHOD(tnc_pdp_connections_t, remove_, void, + private_tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name) +{ + enumerator_t *enumerator; + entry_t *entry; + + enumerator = this->list->create_enumerator(this->list); + while (enumerator->enumerate(enumerator, &entry)) + { + if (equals_entry(entry, nas_id, user_name)) + { + free_entry(entry); + this->list->remove_at(this->list, enumerator); + dbg_nas_user(nas_id, user_name, FALSE, "removed"); + break; + } + } + enumerator->destroy(enumerator); +} + +METHOD(tnc_pdp_connections_t, get_state, eap_method_t*, + private_tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name, + ike_sa_t **ike_sa) +{ + enumerator_t *enumerator; + entry_t *entry; + eap_method_t *found = NULL; + + enumerator = this->list->create_enumerator(this->list); + while (enumerator->enumerate(enumerator, &entry)) + { + if (equals_entry(entry, nas_id, user_name)) + { + found = entry->method; + *ike_sa = entry->ike_sa; + break; + } + } + enumerator->destroy(enumerator); + + dbg_nas_user(nas_id, user_name, !found, "found"); + return found; +} + +METHOD(tnc_pdp_connections_t, destroy, void, + private_tnc_pdp_connections_t *this) +{ + this->list->destroy_function(this->list, (void*)free_entry); + free(this); +} + +/* + * see header file + */ +tnc_pdp_connections_t *tnc_pdp_connections_create(void) +{ + private_tnc_pdp_connections_t *this; + + INIT(this, + .public = { + .add = _add, + .remove = _remove_, + .get_state = _get_state, + .destroy = _destroy, + }, + .list = linked_list_create(), + ); + + return &this->public; +} + diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h new file mode 100644 index 000000000..b9f5d097b --- /dev/null +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR 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 tnc_pdp_connections tnc_pdp_connections + * @{ @ingroup tnc_pdp + */ + +#ifndef TNC_PDP_CONNECTIONS_H_ +#define TNC_PDP_CONNECTIONS_H_ + +typedef struct tnc_pdp_connections_t tnc_pdp_connections_t; + +#include <library.h> +#include <sa/ike_sa.h> +#include <sa/authenticators/eap/eap_method.h> + +/** + * Public interface of a tnc_pdp_connections object + */ +struct tnc_pdp_connections_t { + + /** + * Register a new TNC PEP RADIUS Connection + * + * @param nas_id NAS identifier of Policy Enforcement Point + * @param user_name User name of TNC Client + * @param peer Peer identity + * @param method EAP method state for this TNC PEP Connection + */ + void (*add)(tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name, + identification_t *peer, eap_method_t *method); + + /** + * Remove a TNC PEP RADIUS Connection + * + * @param nas_id NAS identifier of Policy Enforcement Point + * @param user_name User name of TNC Client + */ + void (*remove)(tnc_pdp_connections_t *this, chunk_t nas_id, + chunk_t user_name); + + /** + * Get the EAP method and IKE_SA of a registered TNC PEP RADIUS Connection + * + * @param nas_id NAS identifier of Policy Enforcement Point + * @param user_name User name of TNC Client + * @param ike_sa IKE_SA used for bus communication only + * @return EAP method for this connection or NULL if not found + */ + eap_method_t* (*get_state)(tnc_pdp_connections_t *this, chunk_t nas_id, + chunk_t user_name, ike_sa_t **ike_sa); + + /** + * Destroys a tnc_pdp_connections_t object. + */ + void (*destroy)(tnc_pdp_connections_t *this); +}; + +/** + * Create a tnc_pdp_connections_t instance + */ +tnc_pdp_connections_t* tnc_pdp_connections_create(void); + +#endif /** TNC_PDP_CONNECTIONS_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.c new file mode 100644 index 000000000..9abe02aec --- /dev/null +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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. + */ + +#include "tnc_pdp_plugin.h" +#include "tnc_pdp.h" + +typedef struct private_tnc_pdp_plugin_t private_tnc_pdp_plugin_t; + +/** + * Default RADIUS port, when not configured + */ +#define RADIUS_PORT 1812 + +/** + * private data of tnc_pdp plugin + */ +struct private_tnc_pdp_plugin_t { + + /** + * implements plugin interface + */ + tnc_pdp_plugin_t public; + + /** + * Policy Decision Point object + */ + tnc_pdp_t *pdp; + +}; + +METHOD(plugin_t, get_name, char*, + private_tnc_pdp_plugin_t *this) +{ + return "tnc-pdp"; +} + +METHOD(plugin_t, get_features, int, + private_tnc_pdp_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_PROVIDE(CUSTOM, "tnc-pdp"), + PLUGIN_DEPENDS(CUSTOM, "imv-manager"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_tnc_pdp_plugin_t *this) +{ + DESTROY_IF(this->pdp); + free(this); +} + +/* + * see header file + */ +plugin_t *tnc_pdp_plugin_create() +{ + private_tnc_pdp_plugin_t *this; + int port; + + port = lib->settings->get_int(lib->settings, + "charon.plugins.tnc_pdp.port", RADIUS_PORT); + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + .pdp = tnc_pdp_create(port), + ); + + return &this->public.plugin; +} + diff --git a/src/libcharon/tnc/tnccs/tnccs.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.h index 575b850f5..9b8b9ff0e 100644 --- a/src/libcharon/tnc/tnccs/tnccs.c +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2011 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -13,11 +13,30 @@ * for more details. */ -#include "tnccs.h" +/** + * @defgroup tnc_pdp tnc_pdp + * @ingroup cplugins + * + * @defgroup tnc_pdp_plugin tnc_pdp_plugin + * @{ @ingroup tnc_pdp + */ + +#ifndef TNC_PDP_PLUGIN_H_ +#define TNC_PDP_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct tnc_pdp_plugin_t tnc_pdp_plugin_t; + +/** + * TNC-PDP plugin + */ +struct tnc_pdp_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; -ENUM(tnccs_type_names, TNCCS_UNKNOWN, TNCCS_2_0, - "unknown TNCCS", - "TNCCS 1.1", - "TNCCS SOH", - "TNCCS 2.0", -); +#endif /** TNC_PDP_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_tnccs/Makefile.am b/src/libcharon/plugins/tnc_tnccs/Makefile.am new file mode 100644 index 000000000..c7fc02f7c --- /dev/null +++ b/src/libcharon/plugins/tnc_tnccs/Makefile.am @@ -0,0 +1,22 @@ + +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-tnc-tnccs.la +else +plugin_LTLIBRARIES = libstrongswan-tnc-tnccs.la +libstrongswan_tnc_tnccs_la_LIBADD = \ + $(top_builddir)/src/libtncif/libtncif.la \ + $(top_builddir)/src/libtnccs/libtnccs.la +endif + +libstrongswan_tnc_tnccs_la_SOURCES = \ + tnc_tnccs_plugin.h tnc_tnccs_plugin.c \ + tnc_tnccs_manager.h tnc_tnccs_manager.c + +libstrongswan_tnc_tnccs_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/tnc_tnccs/Makefile.in b/src/libcharon/plugins/tnc_tnccs/Makefile.in new file mode 100644 index 000000000..c12a837d1 --- /dev/null +++ b/src/libcharon/plugins/tnc_tnccs/Makefile.in @@ -0,0 +1,624 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libcharon/plugins/tnc_tnccs +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +@MONOLITHIC_FALSE@libstrongswan_tnc_tnccs_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la +am_libstrongswan_tnc_tnccs_la_OBJECTS = tnc_tnccs_plugin.lo \ + tnc_tnccs_manager.lo +libstrongswan_tnc_tnccs_la_OBJECTS = \ + $(am_libstrongswan_tnc_tnccs_la_OBJECTS) +libstrongswan_tnc_tnccs_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_tnc_tnccs_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_tnc_tnccs_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_tnc_tnccs_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstrongswan_tnc_tnccs_la_SOURCES) +DIST_SOURCES = $(libstrongswan_tnc_tnccs_la_SOURCES) +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@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +default_pkcs11 = @default_pkcs11@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +oldincludedir = @oldincludedir@ +openac_plugins = @openac_plugins@ +p_plugins = @p_plugins@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pluto_plugins = @pluto_plugins@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs + +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-tnccs.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-tnccs.la +@MONOLITHIC_FALSE@libstrongswan_tnc_tnccs_la_LIBADD = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la + +libstrongswan_tnc_tnccs_la_SOURCES = \ + tnc_tnccs_plugin.h tnc_tnccs_plugin.c \ + tnc_tnccs_manager.h tnc_tnccs_manager.c + +libstrongswan_tnc_tnccs_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_tnccs/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_tnccs/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libstrongswan-tnc-tnccs.la: $(libstrongswan_tnc_tnccs_la_OBJECTS) $(libstrongswan_tnc_tnccs_la_DEPENDENCIES) + $(libstrongswan_tnc_tnccs_la_LINK) $(am_libstrongswan_tnc_tnccs_la_rpath) $(libstrongswan_tnc_tnccs_la_OBJECTS) $(libstrongswan_tnc_tnccs_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_tnccs_manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_tnccs_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libcharon/tnc/tnccs/tnccs_manager.c b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.c index 609742dc8..64ed160d9 100644 --- a/src/libcharon/tnc/tnccs/tnccs_manager.c +++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.c @@ -13,16 +13,18 @@ * for more details. */ -#include "tnccs_manager.h" +#include "tnc_tnccs_manager.h" -#include <tnc/imv/imv_recommendations.h> +#include <tnc/tnc.h> +#include <tnc/imv/imv_manager.h> +#include <tnc/imc/imc_manager.h> +#include <tnc/imv/imv_manager.h> #include <debug.h> -#include <daemon.h> #include <utils/linked_list.h> #include <threading/rwlock.h> -typedef struct private_tnccs_manager_t private_tnccs_manager_t; +typedef struct private_tnc_tnccs_manager_t private_tnc_tnccs_manager_t; typedef struct tnccs_entry_t tnccs_entry_t; typedef struct tnccs_connection_entry_t tnccs_connection_entry_t; @@ -53,6 +55,11 @@ struct tnccs_connection_entry_t { TNC_ConnectionID id; /** + * TNCCS protocol type + */ + tnccs_type_t type; + + /** * TNCCS instance */ tnccs_t *tnccs; @@ -74,9 +81,9 @@ struct tnccs_connection_entry_t { }; /** - * private data of tnccs_manager + * private data of tnc_tnccs_manager */ -struct private_tnccs_manager_t { +struct private_tnc_tnccs_manager_t { /** * public functions @@ -111,7 +118,7 @@ struct private_tnccs_manager_t { }; METHOD(tnccs_manager_t, add_method, void, - private_tnccs_manager_t *this, tnccs_type_t type, + private_tnc_tnccs_manager_t *this, tnccs_type_t type, tnccs_constructor_t constructor) { tnccs_entry_t *entry; @@ -126,7 +133,7 @@ METHOD(tnccs_manager_t, add_method, void, } METHOD(tnccs_manager_t, remove_method, void, - private_tnccs_manager_t *this, tnccs_constructor_t constructor) + private_tnc_tnccs_manager_t *this, tnccs_constructor_t constructor) { enumerator_t *enumerator; tnccs_entry_t *entry; @@ -146,7 +153,7 @@ METHOD(tnccs_manager_t, remove_method, void, } METHOD(tnccs_manager_t, create_instance, tnccs_t*, - private_tnccs_manager_t *this, tnccs_type_t type, bool is_server) + private_tnc_tnccs_manager_t *this, tnccs_type_t type, bool is_server) { enumerator_t *enumerator; tnccs_entry_t *entry; @@ -172,32 +179,33 @@ METHOD(tnccs_manager_t, create_instance, tnccs_t*, } METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID, - private_tnccs_manager_t *this, tnccs_t *tnccs, + private_tnc_tnccs_manager_t *this, tnccs_type_t type, tnccs_t *tnccs, tnccs_send_message_t send_message, bool* request_handshake_retry, recommendations_t **recs) { tnccs_connection_entry_t *entry; entry = malloc_thing(tnccs_connection_entry_t); + entry->type = type; entry->tnccs = tnccs; entry->send_message = send_message; entry->request_handshake_retry = request_handshake_retry; if (recs) { /* we assume a TNC Server needing recommendations from IMVs */ - if (!charon->imvs) + if (!tnc->imvs) { - DBG1(DBG_TNC, "no IMV manager available!"); + DBG1(DBG_TNC, "no IMV manager available!"); free(entry); return 0; } - entry->recs = charon->imvs->create_recommendations(charon->imvs); + entry->recs = tnc->imvs->create_recommendations(tnc->imvs); *recs = entry->recs; } else { /* we assume a TNC Client */ - if (!charon->imcs) + if (!tnc->imcs) { DBG1(DBG_TNC, "no IMC manager available!"); free(entry); @@ -215,24 +223,24 @@ METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID, } METHOD(tnccs_manager_t, remove_connection, void, - private_tnccs_manager_t *this, TNC_ConnectionID id, bool is_server) + private_tnc_tnccs_manager_t *this, TNC_ConnectionID id, bool is_server) { enumerator_t *enumerator; tnccs_connection_entry_t *entry; if (is_server) { - if (charon->imvs) + if (tnc->imvs) { - charon->imvs->notify_connection_change(charon->imvs, id, + tnc->imvs->notify_connection_change(tnc->imvs, id, TNC_CONNECTION_STATE_DELETE); } } else { - if (charon->imcs) + if (tnc->imcs) { - charon->imcs->notify_connection_change(charon->imcs, id, + tnc->imcs->notify_connection_change(tnc->imcs, id, TNC_CONNECTION_STATE_DELETE); } } @@ -257,9 +265,9 @@ METHOD(tnccs_manager_t, remove_connection, void, } METHOD(tnccs_manager_t, request_handshake_retry, TNC_Result, - private_tnccs_manager_t *this, bool is_imc, TNC_UInt32 imcv_id, - TNC_ConnectionID id, - TNC_RetryReason reason) + private_tnc_tnccs_manager_t *this, bool is_imc, TNC_UInt32 imcv_id, + TNC_ConnectionID id, + TNC_RetryReason reason) { enumerator_t *enumerator; tnccs_connection_entry_t *entry; @@ -291,26 +299,24 @@ METHOD(tnccs_manager_t, request_handshake_retry, TNC_Result, } METHOD(tnccs_manager_t, send_message, TNC_Result, - private_tnccs_manager_t *this, TNC_IMCID imc_id, TNC_IMVID imv_id, - TNC_ConnectionID id, - TNC_BufferReference msg, - TNC_UInt32 msg_len, - TNC_MessageType msg_type) + private_tnc_tnccs_manager_t *this, TNC_IMCID imc_id, TNC_IMVID imv_id, + TNC_ConnectionID id, + TNC_UInt32 msg_flags, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype) { enumerator_t *enumerator; tnccs_connection_entry_t *entry; tnccs_send_message_t send_message = NULL; tnccs_t *tnccs = NULL; - TNC_VendorID msg_vid; - TNC_MessageSubtype msg_subtype; - - msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY; - msg_subtype = msg_type & TNC_SUBTYPE_ANY; if (msg_vid == TNC_VENDORID_ANY || msg_subtype == TNC_SUBTYPE_ANY) { - DBG1(DBG_TNC, "not sending message of invalid type 0x%08x", msg_type); + DBG1(DBG_TNC, "not sending message of invalid type 0x%02x/0x%08x", + msg_vid, msg_subtype); return TNC_RESULT_INVALID_PARAMETER; } @@ -330,16 +336,17 @@ METHOD(tnccs_manager_t, send_message, TNC_Result, if (tnccs && send_message) { - return send_message(tnccs, imc_id, imv_id, msg, msg_len, msg_type); + return send_message(tnccs, imc_id, imv_id, msg_flags, msg, msg_len, + msg_vid, msg_subtype); } return TNC_RESULT_FATAL; } METHOD(tnccs_manager_t, provide_recommendation, TNC_Result, - private_tnccs_manager_t *this, TNC_IMVID imv_id, - TNC_ConnectionID id, - TNC_IMV_Action_Recommendation rec, - TNC_IMV_Evaluation_Result eval) + private_tnc_tnccs_manager_t *this, TNC_IMVID imv_id, + TNC_ConnectionID id, + TNC_IMV_Action_Recommendation rec, + TNC_IMV_Evaluation_Result eval) { enumerator_t *enumerator; tnccs_connection_entry_t *entry; @@ -366,20 +373,150 @@ METHOD(tnccs_manager_t, provide_recommendation, TNC_Result, return TNC_RESULT_FATAL; } +/** + * Write the value of a boolean attribute into the buffer + */ +static TNC_Result bool_attribute(TNC_UInt32 buffer_len, + TNC_BufferReference buffer, + TNC_UInt32 *value_len, + bool value) +{ + *value_len = 1; + + if (buffer && buffer_len > 0) + { + *buffer = value ? 0x01 : 0x00; + return TNC_RESULT_SUCCESS; + } + else + { + return TNC_RESULT_INVALID_PARAMETER; + } +} + +/** + * Write the value of an u_int32_t attribute into the buffer + */ +static TNC_Result uint_attribute(TNC_UInt32 buffer_len, + TNC_BufferReference buffer, + TNC_UInt32 *value_len, + u_int32_t value) +{ + *value_len = sizeof(u_int32_t); + + if (buffer && buffer_len >= *value_len) + { + htoun32(buffer, value); + return TNC_RESULT_SUCCESS; + } + else + { + return TNC_RESULT_INVALID_PARAMETER; + } +} + +/** + * Write the value of string attribute into the buffer + */ +static TNC_Result str_attribute(TNC_UInt32 buffer_len, + TNC_BufferReference buffer, + TNC_UInt32 *value_len, + char *value) +{ + *value_len = 1 + strlen(value); + + if (buffer && buffer_len >= *value_len) + { + snprintf(buffer, buffer_len, "%s", value); + return TNC_RESULT_SUCCESS; + } + else + { + return TNC_RESULT_INVALID_PARAMETER; + } +} + METHOD(tnccs_manager_t, get_attribute, TNC_Result, - private_tnccs_manager_t *this, TNC_IMVID imv_id, - TNC_ConnectionID id, - TNC_AttributeID attribute_id, - TNC_UInt32 buffer_len, - TNC_BufferReference buffer, - TNC_UInt32 *out_value_len) + private_tnc_tnccs_manager_t *this, bool is_imc, + TNC_UInt32 imcv_id, + TNC_ConnectionID id, + TNC_AttributeID attribute_id, + TNC_UInt32 buffer_len, + TNC_BufferReference buffer, + TNC_UInt32 *value_len) { enumerator_t *enumerator; tnccs_connection_entry_t *entry; - recommendations_t *recs = NULL; + bool attribute_match = FALSE, entry_found = FALSE; + + if (is_imc) + { + switch (attribute_id) + { + /* these attributes are unsupported */ + case TNC_ATTRIBUTEID_SOHR: + case TNC_ATTRIBUTEID_SSOHR: + return TNC_RESULT_INVALID_PARAMETER; + + /* these attributes are supported */ + case TNC_ATTRIBUTEID_PRIMARY_IMC_ID: + attribute_match = TRUE; + break; + + /* these attributes are yet to be matched */ + default: + break; + } + } + else + { + switch (attribute_id) + { + /* these attributes are unsupported or invalid */ + case TNC_ATTRIBUTEID_REASON_STRING: + case TNC_ATTRIBUTEID_REASON_LANGUAGE: + case TNC_ATTRIBUTEID_SOH: + case TNC_ATTRIBUTEID_SSOH: + return TNC_RESULT_INVALID_PARAMETER; + + /* these attributes are supported */ + case TNC_ATTRIBUTEID_PRIMARY_IMV_ID: + attribute_match = TRUE; + break; + + /* these attributes are yet to be matched */ + default: + break; + } + } + + if (!attribute_match) + { + switch (attribute_id) + { + /* these attributes are supported */ + case TNC_ATTRIBUTEID_PREFERRED_LANGUAGE: + case TNC_ATTRIBUTEID_MAX_ROUND_TRIPS: + case TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE: + case TNC_ATTRIBUTEID_HAS_LONG_TYPES: + case TNC_ATTRIBUTEID_HAS_EXCLUSIVE: + case TNC_ATTRIBUTEID_HAS_SOH: + case TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL: + case TNC_ATTRIBUTEID_IFTNCCS_VERSION: + case TNC_ATTRIBUTEID_IFT_PROTOCOL: + case TNC_ATTRIBUTEID_IFT_VERSION: + break; - if (id == TNC_CONNECTIONID_ANY || - attribute_id != TNC_ATTRIBUTEID_PREFERRED_LANGUAGE) + /* these attributes are unsupported or unknown */ + case TNC_ATTRIBUTEID_DHPN: + case TNC_ATTRIBUTEID_TLS_UNIQUE: + default: + return TNC_RESULT_INVALID_PARAMETER; + } + } + + /* attributes specific to the TNCC or TNCS are unsupported */ + if (id == TNC_CONNECTIONID_ANY) { return TNC_RESULT_INVALID_PARAMETER; } @@ -390,44 +527,114 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result, { if (id == entry->id) { - recs = entry->recs; + entry_found = TRUE; break; } } enumerator->destroy(enumerator); this->connection_lock->unlock(this->connection_lock); - if (recs) + if (!entry_found) { - chunk_t pref_lang; + return TNC_RESULT_INVALID_PARAMETER; + } - pref_lang = recs->get_preferred_language(recs); - if (pref_lang.len == 0) + switch (attribute_id) + { + case TNC_ATTRIBUTEID_PREFERRED_LANGUAGE: { - return TNC_RESULT_INVALID_PARAMETER; + recommendations_t *recs; + chunk_t pref_lang; + + recs = entry->recs; + if (!recs) + { + return TNC_RESULT_INVALID_PARAMETER; + } + pref_lang = recs->get_preferred_language(recs); + if (pref_lang.len == 0) + { + return TNC_RESULT_INVALID_PARAMETER; + } + *value_len = pref_lang.len; + if (buffer && buffer_len >= pref_lang.len) + { + memcpy(buffer, pref_lang.ptr, pref_lang.len); + } + return TNC_RESULT_SUCCESS; } - *out_value_len = pref_lang.len; - if (buffer && buffer_len <= pref_lang.len) + case TNC_ATTRIBUTEID_MAX_ROUND_TRIPS: + return uint_attribute(buffer_len, buffer, value_len, 0xffffffff); + case TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE: + return uint_attribute(buffer_len, buffer, value_len, 0x00000000); + case TNC_ATTRIBUTEID_HAS_LONG_TYPES: + case TNC_ATTRIBUTEID_HAS_EXCLUSIVE: + return bool_attribute(buffer_len, buffer, value_len, + entry->type == TNCCS_2_0); + case TNC_ATTRIBUTEID_HAS_SOH: + return bool_attribute(buffer_len, buffer, value_len, + entry->type == TNCCS_SOH); + case TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL: { - memcpy(buffer, pref_lang.ptr, pref_lang.len); + char *protocol; + + switch (entry->type) + { + case TNCCS_1_1: + case TNCCS_2_0: + protocol = "IF-TNCCS"; + break; + case TNCCS_SOH: + protocol = "IF-TNCCS-SOH"; + break; + default: + return TNC_RESULT_INVALID_PARAMETER; + } + return str_attribute(buffer_len, buffer, value_len, protocol); } - return TNC_RESULT_SUCCESS; + case TNC_ATTRIBUTEID_IFTNCCS_VERSION: + { + char *version; + + switch (entry->type) + { + case TNCCS_1_1: + version = "1.1"; + break; + case TNCCS_2_0: + version = "2.0"; + break; + case TNCCS_SOH: + version = "1.0"; + break; + default: + return TNC_RESULT_INVALID_PARAMETER; + } + return str_attribute(buffer_len, buffer, value_len, version); + } + case TNC_ATTRIBUTEID_IFT_PROTOCOL: + return str_attribute(buffer_len, buffer, value_len, + "IF-T for Tunneled EAP"); + case TNC_ATTRIBUTEID_IFT_VERSION: + return str_attribute(buffer_len, buffer, value_len, "1.1"); + default: + return TNC_RESULT_INVALID_PARAMETER; } - return TNC_RESULT_INVALID_PARAMETER; } METHOD(tnccs_manager_t, set_attribute, TNC_Result, - private_tnccs_manager_t *this, TNC_IMVID imv_id, - TNC_ConnectionID id, - TNC_AttributeID attribute_id, - TNC_UInt32 buffer_len, - TNC_BufferReference buffer) + private_tnc_tnccs_manager_t *this, bool is_imc, + TNC_UInt32 imcv_id, + TNC_ConnectionID id, + TNC_AttributeID attribute_id, + TNC_UInt32 buffer_len, + TNC_BufferReference buffer) { enumerator_t *enumerator; tnccs_connection_entry_t *entry; recommendations_t *recs = NULL; - if (id == TNC_CONNECTIONID_ANY || + if (is_imc || id == TNC_CONNECTIONID_ANY || (attribute_id != TNC_ATTRIBUTEID_REASON_STRING && attribute_id != TNC_ATTRIBUTEID_REASON_LANGUAGE)) { @@ -453,18 +660,18 @@ METHOD(tnccs_manager_t, set_attribute, TNC_Result, if (attribute_id == TNC_ATTRIBUTEID_REASON_STRING) { - return recs->set_reason_string(recs, imv_id, attribute); + return recs->set_reason_string(recs, imcv_id, attribute); } else { - return recs->set_reason_language(recs, imv_id, attribute); + return recs->set_reason_language(recs, imcv_id, attribute); } } return TNC_RESULT_INVALID_PARAMETER; } METHOD(tnccs_manager_t, destroy, void, - private_tnccs_manager_t *this) + private_tnc_tnccs_manager_t *this) { this->protocols->destroy_function(this->protocols, free); this->protocol_lock->destroy(this->protocol_lock); @@ -476,9 +683,9 @@ METHOD(tnccs_manager_t, destroy, void, /* * See header */ -tnccs_manager_t *tnccs_manager_create() +tnccs_manager_t *tnc_tnccs_manager_create() { - private_tnccs_manager_t *this; + private_tnc_tnccs_manager_t *this; INIT(this, .public = { diff --git a/src/libcharon/tnc/imv/imv_recommendations.c b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.h index 9daaca16c..dd5149846 100644 --- a/src/libcharon/tnc/imv/imv_recommendations.c +++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.h @@ -13,12 +13,19 @@ * for more details. */ -#include "imv_recommendations.h" +/** + * @defgroup tnc_tnccs_manager tnc_tnccs_manager + * @{ @ingroup tnc_tnccs + */ + +#ifndef TNC_TNCCS_MANAGER_H_ +#define TNC_TNCCS_MANAGER_H_ -ENUM(recommendation_policy_names, RECOMMENDATION_POLICY_DEFAULT, - RECOMMENDATION_POLICY_ALL, - "default", - "any", - "all" -); +#include <tnc/tnccs/tnccs_manager.h> + +/** + * Create a TNCCS manager instance. + */ +tnccs_manager_t *tnc_tnccs_manager_create(); +#endif /** TNC_TNCCS_MANAGER_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.c b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.c new file mode 100644 index 000000000..a44319ed1 --- /dev/null +++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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. + */ + +#include "tnc_tnccs_plugin.h" +#include "tnc_tnccs_manager.h" + +#include <tnc/tnc.h> + +#include <debug.h> + +typedef struct private_tnc_tnccs_plugin_t private_tnc_tnccs_plugin_t; + +/** + * Private data of a tnc_tnccs_plugin_t object. + */ +struct private_tnc_tnccs_plugin_t { + + /** + * Public interface. + */ + tnc_tnccs_plugin_t public; + +}; + + +METHOD(plugin_t, get_name, char*, + private_tnc_tnccs_plugin_t *this) +{ + return "tnc-tnccs"; +} + +METHOD(plugin_t, get_features, int, + private_tnc_tnccs_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(tnc_manager_register, tnc_tnccs_manager_create), + PLUGIN_PROVIDE(CUSTOM, "tnccs-manager"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_tnc_tnccs_plugin_t *this) +{ + libtnccs_deinit(); + free(this); +} + +/* + * see header file + */ +plugin_t *tnc_tnccs_plugin_create(void) +{ + private_tnc_tnccs_plugin_t *this; + + if (lib->integrity) + { + if (lib->integrity->check(lib->integrity, "libtnccs", libtnccs_init)) + { + DBG1(DBG_LIB, + "lib 'libtnccs': passed file and segment integrity tests"); + } + else + { + DBG1(DBG_LIB, + "lib 'libtnccs': failed integrity tests"); + return NULL; + } + } + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + libtnccs_init(); + + return &this->public.plugin; +} + diff --git a/src/libcharon/tnc/tncifimv.c b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.h index fbfd56566..f935fa462 100644 --- a/src/libcharon/tnc/tncifimv.c +++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.h @@ -13,24 +13,30 @@ * for more details. */ -#include "tncifimv.h" +/** + * @defgroup tnc_tnccs tnc_tnccs + * @ingroup cplugins + * + * @defgroup tnc_tnccs_plugin tnc_tnccs_plugin + * @{ @ingroup tnc_tnccs + */ + +#ifndef TNC_TNCCS_PLUGIN_H_ +#define TNC_TNCCS_PLUGIN_H_ -ENUM(TNC_IMV_Action_Recommendation_names, - TNC_IMV_ACTION_RECOMMENDATION_ALLOW, - TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, - "allow", - "no access", - "isolate", - "no recommendation" -); +#include <plugins/plugin.h> + +typedef struct tnc_tnccs_plugin_t tnc_tnccs_plugin_t; + +/** + * TNCCS manager plugin + */ +struct tnc_tnccs_plugin_t { -ENUM(TNC_IMV_Evaluation_Result_names, - TNC_IMV_EVALUATION_RESULT_COMPLIANT, - TNC_IMV_EVALUATION_RESULT_DONT_KNOW, - "compliant", - "non-compliant minor", - "non-compliant major", - "error", - "don't know" -); + /** + * implements plugin interface + */ + plugin_t plugin; +}; +#endif /** TNC_TNCCS_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/Makefile.am b/src/libcharon/plugins/tnccs_11/Makefile.am index 1042c3514..c205692d4 100644 --- a/src/libcharon/plugins/tnccs_11/Makefile.am +++ b/src/libcharon/plugins/tnccs_11/Makefile.am @@ -1,6 +1,10 @@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls ${xml_CFLAGS} +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs \ + ${xml_CFLAGS} AM_CFLAGS = -rdynamic @@ -10,6 +14,9 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-tnccs-11.la else plugin_LTLIBRARIES = libstrongswan-tnccs-11.la +libstrongswan_tnccs_11_la_LIBADD += \ + $(top_builddir)/src/libtncif/libtncif.la \ + $(top_builddir)/src/libtnccs/libtnccs.la endif libstrongswan_tnccs_11_la_SOURCES = \ diff --git a/src/libcharon/plugins/tnccs_11/Makefile.in b/src/libcharon/plugins/tnccs_11/Makefile.in index 308dd57ca..1902d1f93 100644 --- a/src/libcharon/plugins/tnccs_11/Makefile.in +++ b/src/libcharon/plugins/tnccs_11/Makefile.in @@ -34,6 +34,10 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@MONOLITHIC_FALSE@am__append_1 = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la + subdir = src/libcharon/plugins/tnccs_11 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -75,7 +79,8 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) am__DEPENDENCIES_1 = -libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__append_1) am_libstrongswan_tnccs_11_la_OBJECTS = tnccs_11_plugin.lo tnccs_11.lo \ tnccs_batch.lo tnccs_msg.lo imc_imv_msg.lo tnccs_error_msg.lo \ tnccs_preferred_language_msg.lo tnccs_reason_strings_msg.lo \ @@ -198,6 +203,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -206,6 +214,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -222,11 +231,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -270,6 +281,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -280,11 +292,15 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls ${xml_CFLAGS} +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs \ + ${xml_CFLAGS} AM_CFLAGS = -rdynamic -libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS} +libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS} $(am__append_1) @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-11.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-11.la libstrongswan_tnccs_11_la_SOURCES = \ diff --git a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c index 0f6f3a675..c9397722b 100644 --- a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c +++ b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c @@ -16,10 +16,11 @@ #include "tnccs_batch.h" #include "messages/tnccs_error_msg.h" -#include <debug.h> -#include <utils/linked_list.h> #include <tnc/tnccs/tnccs.h> +#include <utils/linked_list.h> +#include <debug.h> + #include <libxml/parser.h> typedef struct private_tnccs_batch_t private_tnccs_batch_t; diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c index f24c0dac9..fa570aae9 100644 --- a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c +++ b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c @@ -16,8 +16,9 @@ #include "imc_imv_msg.h" #include <tnc/tnccs/tnccs.h> -#include <debug.h> + #include <utils/lexparser.h> +#include <debug.h> typedef struct private_imc_imv_msg_t private_imc_imv_msg_t; diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h index 02f07199f..3477fa74e 100644 --- a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h +++ b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h @@ -25,7 +25,7 @@ typedef struct imc_imv_msg_t imc_imv_msg_t; #include "tnccs_msg.h" -#include <tnc/tncif.h> +#include <tncif.h> /** * Classs representing the PB-PA message type. diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h index d301ab2bb..c2de7fe4d 100644 --- a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h @@ -25,7 +25,7 @@ typedef struct tnccs_preferred_language_msg_t tnccs_preferred_language_msg_t; #include "tnccs_msg.h" -#include <tnc/tncif.h> +#include <tncif.h> /** * Class representing the TNCCS-PreferredLanguage message type diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c index d4b5d9bf9..af60a4b3a 100644 --- a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c @@ -14,6 +14,7 @@ */ #include "tnccs_reason_strings_msg.h" +#include "tnccs_error_msg.h" #include <debug.h> @@ -85,6 +86,10 @@ tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node, linked_list_t *errors) { private_tnccs_reason_strings_msg_t *this; + char *error_msg, *lang_string, *reason_string; + tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH; + tnccs_msg_t *msg; + xmlNodePtr child; INIT(this, .public = { @@ -99,7 +104,45 @@ tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node, .node = node, ); + if (xmlStrcmp(node->name, (const xmlChar*)"TNCCS-ReasonStrings")) + { + error_msg = "TNCCS-ReasonStrings tag expected"; + goto fatal; + } + + child = node->xmlChildrenNode; + while (child) + { + if (xmlIsBlankNode(child)) + { + child = child->next; + continue; + } + if (xmlStrcmp(child->name, (const xmlChar*)"ReasonString")) + { + error_msg = "ReasonString tag expected"; + goto fatal; + } + break; + } + + lang_string = (char*)xmlGetProp(child, (const xmlChar*)"lang"); + if (!lang_string) + { + lang_string = ""; + } + this->language = chunk_create(strdup(lang_string), strlen(lang_string)); + + reason_string = (char*)xmlNodeGetContent(child); + this->reason = chunk_create(strdup(reason_string), strlen(reason_string)); + return &this->public.tnccs_msg_interface; + +fatal: + msg = tnccs_error_msg_create(error_type, error_msg); + errors->insert_last(errors, msg); + destroy(this); + return NULL; } /** @@ -140,10 +183,12 @@ tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language) n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type)); /* could add multiple reasons here, if we had them */ + n3 = xmlNewNode(NULL, BAD_CAST "ReasonString"); xmlNewProp(n3, BAD_CAST "xml:lang", BAD_CAST this->language.ptr); xmlNodeSetContent(n3, BAD_CAST this->reason.ptr); xmlAddChild(n2, n3); + xmlAddChild(n, n2); return &this->public.tnccs_msg_interface; } diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c index adc7b54b9..610224242 100644 --- a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c @@ -128,7 +128,7 @@ tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node, fatal: msg = tnccs_error_msg_create(error_type, error_msg); errors->insert_last(errors, msg); - _destroy(this); + destroy(this); return NULL; } diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h index 685049e95..3a67a3b32 100644 --- a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h @@ -25,7 +25,7 @@ typedef struct tnccs_recommendation_msg_t tnccs_recommendation_msg_t; #include "tnccs_msg.h" -#include <tnc/tncifimv.h> +#include <tncifimv.h> /** * Class representing the TNCCS-Recommendation message type diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.c b/src/libcharon/plugins/tnccs_11/tnccs_11.c index 86f1c269f..3673221e5 100644 --- a/src/libcharon/plugins/tnccs_11/tnccs_11.c +++ b/src/libcharon/plugins/tnccs_11/tnccs_11.c @@ -22,12 +22,17 @@ #include "messages/tnccs_reason_strings_msg.h" #include "messages/tnccs_recommendation_msg.h" -#include <daemon.h> +#include <tncif_names.h> +#include <tncif_pa_subtypes.h> + +#include <tnc/tnc.h> +#include <tnc/imc/imc_manager.h> +#include <tnc/imv/imv_manager.h> +#include <tnc/tnccs/tnccs.h> +#include <tnc/tnccs/tnccs_manager.h> + #include <debug.h> #include <threading/mutex.h> -#include <tnc/tncif.h> -#include <tnc/tncifimv.h> -#include <tnc/tnccs/tnccs.h> typedef struct private_tnccs_11_t private_tnccs_11_t; @@ -90,15 +95,20 @@ struct private_tnccs_11_t { * Set of IMV recommendations (TNC Server only) */ recommendations_t *recs; + }; METHOD(tnccs_t, send_msg, TNC_Result, private_tnccs_11_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id, + TNC_UInt32 msg_flags, TNC_BufferReference msg, TNC_UInt32 msg_len, - TNC_MessageType msg_type) + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype) { tnccs_msg_t *tnccs_msg; + TNC_MessageType msg_type; + enum_name_t *pa_subtype_names; if (!this->send_msg) { @@ -107,6 +117,24 @@ METHOD(tnccs_t, send_msg, TNC_Result, this->is_server ? imv_id : imc_id); return TNC_RESULT_ILLEGAL_OPERATION; } + if (msg_vid > TNC_VENDORID_ANY || msg_subtype > TNC_SUBTYPE_ANY) + { + return TNC_RESULT_NO_LONG_MESSAGE_TYPES; + } + msg_type = (msg_vid << 8) | msg_subtype; + + pa_subtype_names = get_pa_subtype_names(msg_vid); + if (pa_subtype_names) + { + DBG2(DBG_TNC, "creating IMC-IMV message type '%N/%N' 0x%06x/0x%02x", + pen_names, msg_vid, pa_subtype_names, msg_subtype, + msg_vid, msg_subtype); + } + else + { + DBG2(DBG_TNC, "creating IMC-IMV message type '%N' 0x%06x/0x%02x", + pen_names, msg_vid, msg_vid, msg_subtype); + } tnccs_msg = imc_imv_msg_create(msg_type, chunk_create(msg, msg_len)); /* adding an IMC-IMV Message to TNCCS batch */ @@ -132,23 +160,40 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg) imc_imv_msg_t *imc_imv_msg; TNC_MessageType msg_type; chunk_t msg_body; + u_int32_t msg_vid, msg_subtype; + enum_name_t *pa_subtype_names; imc_imv_msg = (imc_imv_msg_t*)msg; msg_type = imc_imv_msg->get_msg_type(imc_imv_msg); msg_body = imc_imv_msg->get_msg_body(imc_imv_msg); + msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY; + msg_subtype = msg_type & TNC_SUBTYPE_ANY; - DBG2(DBG_TNC, "handling IMC_IMV message type 0x%08x", msg_type); + pa_subtype_names = get_pa_subtype_names(msg_vid); + if (pa_subtype_names) + { + DBG2(DBG_TNC, "handling IMC-IMV message type '%N/%N' 0x%06x/0x%02x", + pen_names, msg_vid, pa_subtype_names, msg_subtype, + msg_vid, msg_subtype); + } + else + { + DBG2(DBG_TNC, "handling IMC-IMV message type '%N' 0x%06x/0x%02x", + pen_names, msg_vid, msg_vid, msg_subtype); + } this->send_msg = TRUE; if (this->is_server) { - charon->imvs->receive_message(charon->imvs, - this->connection_id, msg_body.ptr, msg_body.len, msg_type); + tnc->imvs->receive_message(tnc->imvs, this->connection_id, + FALSE, msg_body.ptr, msg_body.len, + msg_vid, msg_subtype, 0, TNC_IMVID_ANY); } else { - charon->imcs->receive_message(charon->imcs, - this->connection_id, msg_body.ptr, msg_body.len,msg_type); + tnc->imcs->receive_message(tnc->imcs, this->connection_id, + FALSE, msg_body.ptr, msg_body.len, + msg_vid, msg_subtype, 0, TNC_IMCID_ANY); } this->send_msg = FALSE; break; @@ -181,8 +226,8 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg) default: state = TNC_CONNECTION_STATE_ACCESS_NONE; } - charon->imcs->notify_connection_change(charon->imcs, - this->connection_id, state); + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + state); this->delete_state = TRUE; break; } @@ -221,9 +266,9 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg) reason_msg = (tnccs_reason_strings_msg_t*)msg; reason_string = reason_msg->get_reason(reason_msg, &reason_lang); - DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len, + DBG2(DBG_TNC, "reason string is '%.*s'", reason_string.len, reason_string.ptr); - DBG2(DBG_TNC, "reason language is '%.*s", reason_lang.len, + DBG2(DBG_TNC, "reason language is '%.*s'", reason_lang.len, reason_lang.ptr); break; } @@ -243,17 +288,17 @@ METHOD(tls_t, process, status_t, if (this->is_server && !this->connection_id) { - this->connection_id = charon->tnccs->create_connection(charon->tnccs, - (tnccs_t*)this, _send_msg, + this->connection_id = tnc->tnccs->create_connection(tnc->tnccs, + TNCCS_1_1, (tnccs_t*)this, _send_msg, &this->request_handshake_retry, &this->recs); if (!this->connection_id) { return FAILED; } - charon->imvs->notify_connection_change(charon->imvs, - this->connection_id, TNC_CONNECTION_STATE_CREATE); - charon->imvs->notify_connection_change(charon->imvs, - this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + TNC_CONNECTION_STATE_CREATE); + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + TNC_CONNECTION_STATE_HANDSHAKE); } data = chunk_create(buf, buflen); @@ -304,11 +349,11 @@ METHOD(tls_t, process, status_t, this->send_msg = TRUE; if (this->is_server) { - charon->imvs->batch_ending(charon->imvs, this->connection_id); + tnc->imvs->batch_ending(tnc->imvs, this->connection_id); } else { - charon->imcs->batch_ending(charon->imcs, this->connection_id); + tnc->imcs->batch_ending(tnc->imcs, this->connection_id); } this->send_msg = FALSE; } @@ -331,7 +376,7 @@ static void check_and_build_recommendation(private_tnccs_11_t *this) if (!this->recs->have_recommendation(this->recs, &rec, &eval)) { - charon->imvs->solicit_recommendation(charon->imvs, this->connection_id); + tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id); } if (this->recs->have_recommendation(this->recs, &rec, &eval)) { @@ -351,6 +396,7 @@ static void check_and_build_recommendation(private_tnccs_11_t *this) this->batch->add_msg(this->batch, msg); } enumerator->destroy(enumerator); + this->recs->clear_reasons(this->recs); /* we have reache the final state */ this->delete_state = TRUE; @@ -368,8 +414,8 @@ METHOD(tls_t, build, status_t, tnccs_msg_t *msg; char *pref_lang; - this->connection_id = charon->tnccs->create_connection(charon->tnccs, - (tnccs_t*)this, _send_msg, + this->connection_id = tnc->tnccs->create_connection(tnc->tnccs, + TNCCS_1_1, (tnccs_t*)this, _send_msg, &this->request_handshake_retry, NULL); if (!this->connection_id) { @@ -377,19 +423,19 @@ METHOD(tls_t, build, status_t, } /* Create TNCCS-PreferredLanguage message */ - pref_lang = charon->imcs->get_preferred_language(charon->imcs); + pref_lang = tnc->imcs->get_preferred_language(tnc->imcs); msg = tnccs_preferred_language_msg_create(pref_lang); this->mutex->lock(this->mutex); this->batch = tnccs_batch_create(this->is_server, ++this->batch_id); this->batch->add_msg(this->batch, msg); this->mutex->unlock(this->mutex); - charon->imcs->notify_connection_change(charon->imcs, - this->connection_id, TNC_CONNECTION_STATE_CREATE); - charon->imcs->notify_connection_change(charon->imcs, - this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + TNC_CONNECTION_STATE_CREATE); + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + TNC_CONNECTION_STATE_HANDSHAKE); this->send_msg = TRUE; - charon->imcs->begin_handshake(charon->imcs, this->connection_id); + tnc->imcs->begin_handshake(tnc->imcs, this->connection_id); this->send_msg = FALSE; } @@ -456,7 +502,7 @@ METHOD(tls_t, is_complete, bool, if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval)) { - return charon->imvs->enforce_recommendation(charon->imvs, rec, eval); + return tnc->imvs->enforce_recommendation(tnc->imvs, rec, eval); } else { @@ -473,8 +519,8 @@ METHOD(tls_t, get_eap_msk, chunk_t, METHOD(tls_t, destroy, void, private_tnccs_11_t *this) { - charon->tnccs->remove_connection(charon->tnccs, this->connection_id, - this->is_server); + tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, + this->is_server); this->mutex->destroy(this->mutex); DESTROY_IF(this->batch); free(this); diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c index 9ec91f006..cd95afb1e 100644 --- a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c +++ b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c @@ -16,7 +16,7 @@ #include "tnccs_11_plugin.h" #include "tnccs_11.h" -#include <daemon.h> +#include <tnc/tnccs/tnccs_manager.h> METHOD(plugin_t, get_name, char*, tnccs_11_plugin_t *this) @@ -24,11 +24,23 @@ METHOD(plugin_t, get_name, char*, return "tnccs-11"; } +METHOD(plugin_t, get_features, int, + tnccs_11_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(tnccs_method_register, tnccs_11_create), + PLUGIN_PROVIDE(CUSTOM, "tnccs-1.1"), + PLUGIN_DEPENDS(EAP_SERVER, EAP_TNC), + PLUGIN_DEPENDS(EAP_PEER, EAP_TNC), + PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, tnccs_11_plugin_t *this) { - charon->tnccs->remove_method(charon->tnccs, - (tnccs_constructor_t)tnccs_11_create); free(this); } @@ -42,14 +54,11 @@ plugin_t *tnccs_11_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->tnccs->add_method(charon->tnccs, TNCCS_1_1, - (tnccs_constructor_t)tnccs_11_create); - return &this->plugin; } diff --git a/src/libcharon/plugins/tnccs_20/Makefile.am b/src/libcharon/plugins/tnccs_20/Makefile.am index d72fd3e34..ec17e6412 100644 --- a/src/libcharon/plugins/tnccs_20/Makefile.am +++ b/src/libcharon/plugins/tnccs_20/Makefile.am @@ -1,6 +1,9 @@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @@ -8,7 +11,9 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-tnccs-20.la else plugin_LTLIBRARIES = libstrongswan-tnccs-20.la -libstrongswan_tnccs_20_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +libstrongswan_tnccs_20_la_LIBADD = \ + $(top_builddir)/src/libtncif/libtncif.la \ + $(top_builddir)/src/libtnccs/libtnccs.la endif libstrongswan_tnccs_20_la_SOURCES = \ diff --git a/src/libcharon/plugins/tnccs_20/Makefile.in b/src/libcharon/plugins/tnccs_20/Makefile.in index bbfcc2760..b0078f338 100644 --- a/src/libcharon/plugins/tnccs_20/Makefile.in +++ b/src/libcharon/plugins/tnccs_20/Makefile.in @@ -75,7 +75,8 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) @MONOLITHIC_FALSE@libstrongswan_tnccs_20_la_DEPENDENCIES = \ -@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \ pb_tnc_batch.lo pb_tnc_msg.lo pb_experimental_msg.lo \ pb_pa_msg.lo pb_assessment_result_msg.lo \ @@ -200,6 +201,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -208,6 +212,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -224,11 +229,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -272,6 +279,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -282,13 +290,19 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-20.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-20.la -@MONOLITHIC_FALSE@libstrongswan_tnccs_20_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +@MONOLITHIC_FALSE@libstrongswan_tnccs_20_la_LIBADD = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la + libstrongswan_tnccs_20_la_SOURCES = \ tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \ batch/pb_tnc_batch.h batch/pb_tnc_batch.c \ diff --git a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c index 3f38543ed..c6a4bb599 100644 --- a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c +++ b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c @@ -18,12 +18,14 @@ #include "messages/pb_error_msg.h" #include "state_machine/pb_tnc_state_machine.h" -#include <debug.h> -#include <utils/linked_list.h> -#include <tls_writer.h> -#include <tls_reader.h> #include <tnc/tnccs/tnccs.h> +#include <utils/linked_list.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <pen/pen.h> +#include <debug.h> + ENUM(pb_tnc_batch_type_names, PB_BATCH_CDATA, PB_BATCH_CLOSE, "CDATA", "SDATA", @@ -142,7 +144,7 @@ METHOD(pb_tnc_batch_t, build, void, enumerator_t *enumerator; pb_tnc_msg_type_t msg_type; pb_tnc_msg_t *msg; - tls_writer_t *writer; + bio_writer_t *writer; /* compute total PB-TNC batch size by summing over all messages */ batch_len = PB_TNC_BATCH_HEADER_SIZE; @@ -156,7 +158,7 @@ METHOD(pb_tnc_batch_t, build, void, enumerator->destroy(enumerator); /* build PB-TNC batch header */ - writer = tls_writer_create(batch_len); + writer = bio_writer_create(batch_len); writer->write_uint8 (writer, PB_TNC_VERSION); writer->write_uint8 (writer, this->is_server ? PB_TNC_BATCH_FLAG_D : PB_TNC_BATCH_FLAG_NONE); @@ -178,7 +180,7 @@ METHOD(pb_tnc_batch_t, build, void, flags |= PB_TNC_FLAG_NOSKIP; } writer->write_uint8 (writer, flags); - writer->write_uint24(writer, IETF_VENDOR_ID); + writer->write_uint24(writer, PEN_IETF); writer->write_uint32(writer, msg_type); writer->write_uint32(writer, msg_len); writer->write_data (writer, msg_value); @@ -192,7 +194,7 @@ METHOD(pb_tnc_batch_t, build, void, static status_t process_batch_header(private_pb_tnc_batch_t *this, pb_tnc_state_machine_t *state_machine) { - tls_reader_t *reader; + bio_reader_t *reader; pb_tnc_msg_t *msg; pb_error_msg_t *err_msg; u_int8_t version, flags, reserved, type; @@ -203,12 +205,12 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, { DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC batch header", this->encoding.len); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, 0); goto fatal; } - reader = tls_reader_create(this->encoding); + reader = bio_reader_create(this->encoding); reader->read_uint8 (reader, &version); reader->read_uint8 (reader, &flags); reader->read_uint8 (reader, &reserved); @@ -220,7 +222,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, if (version != PB_TNC_VERSION) { DBG1(DBG_TNC, "unsupported TNCCS batch version 0x%01x", version); - msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create(TRUE, PEN_IETF, PB_ERROR_VERSION_NOT_SUPPORTED); err_msg = (pb_error_msg_t*)msg; err_msg->set_bad_version(err_msg, version); @@ -233,7 +235,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, { DBG1(DBG_TNC, "wrong Directionality: batch is from a PB %s", directionality ? "server" : "client"); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, 1); goto fatal; } @@ -243,7 +245,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, if (this->type > PB_BATCH_ROOF) { DBG1(DBG_TNC, "unknown PB-TNC batch type: %d", this->type); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, 3); goto fatal; } @@ -252,7 +254,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, { DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N", pb_tnc_batch_type_names, this->type); - msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create(TRUE, PEN_IETF, PB_ERROR_UNEXPECTED_BATCH_TYPE); goto fatal; } @@ -262,7 +264,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, { DBG1(DBG_TNC, "%u bytes of data is not equal to batch length of %u bytes", this->encoding.len, batch_len); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, 4); goto fatal; } @@ -277,7 +279,7 @@ fatal: static status_t process_tnc_msg(private_pb_tnc_batch_t *this) { - tls_reader_t *reader; + bio_reader_t *reader; pb_tnc_msg_t *pb_tnc_msg, *msg; u_int8_t flags; u_int32_t vendor_id, msg_type, msg_len, offset; @@ -291,12 +293,12 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) { DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message header", data.len); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, this->offset); goto fatal; } - reader = tls_reader_create(data); + reader = bio_reader_create(data); reader->read_uint8 (reader, &flags); reader->read_uint24(reader, &vendor_id); reader->read_uint32(reader, &msg_type); @@ -308,15 +310,15 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) if (msg_len > data.len) { DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message", data.len); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, this->offset + 8); goto fatal; } - if (vendor_id == RESERVED_VENDOR_ID) + if (vendor_id == PEN_RESERVED) { - DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", PEN_RESERVED); + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, this->offset + 1); goto fatal; @@ -326,19 +328,19 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) { DBG1(DBG_TNC, "PB-TNC message Type 0x%08x is reserved", PB_TNC_RESERVED_MSG_TYPE); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, this->offset + 4); goto fatal; } - if (vendor_id != IETF_VENDOR_ID || msg_type > PB_MSG_ROOF) + if (vendor_id != PEN_IETF || msg_type > PB_MSG_ROOF) { if (msg_len < PB_TNC_HEADER_SIZE) { DBG1(DBG_TNC, "%u bytes too small for PB-TNC message length", msg_len); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, this->offset + 8); goto fatal; } @@ -347,7 +349,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) { DBG1(DBG_TNC, "reject PB-TNC message (Vendor ID 0x%06x / " "Type 0x%08x)", vendor_id, msg_type); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset); goto fatal; } @@ -367,7 +369,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) DBG1(DBG_TNC, "%N message must%s have NOSKIP flag set", pb_tnc_msg_type_names, msg_type, pb_tnc_msg_infos[msg_type].has_noskip_flag ? "" : " not"); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, this->offset); goto fatal; } @@ -380,7 +382,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) pb_tnc_msg_type_names, msg_type, pb_tnc_msg_infos[msg_type].exact_size ? "exactly" : "at least", pb_tnc_msg_infos[msg_type].min_size, msg_len); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, this->offset); goto fatal; } @@ -393,7 +395,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) { DBG1(DBG_TNC,"reject %N message received from a PB-TNC client", pb_tnc_msg_type_names, msg_type); - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_INVALID_PARAMETER, this->offset); goto fatal; } @@ -415,8 +417,8 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) status = pb_tnc_msg->process(pb_tnc_msg, &offset); if (status == FAILED || status == VERIFY_ERROR) { - msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER, this->offset); + msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, + PB_ERROR_INVALID_PARAMETER, this->offset + offset); this->errors->insert_last(this->errors, msg); } if (status == FAILED) diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c index 41b9e31f6..fa3deddf6 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c @@ -15,8 +15,8 @@ #include "pb_access_recommendation_msg.h" -#include <tls_writer.h> -#include <tls_reader.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> #include <debug.h> ENUM(pb_access_recommendation_code_names, PB_REC_ACCESS_ALLOWED, PB_REC_QUARANTINED, @@ -80,10 +80,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t, METHOD(pb_tnc_msg_t, build, void, private_pb_access_recommendation_msg_t *this) { - tls_writer_t *writer; + bio_writer_t *writer; /* build message */ - writer = tls_writer_create(ACCESS_RECOMMENDATION_MSG_SIZE); + writer = bio_writer_create(ACCESS_RECOMMENDATION_MSG_SIZE); writer->write_uint16(writer, ACCESS_RECOMMENDATION_RESERVED); writer->write_uint16(writer, this->recommendation); free(this->encoding.ptr); @@ -95,11 +95,11 @@ METHOD(pb_tnc_msg_t, build, void, METHOD(pb_tnc_msg_t, process, status_t, private_pb_access_recommendation_msg_t *this, u_int32_t *offset) { - tls_reader_t *reader; + bio_reader_t *reader; u_int16_t reserved; /* process message */ - reader = tls_reader_create(this->encoding); + reader = bio_reader_create(this->encoding); reader->read_uint16(reader, &reserved); reader->read_uint16(reader, &this->recommendation); reader->destroy(reader); diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c index c91e54176..0d558c0d4 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c @@ -15,9 +15,10 @@ #include "pb_assessment_result_msg.h" -#include <tls_writer.h> -#include <tls_reader.h> -#include <tnc/tncifimv.h> +#include <tncifimv.h> + +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> #include <debug.h> typedef struct private_pb_assessment_result_msg_t private_pb_assessment_result_msg_t; @@ -75,10 +76,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t, METHOD(pb_tnc_msg_t, build, void, private_pb_assessment_result_msg_t *this) { - tls_writer_t *writer; + bio_writer_t *writer; /* build message */ - writer = tls_writer_create(ASSESSMENT_RESULT_MSG_SIZE); + writer = bio_writer_create(ASSESSMENT_RESULT_MSG_SIZE); writer->write_uint32(writer, this->assessment_result); free(this->encoding.ptr); this->encoding = writer->get_buf(writer); @@ -89,10 +90,10 @@ METHOD(pb_tnc_msg_t, build, void, METHOD(pb_tnc_msg_t, process, status_t, private_pb_assessment_result_msg_t *this, u_int32_t *offset) { - tls_reader_t *reader; + bio_reader_t *reader; /* process message */ - reader = tls_reader_create(this->encoding); + reader = bio_reader_create(this->encoding); reader->read_uint32(reader, &this->assessment_result); reader->destroy(reader); diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c index e1755c512..03e3cec92 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c @@ -15,11 +15,13 @@ #include "pb_error_msg.h" -#include <debug.h> -#include <tls_writer.h> -#include <tls_reader.h> #include <tnc/tnccs/tnccs.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <pen/pen.h> +#include <debug.h> + ENUM(pb_tnc_error_code_names, PB_ERROR_UNEXPECTED_BATCH_TYPE, PB_ERROR_VERSION_NOT_SUPPORTED, "Unexpected Batch Type", @@ -116,10 +118,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t, METHOD(pb_tnc_msg_t, build, void, private_pb_error_msg_t *this) { - tls_writer_t *writer; + bio_writer_t *writer; /* build message header */ - writer = tls_writer_create(ERROR_HEADER_SIZE); + writer = bio_writer_create(ERROR_HEADER_SIZE); writer->write_uint8 (writer, this->fatal ? ERROR_FLAG_FATAL : ERROR_FLAG_NONE); writer->write_uint24(writer, this->vendor_id); @@ -152,24 +154,25 @@ METHOD(pb_tnc_msg_t, process, status_t, { u_int8_t flags, max_version, min_version; u_int16_t reserved; - tls_reader_t *reader; + bio_reader_t *reader; if (this->encoding.len < ERROR_HEADER_SIZE) { DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes", pb_tnc_msg_type_names, PB_MSG_ERROR, ERROR_HEADER_SIZE); + *offset = 0; return FAILED; } /* process message header */ - reader = tls_reader_create(this->encoding); + reader = bio_reader_create(this->encoding); reader->read_uint8 (reader, &flags); reader->read_uint24(reader, &this->vendor_id); reader->read_uint16(reader, &this->error_code); reader->read_uint16(reader, &reserved); this->fatal = (flags & ERROR_FLAG_FATAL) != ERROR_FLAG_NONE; - if (this->vendor_id == IETF_VENDOR_ID && reader->remaining(reader) == 4) + if (this->vendor_id == PEN_IETF && reader->remaining(reader) == 4) { if (this->error_code == PB_ERROR_VERSION_NOT_SUPPORTED) { diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c index 9a94edf30..297cc8df7 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c @@ -15,8 +15,8 @@ #include "pb_language_preference_msg.h" -#include <tls_writer.h> -#include <tls_reader.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> #include <debug.h> typedef struct private_pb_language_preference_msg_t private_pb_language_preference_msg_t; diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c index 8315bfb76..1c4913e5e 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c @@ -17,22 +17,12 @@ #include "pb_pa_msg.h" -#include <tls_writer.h> -#include <tls_reader.h> #include <tnc/tnccs/tnccs.h> -#include <debug.h> -ENUM(pa_tnc_subtype_names, PA_SUBTYPE_TESTING, PA_SUBTYPE_NEA_CLIENT, - "Testing", - "Operating System", - "Anti-Virus", - "Anti-Spyware", - "Anti-Malware", - "Firewall", - "IDPS", - "VPN", - "NEA Client" -); +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <pen/pen.h> +#include <debug.h> typedef struct private_pb_pa_msg_t private_pb_pa_msg_t; @@ -124,10 +114,10 @@ METHOD(pb_tnc_msg_t, build, void, private_pb_pa_msg_t *this) { chunk_t msg_header; - tls_writer_t *writer; + bio_writer_t *writer; /* build message header */ - writer = tls_writer_create(64); + writer = bio_writer_create(64); writer->write_uint8 (writer, this->excl ? PA_FLAG_EXCL : PA_FLAG_NONE); writer->write_uint24(writer, this->vendor_id); writer->write_uint32(writer, this->subtype); @@ -146,10 +136,10 @@ METHOD(pb_tnc_msg_t, process, status_t, { u_int8_t flags; size_t msg_body_len; - tls_reader_t *reader; + bio_reader_t *reader; /* process message header */ - reader = tls_reader_create(this->encoding); + reader = bio_reader_create(this->encoding); reader->read_uint8 (reader, &flags); reader->read_uint24(reader, &this->vendor_id); reader->read_uint32(reader, &this->subtype); @@ -166,9 +156,9 @@ METHOD(pb_tnc_msg_t, process, status_t, } reader->destroy(reader); - if (this->vendor_id == RESERVED_VENDOR_ID) + if (this->vendor_id == PEN_RESERVED) { - DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID); + DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", PEN_RESERVED); *offset = 1; return FAILED; } @@ -221,12 +211,6 @@ METHOD(pb_pa_msg_t, get_exclusive_flag, bool, return this->excl; } -METHOD(pb_pa_msg_t, set_exclusive_flag, void, - private_pb_pa_msg_t *this, bool excl) -{ - this->excl = excl; -} - /** * See header */ @@ -247,7 +231,6 @@ pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data) .get_validator_id = _get_validator_id, .get_body = _get_body, .get_exclusive_flag = _get_exclusive_flag, - .set_exclusive_flag = _set_exclusive_flag, }, .type = PB_MSG_PA, .encoding = chunk_clone(data), @@ -261,7 +244,7 @@ pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data) */ pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype, u_int16_t collector_id, u_int16_t validator_id, - chunk_t msg_body) + bool excl, chunk_t msg_body) { private_pb_pa_msg_t *this; @@ -279,13 +262,13 @@ pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype, .get_validator_id = _get_validator_id, .get_body = _get_body, .get_exclusive_flag = _get_exclusive_flag, - .set_exclusive_flag = _set_exclusive_flag, }, .type = PB_MSG_PA, .vendor_id = vendor_id, .subtype = subtype, .collector_id = collector_id, .validator_id = validator_id, + .excl = excl, .msg_body = chunk_clone(msg_body), ); diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h index 366d790f6..d9db9a1ce 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h +++ b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h @@ -21,32 +21,11 @@ #ifndef PB_PA_MSG_H_ #define PB_PA_MSG_H_ -typedef enum pa_tnc_subtype_t pa_tnc_subtype_t; typedef struct pb_pa_msg_t pb_pa_msg_t; #include "pb_tnc_msg.h" /** - * PA-TNC Subtypes as defined in section 3.5 of RFC 5792 - */ - enum pa_tnc_subtype_t { - PA_SUBTYPE_TESTING = 0, - PA_SUBTYPE_OPERATING_SYSTEM = 1, - PA_SUBTYPE_ANTI_VIRUS = 2, - PA_SUBTYPE_ANTI_SPYWARE = 3, - PA_SUBTYPE_ANTI_MALWARE = 4, - PA_SUBTYPE_FIREWALL = 5, - PA_SUBTYPE_IDPS = 6, - PA_SUBTYPE_VPN = 7, - PA_SUBTYPE_NEA_CLIENT = 8 -}; - -/** - * enum name for pa_tnc_subtype_t. - */ -extern enum_name_t *pa_tnc_subtype_names; - -/** * Class representing the PB-PA message type. */ struct pb_pa_msg_t { @@ -92,12 +71,6 @@ struct pb_pa_msg_t { */ bool (*get_exclusive_flag)(pb_pa_msg_t *this); - /** - * Set the exclusive flag - * - * @param excl vexclusive flag - */ - void (*set_exclusive_flag)(pb_pa_msg_t *this, bool excl); }; /** @@ -107,11 +80,12 @@ struct pb_pa_msg_t { * @param subtype PA Subtype * @param collector_id Posture Collector ID * @param validator_id Posture Validator ID + * @param excl Exclusive Flag * @param msg_body PA Message Body */ pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype, u_int16_t collector_id, u_int16_t validator_id, - chunk_t msg_body); + bool excl, chunk_t msg_body); /** * Create an unprocessed PB-PA message from raw data diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c index e361cf2b2..181ecf61b 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c @@ -15,8 +15,8 @@ #include "pb_reason_string_msg.h" -#include <tls_writer.h> -#include <tls_reader.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> #include <debug.h> typedef struct private_pb_reason_string_msg_t private_pb_reason_string_msg_t; @@ -81,10 +81,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t, METHOD(pb_tnc_msg_t, build, void, private_pb_reason_string_msg_t *this) { - tls_writer_t *writer; + bio_writer_t *writer; /* build message */ - writer = tls_writer_create(64); + writer = bio_writer_create(64); writer->write_data32(writer, this->reason_string); writer->write_data8 (writer, this->language_code); @@ -97,10 +97,10 @@ METHOD(pb_tnc_msg_t, build, void, METHOD(pb_tnc_msg_t, process, status_t, private_pb_reason_string_msg_t *this, u_int32_t *offset) { - tls_reader_t *reader; + bio_reader_t *reader; /* process message */ - reader = tls_reader_create(this->encoding); + reader = bio_reader_create(this->encoding); if (!reader->read_data32(reader, &this->reason_string)) { DBG1(DBG_TNC, "could not parse reason string"); diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c index 79381a7b1..d213db313 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c @@ -15,8 +15,8 @@ #include "pb_remediation_parameters_msg.h" -#include <tls_writer.h> -#include <tls_reader.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> #include <debug.h> ENUM(pb_tnc_remed_param_type_names, PB_REMEDIATION_URI, PB_REMEDIATION_STRING, @@ -106,10 +106,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t, METHOD(pb_tnc_msg_t, build, void, private_pb_remediation_parameters_msg_t *this) { - tls_writer_t *writer; + bio_writer_t *writer; /* build message */ - writer = tls_writer_create(64); + writer = bio_writer_create(64); writer->write_uint32(writer, this->vendor_id); writer->write_uint32(writer, this->parameters_type); writer->write_data32(writer, this->remediation_string); @@ -124,10 +124,10 @@ METHOD(pb_tnc_msg_t, build, void, METHOD(pb_tnc_msg_t, process, status_t, private_pb_remediation_parameters_msg_t *this, u_int32_t *offset) { - tls_reader_t *reader; + bio_reader_t *reader; /* process message */ - reader = tls_reader_create(this->encoding); + reader = bio_reader_create(this->encoding); reader->read_uint32(reader, &this->vendor_id); reader->read_uint32(reader, &this->parameters_type); diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20.c b/src/libcharon/plugins/tnccs_20/tnccs_20.c index 9e2081d46..606fc529b 100644 --- a/src/libcharon/plugins/tnccs_20/tnccs_20.c +++ b/src/libcharon/plugins/tnccs_20/tnccs_20.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Sansar Choinyanbuu - * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010-2011 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -26,12 +26,17 @@ #include "messages/pb_language_preference_msg.h" #include "state_machine/pb_tnc_state_machine.h" +#include <tncif_names.h> +#include <tncif_pa_subtypes.h> + +#include <tnc/tnc.h> +#include <tnc/tnccs/tnccs_manager.h> +#include <tnc/imc/imc_manager.h> +#include <tnc/imv/imv_manager.h> + #include <debug.h> -#include <daemon.h> #include <threading/mutex.h> -#include <tnc/tncif.h> -#include <tnc/tncifimv.h> -#include <tnc/tnccs/tnccs.h> +#include <pen/pen.h> typedef struct private_tnccs_20_t private_tnccs_20_t; @@ -89,18 +94,21 @@ struct private_tnccs_20_t { * Set of IMV recommendations (TNC Server only) */ recommendations_t *recs; + }; METHOD(tnccs_t, send_msg, TNC_Result, private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id, + TNC_UInt32 msg_flags, TNC_BufferReference msg, TNC_UInt32 msg_len, - TNC_MessageType msg_type) + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype) { - TNC_MessageSubtype msg_sub_type; - TNC_VendorID msg_vendor_id; pb_tnc_msg_t *pb_tnc_msg; pb_tnc_batch_type_t batch_type; + enum_name_t *pa_subtype_names; + bool excl; if (!this->send_msg) { @@ -109,12 +117,23 @@ METHOD(tnccs_t, send_msg, TNC_Result, this->is_server ? imv_id : imc_id); return TNC_RESULT_ILLEGAL_OPERATION; } + excl = (msg_flags & TNC_MESSAGE_FLAGS_EXCLUSIVE) != 0; - msg_sub_type = msg_type & TNC_SUBTYPE_ANY; - msg_vendor_id = (msg_type >> 8) & TNC_VENDORID_ANY; + pb_tnc_msg = pb_pa_msg_create(msg_vid, msg_subtype, imc_id, imv_id, + excl, chunk_create(msg, msg_len)); - pb_tnc_msg = pb_pa_msg_create(msg_vendor_id, msg_sub_type, imc_id, imv_id, - chunk_create(msg, msg_len)); + pa_subtype_names = get_pa_subtype_names(msg_vid); + if (pa_subtype_names) + { + DBG2(DBG_TNC, "creating PB-PA message type '%N/%N' 0x%06x/0x%08x", + pen_names, msg_vid, pa_subtype_names, msg_subtype, + msg_vid, msg_subtype); + } + else + { + DBG2(DBG_TNC, "creating PB-PA message type '%N' 0x%06x/0x%08x", + pen_names, msg_vid, msg_vid, msg_subtype); + } /* adding PA message to SDATA or CDATA batch only */ batch_type = this->is_server ? PB_BATCH_SDATA : PB_BATCH_CDATA; @@ -148,27 +167,44 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg) case PB_MSG_PA: { pb_pa_msg_t *pa_msg; - TNC_MessageType msg_type; - u_int32_t vendor_id, subtype; + u_int32_t msg_vid, msg_subtype; + u_int16_t imc_id, imv_id; chunk_t msg_body; + bool excl; + enum_name_t *pa_subtype_names; pa_msg = (pb_pa_msg_t*)msg; - vendor_id = pa_msg->get_vendor_id(pa_msg, &subtype); - msg_type = (vendor_id << 8) | (subtype & 0xff); + msg_vid = pa_msg->get_vendor_id(pa_msg, &msg_subtype); msg_body = pa_msg->get_body(pa_msg); + imc_id = pa_msg->get_collector_id(pa_msg); + imv_id = pa_msg->get_validator_id(pa_msg); + excl = pa_msg->get_exclusive_flag(pa_msg); - DBG2(DBG_TNC, "handling PB-PA message type 0x%08x", msg_type); + pa_subtype_names = get_pa_subtype_names(msg_vid); + if (pa_subtype_names) + { + DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x", + pen_names, msg_vid, pa_subtype_names, msg_subtype, + msg_vid, msg_subtype); + } + else + { + DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x", + pen_names, msg_vid, msg_vid, msg_subtype); + } this->send_msg = TRUE; if (this->is_server) { - charon->imvs->receive_message(charon->imvs, - this->connection_id, msg_body.ptr, msg_body.len, msg_type); + tnc->imvs->receive_message(tnc->imvs, this->connection_id, + excl, msg_body.ptr, msg_body.len, + msg_vid, msg_subtype, imc_id, imv_id); } else { - charon->imcs->receive_message(charon->imcs, - this->connection_id, msg_body.ptr, msg_body.len,msg_type); + tnc->imcs->receive_message(tnc->imcs, this->connection_id, + excl, msg_body.ptr, msg_body.len, + msg_vid, msg_subtype, imv_id, imc_id); } this->send_msg = FALSE; break; @@ -205,8 +241,8 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg) case PB_REC_QUARANTINED: state = TNC_CONNECTION_STATE_ACCESS_ISOLATED; } - charon->imcs->notify_connection_change(charon->imcs, - this->connection_id, state); + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + state); break; } case PB_MSG_REMEDIATION_PARAMETERS: @@ -231,7 +267,7 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg) this->fatal_error = TRUE; } - if (vendor_id == IETF_VENDOR_ID) + if (vendor_id == PEN_IETF) { switch (error_code) { @@ -289,10 +325,10 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg) reason_msg = (pb_reason_string_msg_t*)msg; reason_string = reason_msg->get_reason_string(reason_msg); language_code = reason_msg->get_language_code(reason_msg); - DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len, - reason_string.ptr); - DBG2(DBG_TNC, "language code is '%.*s", language_code.len, - language_code.ptr); + DBG2(DBG_TNC, "reason string is '%.*s'", reason_string.len, + reason_string.ptr); + DBG2(DBG_TNC, "language code is '%.*s'", language_code.len, + language_code.ptr); break; } default: @@ -319,6 +355,11 @@ static void build_retry_batch(private_tnccs_20_t *this) pb_tnc_batch_type_names, this->batch->get_type(this->batch)); this->batch->destroy(this->batch); } + if (this->is_server) + { + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + TNC_CONNECTION_STATE_HANDSHAKE); + } this->batch = pb_tnc_batch_create(this->is_server, batch_retry_type); } @@ -333,17 +374,17 @@ METHOD(tls_t, process, status_t, if (this->is_server && !this->connection_id) { - this->connection_id = charon->tnccs->create_connection(charon->tnccs, - (tnccs_t*)this, _send_msg, + this->connection_id = tnc->tnccs->create_connection(tnc->tnccs, + TNCCS_2_0, (tnccs_t*)this, _send_msg, &this->request_handshake_retry, &this->recs); if (!this->connection_id) { return FAILED; } - charon->imvs->notify_connection_change(charon->imvs, - this->connection_id, TNC_CONNECTION_STATE_CREATE); - charon->imvs->notify_connection_change(charon->imvs, - this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + TNC_CONNECTION_STATE_CREATE); + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + TNC_CONNECTION_STATE_HANDSHAKE); } data = chunk_create(buf, buflen); @@ -372,10 +413,10 @@ METHOD(tls_t, process, status_t, else if (batch_type == PB_BATCH_SRETRY) { /* Restart the measurements */ - charon->imcs->notify_connection_change(charon->imcs, + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); this->send_msg = TRUE; - charon->imcs->begin_handshake(charon->imcs, this->connection_id); + tnc->imcs->begin_handshake(tnc->imcs, this->connection_id); this->send_msg = FALSE; } @@ -406,11 +447,11 @@ METHOD(tls_t, process, status_t, this->send_msg = TRUE; if (this->is_server) { - charon->imvs->batch_ending(charon->imvs, this->connection_id); + tnc->imvs->batch_ending(tnc->imvs, this->connection_id); } else { - charon->imcs->batch_ending(charon->imcs, this->connection_id); + tnc->imcs->batch_ending(tnc->imcs, this->connection_id); } this->send_msg = FALSE; } @@ -459,10 +500,11 @@ static void check_and_build_recommendation(private_tnccs_20_t *this) chunk_t reason, language; enumerator_t *enumerator; pb_tnc_msg_t *msg; + pb_access_recommendation_code_t pb_rec; if (!this->recs->have_recommendation(this->recs, &rec, &eval)) { - charon->imvs->solicit_recommendation(charon->imvs, this->connection_id); + tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id); } if (this->recs->have_recommendation(this->recs, &rec, &eval)) { @@ -472,10 +514,22 @@ static void check_and_build_recommendation(private_tnccs_20_t *this) this->batch->add_msg(this->batch, msg); /** - * IMV Action Recommendation and PB Access Recommendation codes - * are shifted by one. + * Map IMV Action Recommendation codes to PB Access Recommendation codes */ - msg = pb_access_recommendation_msg_create(rec + 1); + switch (rec) + { + case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: + pb_rec = PB_REC_ACCESS_ALLOWED; + break; + case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: + pb_rec = PB_REC_QUARANTINED; + break; + case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: + case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION: + default: + pb_rec = PB_REC_ACCESS_DENIED; + } + msg = pb_access_recommendation_msg_create(pb_rec); this->batch->add_msg(this->batch, msg); enumerator = this->recs->create_reason_enumerator(this->recs); @@ -485,6 +539,7 @@ static void check_and_build_recommendation(private_tnccs_20_t *this) this->batch->add_msg(this->batch, msg); } enumerator->destroy(enumerator); + this->recs->clear_reasons(this->recs); } } @@ -500,8 +555,8 @@ METHOD(tls_t, build, status_t, pb_tnc_msg_t *msg; char *pref_lang; - this->connection_id = charon->tnccs->create_connection(charon->tnccs, - (tnccs_t*)this, _send_msg, + this->connection_id = tnc->tnccs->create_connection(tnc->tnccs, + TNCCS_2_0, (tnccs_t*)this, _send_msg, &this->request_handshake_retry, NULL); if (!this->connection_id) { @@ -509,7 +564,7 @@ METHOD(tls_t, build, status_t, } /* Create PB-TNC Language Preference message */ - pref_lang = charon->imcs->get_preferred_language(charon->imcs); + pref_lang = tnc->imcs->get_preferred_language(tnc->imcs); msg = pb_language_preference_msg_create(chunk_create(pref_lang, strlen(pref_lang))); this->mutex->lock(this->mutex); @@ -517,12 +572,12 @@ METHOD(tls_t, build, status_t, this->batch->add_msg(this->batch, msg); this->mutex->unlock(this->mutex); - charon->imcs->notify_connection_change(charon->imcs, - this->connection_id, TNC_CONNECTION_STATE_CREATE); - charon->imcs->notify_connection_change(charon->imcs, - this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + TNC_CONNECTION_STATE_CREATE); + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + TNC_CONNECTION_STATE_HANDSHAKE); this->send_msg = TRUE; - charon->imcs->begin_handshake(charon->imcs, this->connection_id); + tnc->imcs->begin_handshake(tnc->imcs, this->connection_id); this->send_msg = FALSE; } @@ -639,7 +694,7 @@ METHOD(tls_t, is_complete, bool, if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval)) { - return charon->imvs->enforce_recommendation(charon->imvs, rec, eval); + return tnc->imvs->enforce_recommendation(tnc->imvs, rec, eval); } else { @@ -656,8 +711,8 @@ METHOD(tls_t, get_eap_msk, chunk_t, METHOD(tls_t, destroy, void, private_tnccs_20_t *this) { - charon->tnccs->remove_connection(charon->tnccs, this->connection_id, - this->is_server); + tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, + this->is_server); this->state_machine->destroy(this->state_machine); this->mutex->destroy(this->mutex); DESTROY_IF(this->batch); diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c index e6dc699e6..4f419ecf0 100644 --- a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c +++ b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c @@ -16,7 +16,7 @@ #include "tnccs_20_plugin.h" #include "tnccs_20.h" -#include <daemon.h> +#include <tnc/tnccs/tnccs_manager.h> METHOD(plugin_t, get_name, char*, tnccs_20_plugin_t *this) @@ -24,11 +24,23 @@ METHOD(plugin_t, get_name, char*, return "tnccs-20"; } +METHOD(plugin_t, get_features, int, + tnccs_20_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(tnccs_method_register, tnccs_20_create), + PLUGIN_PROVIDE(CUSTOM, "tnccs-2.0"), + PLUGIN_DEPENDS(EAP_SERVER, EAP_TNC), + PLUGIN_DEPENDS(EAP_PEER, EAP_TNC), + PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, tnccs_20_plugin_t *this) { - charon->tnccs->remove_method(charon->tnccs, - (tnccs_constructor_t)tnccs_20_create); free(this); } @@ -42,14 +54,11 @@ plugin_t *tnccs_20_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->tnccs->add_method(charon->tnccs, TNCCS_2_0, - (tnccs_constructor_t)tnccs_20_create); - return &this->plugin; } diff --git a/src/libcharon/plugins/tnccs_dynamic/Makefile.am b/src/libcharon/plugins/tnccs_dynamic/Makefile.am index 9a81d065f..57c2baaf0 100644 --- a/src/libcharon/plugins/tnccs_dynamic/Makefile.am +++ b/src/libcharon/plugins/tnccs_dynamic/Makefile.am @@ -1,6 +1,9 @@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @@ -8,7 +11,9 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-tnccs-dynamic.la else plugin_LTLIBRARIES = libstrongswan-tnccs-dynamic.la -libstrongswan_tnccs_dynamic_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +libstrongswan_tnccs_dynamic_la_LIBADD = \ + $(top_builddir)/src/libtncif/libtncif.la \ + $(top_builddir)/src/libtnccs/libtnccs.la endif libstrongswan_tnccs_dynamic_la_SOURCES = \ diff --git a/src/libcharon/plugins/tnccs_dynamic/Makefile.in b/src/libcharon/plugins/tnccs_dynamic/Makefile.in index dda1472db..ab24d32d3 100644 --- a/src/libcharon/plugins/tnccs_dynamic/Makefile.in +++ b/src/libcharon/plugins/tnccs_dynamic/Makefile.in @@ -75,7 +75,8 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) @MONOLITHIC_FALSE@libstrongswan_tnccs_dynamic_la_DEPENDENCIES = \ -@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la am_libstrongswan_tnccs_dynamic_la_OBJECTS = tnccs_dynamic_plugin.lo \ tnccs_dynamic.lo libstrongswan_tnccs_dynamic_la_OBJECTS = \ @@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -204,6 +208,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -220,11 +225,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -278,13 +286,19 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls +INCLUDES = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libtls \ + -I$(top_srcdir)/src/libtncif \ + -I$(top_srcdir)/src/libtnccs AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-dynamic.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-dynamic.la -@MONOLITHIC_FALSE@libstrongswan_tnccs_dynamic_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +@MONOLITHIC_FALSE@libstrongswan_tnccs_dynamic_la_LIBADD = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la + libstrongswan_tnccs_dynamic_la_SOURCES = \ tnccs_dynamic_plugin.h tnccs_dynamic_plugin.c tnccs_dynamic.h tnccs_dynamic.c diff --git a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c index b7985fa51..b68d2dd6b 100644 --- a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c +++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c @@ -15,8 +15,9 @@ #include "tnccs_dynamic.h" -#include <tnc/tnccs/tnccs.h> -#include <daemon.h> +#include <tnc/tnc.h> + +#include <debug.h> typedef struct private_tnccs_dynamic_t private_tnccs_dynamic_t; @@ -75,8 +76,7 @@ METHOD(tls_t, process, status_t, type = determine_tnccs_protocol(*(char*)buf); DBG1(DBG_TNC, "%N protocol detected dynamically", tnccs_type_names, type); - this->tls = (tls_t*)charon->tnccs->create_instance(charon->tnccs, - type, TRUE); + this->tls = (tls_t*)tnc->tnccs->create_instance(tnc->tnccs, type, TRUE); if (!this->tls) { DBG1(DBG_TNC, "N% protocol not supported", tnccs_type_names, type); diff --git a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c index 089a3ed57..6f581c543 100644 --- a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c +++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c @@ -16,7 +16,7 @@ #include "tnccs_dynamic_plugin.h" #include "tnccs_dynamic.h" -#include <daemon.h> +#include <tnc/tnccs/tnccs_manager.h> METHOD(plugin_t, get_name, char*, tnccs_dynamic_plugin_t *this) @@ -24,11 +24,24 @@ METHOD(plugin_t, get_name, char*, return "tnccs-dynamic"; } +METHOD(plugin_t, get_features, int, + tnccs_dynamic_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(tnccs_method_register, tnccs_dynamic_create), + PLUGIN_PROVIDE(CUSTOM, "tnccs-dynamic"), + PLUGIN_DEPENDS(CUSTOM, "tnccs-1.1"), + PLUGIN_DEPENDS(CUSTOM, "tnccs-2.0"), + PLUGIN_DEPENDS(EAP_SERVER, EAP_TNC), + PLUGIN_DEPENDS(EAP_PEER, EAP_TNC), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, tnccs_dynamic_plugin_t *this) { - charon->tnccs->remove_method(charon->tnccs, - (tnccs_constructor_t)tnccs_dynamic_create); free(this); } @@ -42,14 +55,11 @@ plugin_t *tnccs_dynamic_plugin_create() INIT(this, .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, ); - charon->tnccs->add_method(charon->tnccs, TNCCS_DYNAMIC, - (tnccs_constructor_t)tnccs_dynamic_create); - return &this->plugin; } diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in index 013ceb7da..dd001e0bd 100644 --- a/src/libcharon/plugins/uci/Makefile.in +++ b/src/libcharon/plugins/uci/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/uci/uci_config.c b/src/libcharon/plugins/uci/uci_config.c index 4e43388ec..2f5e59b89 100644 --- a/src/libcharon/plugins/uci/uci_config.c +++ b/src/libcharon/plugins/uci/uci_config.c @@ -133,10 +133,8 @@ static u_int create_rekey(char *string) return 12 * 3600; } -/** - * Implementation of peer_enumerator_t.public.enumerate - */ -static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) +METHOD(enumerator_t, peer_enumerator_enumerate, bool, + peer_enumerator_t *this, peer_cfg_t **cfg) { char *name, *ike_proposal, *esp_proposal, *ike_rekey, *esp_rekey; char *local_id, *local_addr, *local_net; @@ -177,9 +175,9 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) name, 2, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_NO, 1, create_rekey(ike_rekey), 0, /* keytries, rekey, reauth */ 1800, 900, /* jitter, overtime */ - TRUE, 60, /* mobike, dpddelay */ - NULL, NULL, /* vip, pool */ - FALSE, NULL, NULL); /* mediation, med by, peer id */ + TRUE, 60, /* mobike, dpddelay */ + NULL, NULL, /* vip, pool */ + FALSE, NULL, NULL); /* mediation, med by, peer id */ auth = auth_cfg_create(); auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK); auth->add(auth, AUTH_RULE_IDENTITY, @@ -208,32 +206,30 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) return FALSE; } -/** - * Implementation of peer_enumerator_t.public.destroy - */ -static void peer_enumerator_destroy(peer_enumerator_t *this) + +METHOD(enumerator_t, peer_enumerator_destroy, void, + peer_enumerator_t *this) { DESTROY_IF(this->peer_cfg); this->inner->destroy(this->inner); free(this); } -/** - * Implementation of backend_t.create_peer_cfg_enumerator. - */ -static enumerator_t* create_peer_cfg_enumerator(private_uci_config_t *this, - identification_t *me, - identification_t *other) +METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, + private_uci_config_t *this, identification_t *me, identification_t *other) { - peer_enumerator_t *e = malloc_thing(peer_enumerator_t); - - e->public.enumerate = (void*)peer_enumerator_enumerate; - e->public.destroy = (void*)peer_enumerator_destroy; - e->peer_cfg = NULL; - e->inner = this->parser->create_section_enumerator(this->parser, + peer_enumerator_t *e; + + INIT(e, + .public = { + .enumerate = (void*)_peer_enumerator_enumerate, + .destroy = _peer_enumerator_destroy, + }, + .inner = this->parser->create_section_enumerator(this->parser, "local_id", "remote_id", "local_addr", "remote_addr", "local_net", "remote_net", "ike_proposal", "esp_proposal", - "ike_rekey", "esp_rekey", NULL); + "ike_rekey", "esp_rekey", NULL), + ); if (!e->inner) { free(e); @@ -254,10 +250,8 @@ typedef struct { enumerator_t *inner; } ike_enumerator_t; -/** - * Implementation of peer_enumerator_t.public.enumerate - */ -static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg) +METHOD(enumerator_t, ike_enumerator_enumerate, bool, + ike_enumerator_t *this, ike_cfg_t **cfg) { char *local_addr, *remote_addr, *ike_proposal; @@ -281,29 +275,27 @@ static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg) return FALSE; } -/** - * Implementation of ike_enumerator_t.public.destroy - */ -static void ike_enumerator_destroy(ike_enumerator_t *this) +METHOD(enumerator_t, ike_enumerator_destroy, void, + ike_enumerator_t *this) { DESTROY_IF(this->ike_cfg); this->inner->destroy(this->inner); free(this); } -/** - * Implementation of backend_t.create_ike_cfg_enumerator. - */ -static enumerator_t* create_ike_cfg_enumerator(private_uci_config_t *this, - host_t *me, host_t *other) +METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, + private_uci_config_t *this, host_t *me, host_t *other) { - ike_enumerator_t *e = malloc_thing(ike_enumerator_t); - - e->public.enumerate = (void*)ike_enumerator_enumerate; - e->public.destroy = (void*)ike_enumerator_destroy; - e->ike_cfg = NULL; - e->inner = this->parser->create_section_enumerator(this->parser, - "local_addr", "remote_addr", "ike_proposal", NULL); + ike_enumerator_t *e; + + INIT(e, + .public = { + .enumerate = (void*)_ike_enumerator_enumerate, + .destroy = _ike_enumerator_destroy, + }, + .inner = this->parser->create_section_enumerator(this->parser, + "local_addr", "remote_addr", "ike_proposal", NULL), + ); if (!e->inner) { free(e); @@ -312,10 +304,8 @@ static enumerator_t* create_ike_cfg_enumerator(private_uci_config_t *this, return &e->public; } -/** - * implements backend_t.get_peer_cfg_by_name. - */ -static peer_cfg_t *get_peer_cfg_by_name(private_uci_config_t *this, char *name) +METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*, + private_uci_config_t *this, char *name) { enumerator_t *enumerator; peer_cfg_t *current, *found = NULL; @@ -336,10 +326,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_uci_config_t *this, char *name) return found; } -/** - * Implementation of uci_config_t.destroy. - */ -static void destroy(private_uci_config_t *this) +METHOD(uci_config_t, destroy, void, + private_uci_config_t *this) { free(this); } @@ -349,13 +337,19 @@ static void destroy(private_uci_config_t *this) */ uci_config_t *uci_config_create(uci_parser_t *parser) { - private_uci_config_t *this = malloc_thing(private_uci_config_t); - - this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator; - this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator; - this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name; - this->public.destroy = (void(*)(uci_config_t*))destroy; - this->parser = parser; + private_uci_config_t *this; + + INIT(this, + .public = { + .backend = { + .create_peer_cfg_enumerator = _create_peer_cfg_enumerator, + .create_ike_cfg_enumerator = _create_ike_cfg_enumerator, + .get_peer_cfg_by_name = _get_peer_cfg_by_name, + }, + .destroy = _destroy, + }, + .parser = parser, + ); return &this->public; } diff --git a/src/libcharon/plugins/uci/uci_control.c b/src/libcharon/plugins/uci/uci_control.c index aee2505e3..af4a6a711 100644 --- a/src/libcharon/plugins/uci/uci_control.c +++ b/src/libcharon/plugins/uci/uci_control.c @@ -76,8 +76,7 @@ static void write_fifo(private_uci_control_t *this, char *format, ...) */ static void status(private_uci_control_t *this, char *name) { - enumerator_t *configs, *sas; - iterator_t *children; + enumerator_t *configs, *sas, *children; ike_sa_t *ike_sa; child_sa_t *child_sa; peer_cfg_t *peer_cfg; @@ -92,7 +91,8 @@ static void status(private_uci_control_t *this, char *name) { continue; } - sas = charon->controller->create_ike_sa_enumerator(charon->controller); + sas = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (sas->enumerate(sas, &ike_sa)) { if (!streq(ike_sa->get_name(ike_sa), peer_cfg->get_name(peer_cfg))) @@ -110,8 +110,8 @@ static void status(private_uci_control_t *this, char *name) fprintf(out, "%-8s %-20D %-16H ", ike_sa->get_name(ike_sa), ike_sa->get_other_id(ike_sa), ike_sa->get_other_host(ike_sa)); - children = ike_sa->create_child_sa_iterator(ike_sa); - while (children->iterate(children, (void**)&child_sa)) + children = ike_sa->create_child_sa_enumerator(ike_sa); + while (children->enumerate(children, (void**)&child_sa)) { fprintf(out, "%#R", child_sa->get_traffic_selectors(child_sa, FALSE)); @@ -148,8 +148,8 @@ static void initiate(private_uci_control_t *this, char *name) enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg); if (enumerator->enumerate(enumerator, &child_cfg) && charon->controller->initiate(charon->controller, peer_cfg, - child_cfg->get_ref(child_cfg), - controller_cb_empty, NULL) == SUCCESS) + child_cfg->get_ref(child_cfg), + controller_cb_empty, NULL, 0) == SUCCESS) { write_fifo(this, "connection '%s' established\n", name); } @@ -174,7 +174,8 @@ static void terminate(private_uci_control_t *this, char *name) ike_sa_t *ike_sa; u_int id; - enumerator = charon->controller->create_ike_sa_enumerator(charon->controller); + enumerator = charon->controller->create_ike_sa_enumerator( + charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { if (streq(name, ike_sa->get_name(ike_sa))) @@ -182,7 +183,7 @@ static void terminate(private_uci_control_t *this, char *name) id = ike_sa->get_unique_id(ike_sa); enumerator->destroy(enumerator); charon->controller->terminate_ike(charon->controller, id, - controller_cb_empty, NULL); + controller_cb_empty, NULL, 0); write_fifo(this, "connection '%s' terminated\n", name); return; } @@ -265,10 +266,8 @@ static job_requeue_t receive(private_uci_control_t *this) return JOB_REQUEUE_FAIR; } -/** - * Implementation of uci_control_t.destroy - */ -static void destroy(private_uci_control_t *this) +METHOD(uci_control_t, destroy, void, + private_uci_control_t *this) { this->job->cancel(this->job); unlink(FIFO_FILE); @@ -280,9 +279,13 @@ static void destroy(private_uci_control_t *this) */ uci_control_t *uci_control_create() { - private_uci_control_t *this = malloc_thing(private_uci_control_t); + private_uci_control_t *this; - this->public.destroy = (void(*)(uci_control_t*))destroy; + INIT(this, + .public = { + .destroy = _destroy, + }, + ); unlink(FIFO_FILE); if (mkfifo(FIFO_FILE, S_IRUSR|S_IWUSR) != 0) @@ -292,8 +295,8 @@ uci_control_t *uci_control_create() } else { - this->job = callback_job_create((callback_job_cb_t)receive, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)receive, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); } return &this->public; diff --git a/src/libcharon/plugins/uci/uci_creds.c b/src/libcharon/plugins/uci/uci_creds.c index 4d664feb2..f5d5ace70 100644 --- a/src/libcharon/plugins/uci/uci_creds.c +++ b/src/libcharon/plugins/uci/uci_creds.c @@ -51,11 +51,9 @@ typedef struct { identification_t *other; } shared_enumerator_t; -/** - * Implementation of shared_enumerator_t.public.enumerate - */ -static bool shared_enumerator_enumerate(shared_enumerator_t *this, - shared_key_t **key, id_match_t *me, id_match_t *other) +METHOD(enumerator_t, shared_enumerator_enumerate, bool, + shared_enumerator_t *this, shared_key_t **key, id_match_t *me, + id_match_t *other) { char *local_id, *remote_id, *psk; identification_t *local, *remote; @@ -107,23 +105,17 @@ static bool shared_enumerator_enumerate(shared_enumerator_t *this, return TRUE; } -/** - * Implementation of shared_enumerator_t.public.destroy - */ -static void shared_enumerator_destroy(shared_enumerator_t *this) +METHOD(enumerator_t, shared_enumerator_destroy, void, + shared_enumerator_t *this) { this->inner->destroy(this->inner); DESTROY_IF(this->current); free(this); } -/** - * Implementation of backend_t.create_shared_cfg_enumerator. - */ -static enumerator_t* create_shared_enumerator(private_uci_creds_t *this, - shared_key_type_t type, - identification_t *me, - identification_t *other) +METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, + private_uci_creds_t *this, shared_key_type_t type, + identification_t *me, identification_t *other) { shared_enumerator_t *e; @@ -132,14 +124,16 @@ static enumerator_t* create_shared_enumerator(private_uci_creds_t *this, return NULL; } - e = malloc_thing(shared_enumerator_t); - e->current = NULL; - e->public.enumerate = (void*)shared_enumerator_enumerate; - e->public.destroy = (void*)shared_enumerator_destroy; - e->me = me; - e->other = other; - e->inner = this->parser->create_section_enumerator(this->parser, - "local_id", "remote_id", "psk", NULL); + INIT(e, + .public = { + .enumerate = (void*)_shared_enumerator_enumerate, + .destroy = _shared_enumerator_destroy, + }, + .me = me, + .other = other, + .inner = this->parser->create_section_enumerator(this->parser, + "local_id", "remote_id", "psk", NULL), + ); if (!e->inner) { free(e); @@ -148,24 +142,28 @@ static enumerator_t* create_shared_enumerator(private_uci_creds_t *this, return &e->public; } -/** - * Implementation of uci_creds_t.destroy - */ -static void destroy(private_uci_creds_t *this) +METHOD(uci_creds_t, destroy, void, + private_uci_creds_t *this) { free(this); } uci_creds_t *uci_creds_create(uci_parser_t *parser) { - private_uci_creds_t *this = malloc_thing(private_uci_creds_t); - - this->public.credential_set.create_shared_enumerator = (enumerator_t*(*)(credential_set_t*, shared_key_type_t, identification_t*, identification_t*))create_shared_enumerator; - this->public.credential_set.create_private_enumerator = (enumerator_t*(*) (credential_set_t*, key_type_t, identification_t*))return_null; - this->public.credential_set.create_cert_enumerator = (enumerator_t*(*) (credential_set_t*, certificate_type_t, key_type_t,identification_t *, bool))return_null; - this->public.credential_set.create_cdp_enumerator = (enumerator_t*(*) (credential_set_t *,certificate_type_t, identification_t *))return_null; - this->public.credential_set.cache_cert = (void (*)(credential_set_t *, certificate_t *))nop; - this->public.destroy = (void(*) (uci_creds_t*))destroy; + private_uci_creds_t *this; + + INIT(this, + .public = { + .credential_set = { + .create_shared_enumerator = _create_shared_enumerator, + .create_private_enumerator = (void*)return_null, + .create_cert_enumerator = (void*)return_null, + .create_cdp_enumerator = (void*)return_null, + .cache_cert = (void*)nop, + }, + .destroy = _destroy, + }, + ); this->parser = parser; diff --git a/src/libcharon/plugins/uci/uci_parser.c b/src/libcharon/plugins/uci/uci_parser.c index 6de55d218..2429e9e44 100644 --- a/src/libcharon/plugins/uci/uci_parser.c +++ b/src/libcharon/plugins/uci/uci_parser.c @@ -57,10 +57,8 @@ typedef struct { char *keywords[]; } section_enumerator_t; -/** - * Implementation of section_enumerator_t.enumerate - */ -static bool section_enumerator_enumerate(section_enumerator_t *this, ...) +METHOD(enumerator_t, section_enumerator_enumerate, bool, + section_enumerator_t *this, ...) { struct uci_element *element; char **value; @@ -104,19 +102,15 @@ static bool section_enumerator_enumerate(section_enumerator_t *this, ...) return TRUE; } -/** - * Implementation of section_enumerator_t.public.destroy - */ -static void section_enumerator_destroy(section_enumerator_t *this) +METHOD(enumerator_t, section_enumerator_destroy, void, + section_enumerator_t *this) { uci_free_context(this->ctx); free(this); } -/** - * Implementation of backend_t.create_section_enumerator. - */ -static enumerator_t* create_section_enumerator(private_uci_parser_t *this, ...) +METHOD(uci_parser_t, create_section_enumerator, enumerator_t*, + private_uci_parser_t *this, ...) { section_enumerator_t *e; va_list args; @@ -140,8 +134,8 @@ static enumerator_t* create_section_enumerator(private_uci_parser_t *this, ...) while (e->keywords[i++]); va_end(args); - e->public.enumerate = (void*)section_enumerator_enumerate; - e->public.destroy = (void*)section_enumerator_destroy; + e->public.enumerate = (void*)_section_enumerator_enumerate; + e->public.destroy = _section_enumerator_destroy; /* load uci context */ e->ctx = uci_alloc_context(); @@ -160,10 +154,8 @@ static enumerator_t* create_section_enumerator(private_uci_parser_t *this, ...) return &e->public; } -/** - * Implementation of uci_parser_t.destroy. - */ -static void destroy(private_uci_parser_t *this) +METHOD(uci_parser_t, destroy, void, + private_uci_parser_t *this) { free(this->package); free(this); @@ -174,12 +166,15 @@ static void destroy(private_uci_parser_t *this) */ uci_parser_t *uci_parser_create(char *package) { - private_uci_parser_t *this = malloc_thing(private_uci_parser_t); - - this->public.create_section_enumerator = (enumerator_t*(*)(uci_parser_t*, ...))create_section_enumerator; - this->public.destroy = (void(*)(uci_parser_t*))destroy; - - this->package = strdup(package); + private_uci_parser_t *this; + + INIT(this, + .public = { + .create_section_enumerator = _create_section_enumerator, + .destroy = _destroy, + }, + .package = strdup(package), + ); return &this->public; } diff --git a/src/libcharon/plugins/uci/uci_plugin.c b/src/libcharon/plugins/uci/uci_plugin.c index a6d24c32b..497c473a4 100644 --- a/src/libcharon/plugins/uci/uci_plugin.c +++ b/src/libcharon/plugins/uci/uci_plugin.c @@ -92,10 +92,10 @@ plugin_t *uci_plugin_create() }, }, .parser = uci_parser_create(UCI_PACKAGE), - .config = uci_config_create(this->parser), - .creds = uci_creds_create(this->parser), .control = uci_control_create(), ); + this->config = uci_config_create(this->parser); + this->creds = uci_creds_create(this->parser); charon->backends->add_backend(charon->backends, &this->config->backend); lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set); diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/unit_tester/Makefile.in index 2fee3da82..106c9b1fe 100644 --- a/src/libcharon/plugins/unit_tester/Makefile.in +++ b/src/libcharon/plugins/unit_tester/Makefile.in @@ -198,6 +198,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -206,6 +209,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -222,11 +226,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -270,6 +276,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in index 49cffe218..fb7b38f65 100644 --- a/src/libcharon/plugins/updown/Makefile.in +++ b/src/libcharon/plugins/updown/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c index 8e58b1a9b..2bd757ec7 100644 --- a/src/libcharon/plugins/updown/updown_listener.c +++ b/src/libcharon/plugins/updown/updown_listener.c @@ -115,37 +115,15 @@ METHOD(listener_t, child_updown, bool, while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { char command[1024]; - char *my_client, *other_client, *my_client_mask, *other_client_mask; - char *pos, *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc; + host_t *my_client, *other_client; + u_int8_t my_client_mask, other_client_mask; + char *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc; mark_t mark; bool is_host, is_ipv6; FILE *shell; - /* get subnet/bits from string */ - if (asprintf(&my_client, "%R", my_ts) < 0) - { - my_client = NULL; - } - pos = strchr(my_client, '/'); - *pos = '\0'; - my_client_mask = pos + 1; - pos = strchr(my_client_mask, '['); - if (pos) - { - *pos = '\0'; - } - if (asprintf(&other_client, "%R", other_ts) < 0) - { - other_client = NULL; - } - pos = strchr(other_client, '/'); - *pos = '\0'; - other_client_mask = pos + 1; - pos = strchr(other_client_mask, '['); - if (pos) - { - *pos = '\0'; - } + my_ts->to_subnet(my_ts, &my_client, &my_client_mask); + other_ts->to_subnet(other_ts, &other_client, &other_client_mask); if (vip) { @@ -248,16 +226,12 @@ METHOD(listener_t, child_updown, bool, "PLUTO_REQID='%u' " "PLUTO_ME='%H' " "PLUTO_MY_ID='%Y' " - "PLUTO_MY_CLIENT='%s/%s' " - "PLUTO_MY_CLIENT_NET='%s' " - "PLUTO_MY_CLIENT_MASK='%s' " + "PLUTO_MY_CLIENT='%H/%u' " "PLUTO_MY_PORT='%u' " "PLUTO_MY_PROTOCOL='%u' " "PLUTO_PEER='%H' " "PLUTO_PEER_ID='%Y' " - "PLUTO_PEER_CLIENT='%s/%s' " - "PLUTO_PEER_CLIENT_NET='%s' " - "PLUTO_PEER_CLIENT_MASK='%s' " + "PLUTO_PEER_CLIENT='%H/%u' " "PLUTO_PEER_PORT='%u' " "PLUTO_PEER_PROTOCOL='%u' " "%s" @@ -274,12 +248,10 @@ METHOD(listener_t, child_updown, bool, child_sa->get_reqid(child_sa), me, ike_sa->get_my_id(ike_sa), my_client, my_client_mask, - my_client, my_client_mask, my_ts->get_from_port(my_ts), my_ts->get_protocol(my_ts), other, ike_sa->get_other_id(ike_sa), other_client, other_client_mask, - other_client, other_client_mask, other_ts->get_from_port(other_ts), other_ts->get_protocol(other_ts), virtual_ip, @@ -288,8 +260,8 @@ METHOD(listener_t, child_updown, bool, udp_enc, config->get_hostaccess(config) ? "PLUTO_HOST_ACCESS='1' " : "", script); - free(my_client); - free(other_client); + my_client->destroy(my_client); + other_client->destroy(other_client); free(virtual_ip); free(mark_in); free(mark_out); diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in index 37ae5f9c3..2534f4bec 100644 --- a/src/libcharon/plugins/whitelist/Makefile.in +++ b/src/libcharon/plugins/whitelist/Makefile.in @@ -202,6 +202,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -210,6 +213,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -226,11 +230,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -274,6 +280,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libcharon/plugins/whitelist/whitelist_control.c b/src/libcharon/plugins/whitelist/whitelist_control.c index 4a1fc5d87..202c9a418 100644 --- a/src/libcharon/plugins/whitelist/whitelist_control.c +++ b/src/libcharon/plugins/whitelist/whitelist_control.c @@ -225,8 +225,8 @@ whitelist_control_t *whitelist_control_create(whitelist_listener_t *listener) return NULL; } - this->job = callback_job_create((callback_job_cb_t)receive, - this, NULL, NULL); + this->job = callback_job_create_with_prio((callback_job_cb_t)receive, + this, NULL, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; diff --git a/src/libcharon/processing/jobs/acquire_job.c b/src/libcharon/processing/jobs/acquire_job.c index 3544dd332..2d836b002 100644 --- a/src/libcharon/processing/jobs/acquire_job.c +++ b/src/libcharon/processing/jobs/acquire_job.c @@ -61,6 +61,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_acquire_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -74,6 +80,7 @@ acquire_job_t *acquire_job_create(u_int32_t reqid, .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c index 29122cd03..bd8bb9562 100644 --- a/src/libcharon/processing/jobs/delete_child_sa_job.c +++ b/src/libcharon/processing/jobs/delete_child_sa_job.c @@ -73,6 +73,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_delete_child_sa_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -86,6 +92,7 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid, .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/delete_ike_sa_job.c b/src/libcharon/processing/jobs/delete_ike_sa_job.c index 468c9ef94..c29b72230 100644 --- a/src/libcharon/processing/jobs/delete_ike_sa_job.c +++ b/src/libcharon/processing/jobs/delete_ike_sa_job.c @@ -92,6 +92,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_delete_ike_sa_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -104,6 +110,7 @@ delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id, .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c index 1371000eb..251b9ab03 100644 --- a/src/libcharon/processing/jobs/inactivity_job.c +++ b/src/libcharon/processing/jobs/inactivity_job.c @@ -61,15 +61,15 @@ METHOD(job_t, execute, void, this->reqid, TRUE); if (ike_sa) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; u_int32_t delete = 0; protocol_id_t proto = 0; int children = 0; status_t status = SUCCESS; - iterator = ike_sa->create_child_sa_iterator(ike_sa); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = ike_sa->create_child_sa_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (child_sa->get_reqid(child_sa) == this->reqid) { @@ -94,7 +94,7 @@ METHOD(job_t, execute, void, } children++; } - iterator->destroy(iterator); + enumerator->destroy(enumerator); if (delete) { @@ -127,6 +127,12 @@ METHOD(job_t, execute, void, } } +METHOD(job_t, get_priority, job_priority_t, + private_inactivity_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /** * See header */ @@ -137,8 +143,9 @@ inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout, INIT(this, .public = { - .job_interface = { + .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/initiate_mediation_job.c b/src/libcharon/processing/jobs/initiate_mediation_job.c index ffe8755e2..e52f3c6df 100644 --- a/src/libcharon/processing/jobs/initiate_mediation_job.c +++ b/src/libcharon/processing/jobs/initiate_mediation_job.c @@ -41,10 +41,8 @@ struct private_initiate_mediation_job_t { ike_sa_id_t *mediation_sa_id; }; -/** - * Implements job_t.destroy. - */ -static void destroy(private_initiate_mediation_job_t *this) +METHOD(job_t, destroy, void, + private_initiate_mediation_job_t *this) { DESTROY_IF(this->mediation_sa_id); DESTROY_IF(this->mediated_sa_id); @@ -66,10 +64,8 @@ static bool initiate_callback(private_initiate_mediation_job_t *this, return TRUE; } -/** - * Implementation of job_t.execute. - */ -static void initiate(private_initiate_mediation_job_t *this) +METHOD(job_t, initiate, void, + private_initiate_mediation_job_t *this) { ike_sa_t *mediated_sa, *mediation_sa; peer_cfg_t *mediated_cfg, *mediation_cfg; @@ -126,7 +122,7 @@ static void initiate(private_initiate_mediation_job_t *this) mediation_cfg->get_ref(mediation_cfg); if (charon->controller->initiate(charon->controller, mediation_cfg, - NULL, (controller_cb_t)initiate_callback, this) != SUCCESS) + NULL, (controller_cb_t)initiate_callback, this, 0) != SUCCESS) { mediation_cfg->destroy(mediation_cfg); mediated_cfg->destroy(mediated_cfg); @@ -172,10 +168,8 @@ static void initiate(private_initiate_mediation_job_t *this) destroy(this); } -/** - * Implementation of job_t.execute. - */ -static void reinitiate(private_initiate_mediation_job_t *this) +METHOD(job_t, reinitiate, void, + private_initiate_mediation_job_t *this) { ike_sa_t *mediated_sa, *mediation_sa; peer_cfg_t *mediated_cfg; @@ -223,20 +217,26 @@ static void reinitiate(private_initiate_mediation_job_t *this) destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_initiate_mediation_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /** * Creates an empty job */ static private_initiate_mediation_job_t *initiate_mediation_job_create_empty() { - private_initiate_mediation_job_t *this = malloc_thing(private_initiate_mediation_job_t); - - /* interface functions */ - this->public.job_interface.destroy = (void (*) (job_t *)) destroy; - - /* private variables */ - this->mediation_sa_id = NULL; - this->mediated_sa_id = NULL; - + private_initiate_mediation_job_t *this; + INIT(this, + .public = { + .job_interface = { + .get_priority = _get_priority, + .destroy = _destroy, + }, + }, + ); return this; } @@ -247,8 +247,7 @@ initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id) { private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty(); - this->public.job_interface.execute = (void (*) (job_t *)) initiate; - + this->public.job_interface.execute = _initiate; this->mediated_sa_id = ike_sa_id->clone(ike_sa_id); return &this->public; @@ -262,8 +261,7 @@ initiate_mediation_job_t *reinitiate_mediation_job_create(ike_sa_id_t *mediation { private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty(); - this->public.job_interface.execute = (void (*) (job_t *)) reinitiate; - + this->public.job_interface.execute = _reinitiate; this->mediation_sa_id = mediation_sa_id->clone(mediation_sa_id); this->mediated_sa_id = mediated_sa_id->clone(mediated_sa_id); diff --git a/src/libcharon/processing/jobs/mediation_job.c b/src/libcharon/processing/jobs/mediation_job.c index b5b8af3b3..6f02f2a0a 100644 --- a/src/libcharon/processing/jobs/mediation_job.c +++ b/src/libcharon/processing/jobs/mediation_job.c @@ -66,10 +66,8 @@ struct private_mediation_job_t { bool response; }; -/** - * Implements job_t.destroy. - */ -static void destroy(private_mediation_job_t *this) +METHOD(job_t, destroy, void, + private_mediation_job_t *this) { DESTROY_IF(this->target); DESTROY_IF(this->source); @@ -79,10 +77,8 @@ static void destroy(private_mediation_job_t *this) free(this); } -/** - * Implementation of job_t.execute. - */ -static void execute(private_mediation_job_t *this) +METHOD(job_t, execute, void, + private_mediation_job_t *this) { ike_sa_id_t *target_sa_id; @@ -137,26 +133,27 @@ static void execute(private_mediation_job_t *this) destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_mediation_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /** * Creates an empty mediation job */ static private_mediation_job_t *mediation_job_create_empty() { - private_mediation_job_t *this = malloc_thing(private_mediation_job_t); - - /* interface functions */ - this->public.job_interface.execute = (void (*) (job_t *)) execute; - this->public.job_interface.destroy = (void (*) (job_t *)) destroy; - - /* private variables */ - this->target = NULL; - this->source = NULL; - this->callback = FALSE; - this->connect_id = chunk_empty; - this->connect_key = chunk_empty; - this->endpoints = NULL; - this->response = FALSE; - + private_mediation_job_t *this; + INIT(this, + .public = { + .job_interface = { + .execute = _execute, + .get_priority = _get_priority, + .destroy = _destroy, + }, + }, + ); return this; } diff --git a/src/libcharon/processing/jobs/migrate_job.c b/src/libcharon/processing/jobs/migrate_job.c index 5e7c7ae88..eb10e2e46 100644 --- a/src/libcharon/processing/jobs/migrate_job.c +++ b/src/libcharon/processing/jobs/migrate_job.c @@ -79,12 +79,12 @@ METHOD(job_t, execute, void, } if (ike_sa) { - iterator_t *children; + enumerator_t *children; child_sa_t *child_sa; host_t *host; - children = ike_sa->create_child_sa_iterator(ike_sa); - while (children->iterate(children, (void**)&child_sa)) + children = ike_sa->create_child_sa_enumerator(ike_sa); + while (children->enumerate(children, (void**)&child_sa)) { if (child_sa->get_reqid(child_sa) == this->reqid) { @@ -120,6 +120,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_migrate_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -135,6 +141,7 @@ migrate_job_t *migrate_job_create(u_int32_t reqid, .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/process_message_job.c b/src/libcharon/processing/jobs/process_message_job.c index b6de4fc0f..a4924d001 100644 --- a/src/libcharon/processing/jobs/process_message_job.c +++ b/src/libcharon/processing/jobs/process_message_job.c @@ -84,6 +84,27 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_process_message_job_t *this) +{ + switch (this->message->get_exchange_type(this->message)) + { + case IKE_AUTH: + /* IKE auth is rather expensive and often blocking, low priority */ + return JOB_PRIO_LOW; + case INFORMATIONAL: + /* INFORMATIONALs are inexpensive, for DPD we should have low + * reaction times */ + return JOB_PRIO_HIGH; + case IKE_SA_INIT: + case CREATE_CHILD_SA: + default: + /* IKE_SA_INIT is expensive, but we will drop them in the receiver + * if we are overloaded */ + return JOB_PRIO_MEDIUM; + } +} + /* * Described in header */ @@ -95,6 +116,7 @@ process_message_job_t *process_message_job_create(message_t *message) .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.c b/src/libcharon/processing/jobs/rekey_child_sa_job.c index 2bcee2ddf..5855f1bc9 100644 --- a/src/libcharon/processing/jobs/rekey_child_sa_job.c +++ b/src/libcharon/processing/jobs/rekey_child_sa_job.c @@ -71,6 +71,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_rekey_child_sa_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -84,6 +90,7 @@ rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid, .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.c b/src/libcharon/processing/jobs/rekey_ike_sa_job.c index dc86ba9b3..5366195fd 100644 --- a/src/libcharon/processing/jobs/rekey_ike_sa_job.c +++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.c @@ -81,6 +81,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_rekey_ike_sa_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -92,6 +98,7 @@ rekey_ike_sa_job_t *rekey_ike_sa_job_create(ike_sa_id_t *ike_sa_id, bool reauth) .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/retransmit_job.c b/src/libcharon/processing/jobs/retransmit_job.c index 1c78abd27..050f7005a 100644 --- a/src/libcharon/processing/jobs/retransmit_job.c +++ b/src/libcharon/processing/jobs/retransmit_job.c @@ -70,6 +70,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_retransmit_job_t *this) +{ + return JOB_PRIO_HIGH; +} + /* * Described in header. */ @@ -81,6 +87,7 @@ retransmit_job_t *retransmit_job_create(u_int32_t message_id,ike_sa_id_t *ike_sa .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/roam_job.c b/src/libcharon/processing/jobs/roam_job.c index 74ef8bd6d..951ac5ad3 100644 --- a/src/libcharon/processing/jobs/roam_job.c +++ b/src/libcharon/processing/jobs/roam_job.c @@ -55,7 +55,8 @@ METHOD(job_t, execute, void, /* enumerator over all IKE_SAs gives us no way to checkin_and_destroy * after a DESTROY_ME, so we check out each available IKE_SA by hand. */ list = linked_list_create(); - enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager); + enumerator = charon->ike_sa_manager->create_enumerator( + charon->ike_sa_manager, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { id = ike_sa->get_id(ike_sa); @@ -85,6 +86,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_roam_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -96,6 +103,7 @@ roam_job_t *roam_job_create(bool address) .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/send_dpd_job.c b/src/libcharon/processing/jobs/send_dpd_job.c index 47b525363..ab00d013d 100644 --- a/src/libcharon/processing/jobs/send_dpd_job.c +++ b/src/libcharon/processing/jobs/send_dpd_job.c @@ -66,6 +66,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_send_dpd_job_t *this) +{ + return JOB_PRIO_HIGH; +} + /* * Described in header */ @@ -77,6 +83,7 @@ send_dpd_job_t *send_dpd_job_create(ike_sa_id_t *ike_sa_id) .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/send_keepalive_job.c b/src/libcharon/processing/jobs/send_keepalive_job.c index 8d98aad7e..5e128d478 100644 --- a/src/libcharon/processing/jobs/send_keepalive_job.c +++ b/src/libcharon/processing/jobs/send_keepalive_job.c @@ -60,6 +60,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_send_keepalive_job_t *this) +{ + return JOB_PRIO_HIGH; +} + /* * Described in header */ @@ -71,6 +77,7 @@ send_keepalive_job_t *send_keepalive_job_create(ike_sa_id_t *ike_sa_id) .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/processing/jobs/start_action_job.c b/src/libcharon/processing/jobs/start_action_job.c index 5dda18be2..b65181ef8 100644 --- a/src/libcharon/processing/jobs/start_action_job.c +++ b/src/libcharon/processing/jobs/start_action_job.c @@ -42,6 +42,7 @@ METHOD(job_t, execute, void, enumerator_t *enumerator, *children; peer_cfg_t *peer_cfg; child_cfg_t *child_cfg; + ipsec_mode_t mode; char *name; enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends, @@ -65,11 +66,20 @@ METHOD(job_t, execute, void, charon->controller->initiate(charon->controller, peer_cfg->get_ref(peer_cfg), child_cfg->get_ref(child_cfg), - NULL, NULL); + NULL, NULL, 0); break; case ACTION_ROUTE: DBG1(DBG_JOB, "start action: route '%s'", name); - charon->traps->install(charon->traps, peer_cfg, child_cfg); + mode = child_cfg->get_mode(child_cfg); + if (mode == MODE_PASS || mode == MODE_DROP) + { + charon->shunts->install(charon->shunts, child_cfg); + } + else + { + charon->traps->install(charon->traps, peer_cfg, + child_cfg); + } break; case ACTION_NONE: break; @@ -81,6 +91,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_start_action_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -92,10 +108,11 @@ start_action_job_t *start_action_job_create(void) .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, - ) + ); return &this->public; } diff --git a/src/libcharon/processing/jobs/update_sa_job.c b/src/libcharon/processing/jobs/update_sa_job.c index 3b4e9949f..c4f6e4782 100644 --- a/src/libcharon/processing/jobs/update_sa_job.c +++ b/src/libcharon/processing/jobs/update_sa_job.c @@ -74,6 +74,12 @@ METHOD(job_t, execute, void, destroy(this); } +METHOD(job_t, get_priority, job_priority_t, + private_update_sa_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + /* * Described in header */ @@ -85,6 +91,7 @@ update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new) .public = { .job_interface = { .execute = _execute, + .get_priority = _get_priority, .destroy = _destroy, }, }, diff --git a/src/libcharon/sa/authenticators/authenticator.c b/src/libcharon/sa/authenticators/authenticator.c index 83f5fbaad..9ffe661cc 100644 --- a/src/libcharon/sa/authenticators/authenticator.c +++ b/src/libcharon/sa/authenticators/authenticator.c @@ -28,11 +28,12 @@ ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS, "RSA signature", "pre-shared key", "DSS signature"); -ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS, +ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_GSPM, AUTH_DSS, "ECDSA-256 signature", "ECDSA-384 signature", - "ECDSA-521 signature"); -ENUM_END(auth_method_names, AUTH_ECDSA_521); + "ECDSA-521 signature", + "secure password method"); +ENUM_END(auth_method_names, AUTH_GSPM); /** * Described in header. diff --git a/src/libcharon/sa/authenticators/authenticator.h b/src/libcharon/sa/authenticators/authenticator.h index d27e006a3..5042e4a73 100644 --- a/src/libcharon/sa/authenticators/authenticator.h +++ b/src/libcharon/sa/authenticators/authenticator.h @@ -67,6 +67,12 @@ enum auth_method_t { * ECDSA with SHA-512 on the P-521 curve as specified in RFC 4754 */ AUTH_ECDSA_521 = 11, + + /** + * Generic Secure Password Authentication Method as specified in RFC 6467 + */ + AUTH_GSPM = 12, + }; /** diff --git a/src/libcharon/sa/authenticators/eap/eap_method.c b/src/libcharon/sa/authenticators/eap/eap_method.c index 0fa4a00c5..a05e8c59a 100644 --- a/src/libcharon/sa/authenticators/eap/eap_method.c +++ b/src/libcharon/sa/authenticators/eap/eap_method.c @@ -15,8 +15,28 @@ #include "eap_method.h" +#include <daemon.h> + ENUM(eap_role_names, EAP_SERVER, EAP_PEER, "EAP_SERVER", "EAP_PEER", ); +/** + * See header + */ +bool eap_method_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data) +{ + if (reg) + { + charon->eap->add_method(charon->eap, feature->arg.eap, 0, + feature->type == FEATURE_EAP_SERVER ? EAP_SERVER : EAP_PEER, + (eap_constructor_t)data); + } + else + { + charon->eap->remove_method(charon->eap, (eap_constructor_t)data); + } + return TRUE; +} diff --git a/src/libcharon/sa/authenticators/eap/eap_method.h b/src/libcharon/sa/authenticators/eap/eap_method.h index 0eab2b5ff..6242a5a6e 100644 --- a/src/libcharon/sa/authenticators/eap/eap_method.h +++ b/src/libcharon/sa/authenticators/eap/eap_method.h @@ -25,6 +25,7 @@ typedef struct eap_method_t eap_method_t; typedef enum eap_role_t eap_role_t; #include <library.h> +#include <plugins/plugin.h> #include <utils/identification.h> #include <eap/eap.h> #include <encoding/payloads/eap_payload.h> @@ -159,4 +160,18 @@ struct eap_method_t { typedef eap_method_t *(*eap_constructor_t)(identification_t *server, identification_t *peer); +/** + * Helper function to (un-)register EAP methods from plugin features. + * + * This function is a plugin_feature_callback_t and can be used with the + * PLUGIN_CALLBACK macro to register a EAP method constructor. + * + * @param plugin plugin registering the EAP method constructor + * @param feature associated plugin feature + * @param reg TRUE to register, FALSE to unregister. + * @param data data passed to callback, an eap_constructor_t + */ +bool eap_method_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data); + #endif /** EAP_METHOD_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/sim_card.h b/src/libcharon/sa/authenticators/eap/sim_card.h deleted file mode 100644 index 5f5dc580b..000000000 --- a/src/libcharon/sa/authenticators/eap/sim_card.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2008-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 sim_card sim_card - * @{ @ingroup eap - */ - -#ifndef SIM_CARD_H_ -#define SIM_CARD_H_ - -typedef struct sim_card_t sim_card_t; - -/** - * Interface for a (U)SIM card (used as EAP client). - * - * The SIM card completes triplets/quintuplets requested in a challenge - * received from the server. - * An implementation supporting only one of SIM/AKA authentication may - * implement the other methods with return_false()/return NOT_SUPPORTED/NULL. - */ -struct sim_card_t { - - /** - * Calculate SRES/KC from a RAND for SIM authentication. - * - * @param id permanent identity to get a triplet for - * @param rand RAND input buffer, fixed size 16 bytes - * @param sres SRES output buffer, fixed size 4 byte - * @param kc KC output buffer, fixed size 8 bytes - * @return TRUE if SRES/KC calculated, FALSE on error/wrong identity - */ - bool (*get_triplet)(sim_card_t *this, identification_t *id, - char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], - char kc[SIM_KC_LEN]); - - /** - * Calculate CK/IK/RES from RAND/AUTN for AKA authentication. - * - * If the received sequence number (in autn) is out of sync, INVALID_STATE - * is returned. - * The RES value is the only one with variable length. Pass a buffer - * of at least AKA_RES_MAX, the actual number of bytes is written to the - * res_len value. While the standard would allow any bit length between - * 32 and 128 bits, we support only full bytes for now. - * - * @param id permanent identity to request quintuplet for - * @param rand random value rand - * @param autn authentication token autn - * @param ck buffer receiving encryption key ck - * @param ik buffer receiving integrity key ik - * @param res buffer receiving authentication result res - * @param res_len nubmer of bytes written to res buffer - * @return SUCCESS, FAILED, or INVALID_STATE if out of sync - */ - status_t (*get_quintuplet)(sim_card_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], - char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char res[AKA_RES_MAX], int *res_len); - - /** - * Calculate AUTS from RAND for AKA resynchronization. - * - * @param id permanent identity to request quintuplet for - * @param rand random value rand - * @param auts resynchronization parameter auts - * @return TRUE if parameter generated successfully - */ - bool (*resync)(sim_card_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]); - - /** - * Set the pseudonym to use for next authentication. - * - * @param id permanent identity of the peer - * @param pseudonym pseudonym identity received from the server - */ - void (*set_pseudonym)(sim_card_t *this, identification_t *id, - identification_t *pseudonym); - - /** - * Get the pseudonym previously stored via set_pseudonym(). - * - * @param id permanent identity of the peer - * @return associated pseudonym identity, NULL if none stored - */ - identification_t* (*get_pseudonym)(sim_card_t *this, identification_t *id); - - /** - * Store parameters to use for the next fast reauthentication. - * - * @param id permanent identity of the peer - * @param next next fast reauthentication identity to use - * @param mk master key MK to store for reauthentication - * @param counter counter value to store, host order - */ - void (*set_reauth)(sim_card_t *this, identification_t *id, - identification_t *next, char mk[HASH_SIZE_SHA1], - u_int16_t counter); - - /** - * Retrieve parameters for fast reauthentication stored via set_reauth(). - * - * @param id permanent identity of the peer - * @param mk buffer receiving master key MK - * @param counter pointer receiving counter value, in host order - * @return fast reauthentication identity, NULL if not found - */ - identification_t* (*get_reauth)(sim_card_t *this, identification_t *id, - char mk[HASH_SIZE_SHA1], u_int16_t *counter); -}; - -#endif /** SIM_CARD_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/sim_hooks.h b/src/libcharon/sa/authenticators/eap/sim_hooks.h deleted file mode 100644 index 0a675e4ab..000000000 --- a/src/libcharon/sa/authenticators/eap/sim_hooks.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008-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 sim_hooks sim_hooks - * @{ @ingroup eap - */ - -#ifndef SIM_HOOKS_H_ -#define SIM_HOOKS_H_ - -typedef struct sim_hooks_t sim_hooks_t; - -/** - * Additional hooks invoked during EAP-SIM/AKA message processing. - */ -struct sim_hooks_t { - - /** - * SIM/AKA message parsing. - * - * As a SIM/AKA optionally contains encrypted attributes, the hook - * might get invoked twice, once before and once after decryption. - * - * @param message SIM/AKA message - * @param inbound TRUE for incoming messages, FALSE for outgoing - * @param decrypted TRUE if AT_ENCR_DATA has been decrypted - */ - void (*message)(sim_hooks_t *this, simaka_message_t *message, - bool inbound, bool decrypted); - - /** - * SIM/AKA encryption/authentication key hooks. - * - * @param k_encr derived SIM/AKA encryption key k_encr - * @param k_auth derived SIM/AKA authentication key k_auth - */ - void (*keys)(sim_hooks_t *this, chunk_t k_encr, chunk_t k_auth); -}; - -#endif /** SIM_HOOKS_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/sim_manager.c b/src/libcharon/sa/authenticators/eap/sim_manager.c deleted file mode 100644 index 9ccaf5298..000000000 --- a/src/libcharon/sa/authenticators/eap/sim_manager.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright (C) 2008 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. - */ - -#include "sim_manager.h" - -#include <daemon.h> -#include <utils/linked_list.h> -#include <threading/rwlock.h> - -typedef struct private_sim_manager_t private_sim_manager_t; - -/** - * Private data of an sim_manager_t object. - */ -struct private_sim_manager_t { - - /** - * Public sim_manager_t interface. - */ - sim_manager_t public; - - /** - * list of added cards - */ - linked_list_t *cards; - - /** - * list of added provider - */ - linked_list_t *providers; - - /** - * list of added hooks - */ - linked_list_t *hooks; - - /** - * lock for lists above - */ - rwlock_t *lock; -}; - -METHOD(sim_manager_t, add_card, void, - private_sim_manager_t *this, sim_card_t *card) -{ - this->lock->write_lock(this->lock); - this->cards->insert_last(this->cards, card); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, remove_card, void, - private_sim_manager_t *this, sim_card_t *card) -{ - this->lock->write_lock(this->lock); - this->cards->remove(this->cards, card, NULL); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, card_get_triplet, bool, - private_sim_manager_t *this, identification_t *id, - char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) -{ - enumerator_t *enumerator; - sim_card_t *card; - int tried = 0; - - this->lock->read_lock(this->lock); - enumerator = this->cards->create_enumerator(this->cards); - while (enumerator->enumerate(enumerator, &card)) - { - if (card->get_triplet(card, id, rand, sres, kc)) - { - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return TRUE; - } - tried++; - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - DBG1(DBG_IKE, "tried %d SIM cards, but none has triplets for '%Y'", - tried, id); - return FALSE; -} - -METHOD(sim_manager_t, card_get_quintuplet, status_t, - private_sim_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN], - char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char res[AKA_RES_MAX], int *res_len) -{ - enumerator_t *enumerator; - sim_card_t *card; - status_t status = NOT_FOUND; - int tried = 0; - - this->lock->read_lock(this->lock); - enumerator = this->cards->create_enumerator(this->cards); - while (enumerator->enumerate(enumerator, &card)) - { - status = card->get_quintuplet(card, id, rand, autn, ck, ik, res, res_len); - switch (status) - { /* try next on error, but not on INVALID_STATE */ - case SUCCESS: - case INVALID_STATE: - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return status; - case NOT_SUPPORTED: - case FAILED: - default: - tried++; - continue; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - DBG1(DBG_IKE, "tried %d SIM cards, but none has quintuplets for '%Y'", - tried, id); - return status; -} - -METHOD(sim_manager_t, card_resync, bool, - private_sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) -{ - enumerator_t *enumerator; - sim_card_t *card; - - this->lock->read_lock(this->lock); - enumerator = this->cards->create_enumerator(this->cards); - while (enumerator->enumerate(enumerator, &card)) - { - if (card->resync(card, id, rand, auts)) - { - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return TRUE; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return FALSE; -} - -METHOD(sim_manager_t, card_set_pseudonym, void, - private_sim_manager_t *this, identification_t *id, - identification_t *pseudonym) -{ - enumerator_t *enumerator; - sim_card_t *card; - - DBG1(DBG_IKE, "storing pseudonym '%Y' for '%Y'", pseudonym, id); - - this->lock->read_lock(this->lock); - enumerator = this->cards->create_enumerator(this->cards); - while (enumerator->enumerate(enumerator, &card)) - { - card->set_pseudonym(card, id, pseudonym); - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, card_get_pseudonym, identification_t*, - private_sim_manager_t *this, identification_t *id) -{ - enumerator_t *enumerator; - sim_card_t *card; - identification_t *pseudonym = NULL; - - this->lock->read_lock(this->lock); - enumerator = this->cards->create_enumerator(this->cards); - while (enumerator->enumerate(enumerator, &card)) - { - pseudonym = card->get_pseudonym(card, id); - if (pseudonym) - { - DBG1(DBG_IKE, "using stored pseudonym identity '%Y' " - "instead of '%Y'", pseudonym, id); - break; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return pseudonym; -} - -METHOD(sim_manager_t, card_set_reauth, void, - private_sim_manager_t *this, identification_t *id, identification_t *next, - char mk[HASH_SIZE_SHA1], u_int16_t counter) -{ - enumerator_t *enumerator; - sim_card_t *card; - - DBG1(DBG_IKE, "storing next reauthentication identity '%Y' for '%Y'", - next, id); - - this->lock->read_lock(this->lock); - enumerator = this->cards->create_enumerator(this->cards); - while (enumerator->enumerate(enumerator, &card)) - { - card->set_reauth(card, id, next, mk, counter); - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, card_get_reauth, identification_t*, - private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter) -{ - enumerator_t *enumerator; - sim_card_t *card; - identification_t *reauth = NULL; - - this->lock->read_lock(this->lock); - enumerator = this->cards->create_enumerator(this->cards); - while (enumerator->enumerate(enumerator, &card)) - { - reauth = card->get_reauth(card, id, mk, counter); - if (reauth) - { - DBG1(DBG_IKE, "using stored reauthentication identity '%Y' " - "instead of '%Y'", reauth, id); - break; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return reauth; -} - -METHOD(sim_manager_t, add_provider, void, - private_sim_manager_t *this, sim_provider_t *provider) -{ - this->lock->write_lock(this->lock); - this->providers->insert_last(this->providers, provider); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, remove_provider, void, - private_sim_manager_t *this, sim_provider_t *provider) -{ - this->lock->write_lock(this->lock); - this->providers->remove(this->providers, provider, NULL); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, provider_get_triplet, bool, - private_sim_manager_t *this, identification_t *id, char rand[SIM_RAND_LEN], - char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]) -{ - enumerator_t *enumerator; - sim_provider_t *provider; - int tried = 0; - - this->lock->read_lock(this->lock); - enumerator = this->providers->create_enumerator(this->providers); - while (enumerator->enumerate(enumerator, &provider)) - { - if (provider->get_triplet(provider, id, rand, sres, kc)) - { - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return TRUE; - } - tried++; - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - DBG1(DBG_IKE, "tried %d SIM providers, but none had a triplet for '%Y'", - tried, id); - return FALSE; -} - -METHOD(sim_manager_t, provider_get_quintuplet, bool, - private_sim_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN], - char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], - char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]) -{ - enumerator_t *enumerator; - sim_provider_t *provider; - int tried = 0; - - this->lock->read_lock(this->lock); - enumerator = this->providers->create_enumerator(this->providers); - while (enumerator->enumerate(enumerator, &provider)) - { - if (provider->get_quintuplet(provider, id, rand, xres, xres_len, - ck, ik, autn)) - { - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return TRUE; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - DBG1(DBG_IKE, "tried %d SIM providers, but none had a quintuplet for '%Y'", - tried, id); - return FALSE; -} - -METHOD(sim_manager_t, provider_resync, bool, - private_sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) -{ - enumerator_t *enumerator; - sim_provider_t *provider; - - this->lock->read_lock(this->lock); - enumerator = this->providers->create_enumerator(this->providers); - while (enumerator->enumerate(enumerator, &provider)) - { - if (provider->resync(provider, id, rand, auts)) - { - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return TRUE; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return FALSE; -} - -METHOD(sim_manager_t, provider_is_pseudonym, identification_t*, - private_sim_manager_t *this, identification_t *id) -{ - enumerator_t *enumerator; - sim_provider_t *provider; - identification_t *permanent = NULL; - - this->lock->read_lock(this->lock); - enumerator = this->providers->create_enumerator(this->providers); - while (enumerator->enumerate(enumerator, &provider)) - { - permanent = provider->is_pseudonym(provider, id); - if (permanent) - { - DBG1(DBG_IKE, "received pseudonym identity '%Y' " - "mapping to '%Y'", id, permanent); - break; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return permanent; -} - -METHOD(sim_manager_t, provider_gen_pseudonym, identification_t*, - private_sim_manager_t *this, identification_t *id) -{ - enumerator_t *enumerator; - sim_provider_t *provider; - identification_t *pseudonym = NULL; - - this->lock->read_lock(this->lock); - enumerator = this->providers->create_enumerator(this->providers); - while (enumerator->enumerate(enumerator, &provider)) - { - pseudonym = provider->gen_pseudonym(provider, id); - if (pseudonym) - { - DBG1(DBG_IKE, "proposing new pseudonym '%Y'", pseudonym); - break; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return pseudonym; -} - -METHOD(sim_manager_t, provider_is_reauth, identification_t*, - private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter) -{ - enumerator_t *enumerator; - sim_provider_t *provider; - identification_t *permanent = NULL; - - this->lock->read_lock(this->lock); - enumerator = this->providers->create_enumerator(this->providers); - while (enumerator->enumerate(enumerator, &provider)) - { - permanent = provider->is_reauth(provider, id, mk, counter); - if (permanent) - { - DBG1(DBG_IKE, "received reauthentication identity '%Y' " - "mapping to '%Y'", id, permanent); - break; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return permanent; -} - -METHOD(sim_manager_t, provider_gen_reauth, identification_t*, - private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1]) -{ - enumerator_t *enumerator; - sim_provider_t *provider; - identification_t *reauth = NULL; - - this->lock->read_lock(this->lock); - enumerator = this->providers->create_enumerator(this->providers); - while (enumerator->enumerate(enumerator, &provider)) - { - reauth = provider->gen_reauth(provider, id, mk); - if (reauth) - { - DBG1(DBG_IKE, "proposing new reauthentication identity '%Y'", reauth); - break; - } - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - return reauth; -} - -METHOD(sim_manager_t, add_hooks, void, - private_sim_manager_t *this, sim_hooks_t *hooks) -{ - this->lock->write_lock(this->lock); - this->hooks->insert_last(this->hooks, hooks); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, remove_hooks, void, - private_sim_manager_t *this, sim_hooks_t *hooks) -{ - this->lock->write_lock(this->lock); - this->hooks->remove(this->hooks, hooks, NULL); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, message_hook, void, - private_sim_manager_t *this, simaka_message_t *message, - bool inbound, bool decrypted) -{ - enumerator_t *enumerator; - sim_hooks_t *hooks; - - this->lock->read_lock(this->lock); - enumerator = this->hooks->create_enumerator(this->hooks); - while (enumerator->enumerate(enumerator, &hooks)) - { - hooks->message(hooks, message, inbound, decrypted); - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, key_hook, void, - private_sim_manager_t *this, chunk_t k_encr, chunk_t k_auth) -{ - enumerator_t *enumerator; - sim_hooks_t *hooks; - - this->lock->read_lock(this->lock); - enumerator = this->hooks->create_enumerator(this->hooks); - while (enumerator->enumerate(enumerator, &hooks)) - { - hooks->keys(hooks, k_encr, k_auth); - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); -} - -METHOD(sim_manager_t, destroy, void, - private_sim_manager_t *this) -{ - this->cards->destroy(this->cards); - this->providers->destroy(this->providers); - this->hooks->destroy(this->hooks); - this->lock->destroy(this->lock); - free(this); -} - -/** - * See header - */ -sim_manager_t *sim_manager_create() -{ - private_sim_manager_t *this; - - INIT(this, - .public = { - .add_card = _add_card, - .remove_card = _remove_card, - .card_get_triplet = _card_get_triplet, - .card_get_quintuplet = _card_get_quintuplet, - .card_resync = _card_resync, - .card_set_pseudonym = _card_set_pseudonym, - .card_get_pseudonym = _card_get_pseudonym, - .card_set_reauth = _card_set_reauth, - .card_get_reauth = _card_get_reauth, - .add_provider = _add_provider, - .remove_provider = _remove_provider, - .provider_get_triplet = _provider_get_triplet, - .provider_get_quintuplet = _provider_get_quintuplet, - .provider_resync = _provider_resync, - .provider_is_pseudonym = _provider_is_pseudonym, - .provider_gen_pseudonym = _provider_gen_pseudonym, - .provider_is_reauth = _provider_is_reauth, - .provider_gen_reauth = _provider_gen_reauth, - .add_hooks = _add_hooks, - .remove_hooks = _remove_hooks, - .message_hook = _message_hook, - .key_hook = _key_hook, - .destroy = _destroy, - }, - .cards = linked_list_create(), - .providers = linked_list_create(), - .hooks = linked_list_create(), - .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), - ); - - return &this->public; -} - diff --git a/src/libcharon/sa/authenticators/eap/sim_manager.h b/src/libcharon/sa/authenticators/eap/sim_manager.h deleted file mode 100644 index db4a65011..000000000 --- a/src/libcharon/sa/authenticators/eap/sim_manager.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2008-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 sim_manager sim_manager - * @{ @ingroup eap - */ - -#ifndef SIM_MANAGER_H_ -#define SIM_MANAGER_H_ - -#include <crypto/hashers/hasher.h> -#include <utils/identification.h> -#include <utils/enumerator.h> -#include <sa/authenticators/eap/eap_method.h> - -typedef struct sim_manager_t sim_manager_t; - -/** implemented in libsimaka, but we need it for the message hook */ -typedef struct simaka_message_t simaka_message_t; - -#define SIM_RAND_LEN 16 -#define SIM_SRES_LEN 4 -#define SIM_KC_LEN 8 - -#define AKA_RAND_LEN 16 -#define AKA_RES_MAX 16 -#define AKA_CK_LEN 16 -#define AKA_IK_LEN 16 -#define AKA_AUTN_LEN 16 -#define AKA_AUTS_LEN 14 - -#include <sa/authenticators/eap/sim_card.h> -#include <sa/authenticators/eap/sim_provider.h> -#include <sa/authenticators/eap/sim_hooks.h> - -/** - * The SIM manager handles multiple (U)SIM cards/providers and hooks. - */ -struct sim_manager_t { - - /** - * Register a SIM card (client) at the manager. - * - * @param card sim card to register - */ - void (*add_card)(sim_manager_t *this, sim_card_t *card); - - /** - * Unregister a previously registered card from the manager. - * - * @param card sim card to unregister - */ - void (*remove_card)(sim_manager_t *this, sim_card_t *card); - - /** - * Calculate SIM triplets on one of the registered SIM cards. - * - * @param id permanent identity to get a triplet for - * @param rand RAND input buffer, fixed size 16 bytes - * @param sres SRES output buffer, fixed size 4 byte - * @param kc KC output buffer, fixed size 8 bytes - * @return TRUE if calculated, FALSE if no matching card found - */ - bool (*card_get_triplet)(sim_manager_t *this, identification_t *id, - char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], - char kc[SIM_KC_LEN]); - - /** - * Calculate AKA quitpulets on one of the registered SIM cards. - * - * @param id permanent identity to request quintuplet for - * @param rand random value rand - * @param autn authentication token autn - * @param ck buffer receiving encryption key ck - * @param ik buffer receiving integrity key ik - * @param res buffer receiving authentication result res - * @param res_len nubmer of bytes written to res buffer - * @return SUCCESS, FAILED, or INVALID_STATE if out of sync - */ - status_t (*card_get_quintuplet)(sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], - char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char res[AKA_RES_MAX], int *res_len); - - /** - * Calculate resynchronization data on one of the registered SIM cards. - * - * @param id permanent identity to request quintuplet for - * @param rand random value rand - * @param auts resynchronization parameter auts - * @return TRUE if calculated, FALSE if no matcing card found - */ - bool (*card_resync)(sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]); - - /** - * Store a received pseudonym on one of the registered SIM cards. - * - * @param id permanent identity of the peer - * @param pseudonym pseudonym identity received from the server - */ - void (*card_set_pseudonym)(sim_manager_t *this, identification_t *id, - identification_t *pseudonym); - - /** - * Get a stored pseudonym from one of the registerd SIM cards. - * - * @param id permanent identity of the peer - * @return associated pseudonym identity, NULL if none found - */ - identification_t* (*card_get_pseudonym)(sim_manager_t *this, - identification_t *id); - - /** - * Store fast reauthentication parameters on one of the registered cards. - * - * @param id permanent identity of the peer - * @param next next fast reauthentication identity to use - * @param mk master key MK to store for reauthentication - * @param counter counter value to store, host order - */ - void (*card_set_reauth)(sim_manager_t *this, identification_t *id, - identification_t *next, char mk[HASH_SIZE_SHA1], - u_int16_t counter); - - /** - * Retrieve fast reauthentication parameters from one of the registerd cards. - * - * @param id permanent identity of the peer - * @param mk buffer receiving master key MK - * @param counter pointer receiving counter value, in host order - * @return fast reauthentication identity, NULL if none found - */ - identification_t* (*card_get_reauth)(sim_manager_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter); - - /** - * Register a triplet provider (server) at the manager. - * - * @param card sim card to register - */ - void (*add_provider)(sim_manager_t *this, sim_provider_t *provider); - - /** - * Unregister a previously registered provider from the manager. - * - * @param card sim card to unregister - */ - void (*remove_provider)(sim_manager_t *this, sim_provider_t *provider); - - /** - * Get a SIM triplet from one of the registered providers. - * - * @param id permanent identity of peer to gen triplet for - * @param rand RAND output buffer, fixed size 16 bytes - * @param sres SRES output buffer, fixed size 4 byte - * @param kc KC output buffer, fixed size 8 bytes - * @return TRUE if triplet received, FALSE if no match found - */ - bool (*provider_get_triplet)(sim_manager_t *this, identification_t *id, - char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], - char kc[SIM_KC_LEN]); - - /** - * Get a AKA quintuplet from one of the registered providers. - * - * @param id permanent identity of peer to create challenge for - * @param rand buffer receiving random value rand - * @param xres buffer receiving expected authentication result xres - * @param ck buffer receiving encryption key ck - * @param ik buffer receiving integrity key ik - * @param autn authentication token autn - * @return TRUE if quintuplet received, FALSE if no match found - */ - bool (*provider_get_quintuplet)(sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], - char xres[AKA_RES_MAX], int *xres_len, - char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char autn[AKA_AUTN_LEN]); - - /** - * Pass AKA resynchronization data to one of the registered providers. - * - * @param id permanent identity of peer requesting resynchronisation - * @param rand random value rand - * @param auts synchronization parameter auts - * @return TRUE if resynchronized, FALSE if not handled - */ - bool (*provider_resync)(sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]); - - /** - * Check if a peer uses a pseudonym using one of the registered providers. - * - * @param id pseudonym identity candidate - * @return permanent identity, NULL if id not a pseudonym - */ - identification_t* (*provider_is_pseudonym)(sim_manager_t *this, - identification_t *id); - - /** - * Generate a new pseudonym using one of the registered providers. - * - * @param id permanent identity to generate a pseudonym for - * @return generated pseudonym, NULL to not use a pseudonym identity - */ - identification_t* (*provider_gen_pseudonym)(sim_manager_t *this, - identification_t *id); - - /** - * Check if a peer uses a reauth id using one of the registered providers. - * - * @param id reauthentication identity (candidate) - * @param mk buffer receiving master key MK - * @param counter pointer receiving current counter value, host order - * @return permanent identity, NULL if not a known reauth identity - */ - identification_t* (*provider_is_reauth)(sim_manager_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1], - u_int16_t *counter); - - /** - * Generate a fast reauth id using one of the registered providers. - * - * @param id permanent peer identity - * @param mk master key to store along with generated identity - * @return fast reauthentication identity, NULL to not use reauth - */ - identification_t* (*provider_gen_reauth)(sim_manager_t *this, - identification_t *id, char mk[HASH_SIZE_SHA1]); - - /** - * Register a set of hooks to the manager. - * - * @param hooks hook interface implementation to register - */ - void (*add_hooks)(sim_manager_t *this, sim_hooks_t *hooks); - - /** - * Unregister a set of hooks from the manager. - * - * @param hooks hook interface implementation to unregister - */ - void (*remove_hooks)(sim_manager_t *this, sim_hooks_t *hooks); - - /** - * Invoke SIM/AKA message hook. - * - * @param message SIM message - * @param inbound TRUE for incoming messages, FALSE for outgoing - * @param decrypted TRUE if AT_ENCR_DATA has been decrypted - */ - void (*message_hook)(sim_manager_t *this, simaka_message_t *message, - bool inbound, bool decrypted); - - /** - * Invoke SIM/AKA key hook. - * - * @param k_encr SIM/AKA encryption key k_encr - * @param k_auth SIM/AKA authentication key k_auth - */ - void (*key_hook)(sim_manager_t *this, chunk_t k_encr, chunk_t k_auth); - - /** - * Destroy a manager instance. - */ - void (*destroy)(sim_manager_t *this); -}; - -/** - * Create an SIM manager to handle multiple (U)SIM cards/providers. - * - * @return sim_t object - */ -sim_manager_t *sim_manager_create(); - -#endif /** SIM_MANAGER_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/sim_provider.h b/src/libcharon/sa/authenticators/eap/sim_provider.h deleted file mode 100644 index 191e094db..000000000 --- a/src/libcharon/sa/authenticators/eap/sim_provider.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2008-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 sim_provider sim_provider - * @{ @ingroup eap - */ - -#ifndef SIM_PROVIDER_H_ -#define SIM_PROVIDER_H_ - -typedef struct sim_provider_t sim_provider_t; - -/** - * Interface for a triplet/quintuplet provider (used as EAP server). - * - * A SIM provider hands out triplets for SIM authentication and quintuplets - * for AKA authentication. Multiple SIM provider instances can serve as - * authentication backend to authenticate clients using SIM/AKA. - * An implementation supporting only one of SIM/AKA authentication may - * implement the other methods with return_false(). - */ -struct sim_provider_t { - - /** - * Create a challenge for SIM authentication. - * - * @param id permanent identity of peer to gen triplet for - * @param rand RAND output buffer, fixed size 16 bytes - * @param sres SRES output buffer, fixed size 4 byte - * @param kc KC output buffer, fixed size 8 bytes - * @return TRUE if triplet received, FALSE otherwise - */ - bool (*get_triplet)(sim_provider_t *this, identification_t *id, - char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], - char kc[SIM_KC_LEN]); - - /** - * Create a challenge for AKA authentication. - * - * The XRES value is the only one with variable length. Pass a buffer - * of at least AKA_RES_MAX, the actual number of bytes is written to the - * xres_len value. While the standard would allow any bit length between - * 32 and 128 bits, we support only full bytes for now. - * - * @param id permanent identity of peer to create challenge for - * @param rand buffer receiving random value rand - * @param xres buffer receiving expected authentication result xres - * @param xres_len nubmer of bytes written to xres buffer - * @param ck buffer receiving encryption key ck - * @param ik buffer receiving integrity key ik - * @param autn authentication token autn - * @return TRUE if quintuplet generated successfully - */ - bool (*get_quintuplet)(sim_provider_t *this, identification_t *id, - char rand[AKA_RAND_LEN], - char xres[AKA_RES_MAX], int *xres_len, - char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], - char autn[AKA_AUTN_LEN]); - - /** - * Process AKA resynchroniusation request of a peer. - * - * @param id permanent identity of peer requesting resynchronisation - * @param rand random value rand - * @param auts synchronization parameter auts - * @return TRUE if resynchronized successfully - */ - bool (*resync)(sim_provider_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]); - - /** - * Check if peer uses a pseudonym, get permanent identity. - * - * @param id pseudonym identity candidate - * @return permanent identity, NULL if id not a pseudonym - */ - identification_t* (*is_pseudonym)(sim_provider_t *this, - identification_t *id); - - /** - * Generate a pseudonym identitiy for a given peer identity. - * - * @param id permanent identity to generate a pseudonym for - * @return generated pseudonym, NULL to not use a pseudonym identity - */ - identification_t* (*gen_pseudonym)(sim_provider_t *this, - identification_t *id); - - /** - * Check if peer uses reauthentication, retrieve reauth parameters. - * - * @param id reauthentication identity (candidate) - * @param mk buffer receiving master key MK - * @param counter pointer receiving current counter value, host order - * @return permanent identity, NULL if id not a reauth identity - */ - identification_t* (*is_reauth)(sim_provider_t *this, identification_t *id, - char mk[HASH_SIZE_SHA1], u_int16_t *counter); - - /** - * Generate a fast reauthentication identity, associated to a master key. - * - * @param id permanent peer identity - * @param mk master key to store along with generated identity - * @return fast reauthentication identity, NULL to not use reauth - */ - identification_t* (*gen_reauth)(sim_provider_t *this, identification_t *id, - char mk[HASH_SIZE_SHA1]); -}; - -#endif /** SIM_CARD_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c index d442acb00..5c8f0b6ce 100644 --- a/src/libcharon/sa/authenticators/eap_authenticator.c +++ b/src/libcharon/sa/authenticators/eap_authenticator.c @@ -160,7 +160,9 @@ static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this, { if (this->method->initiate(this->method, &out) == NEED_MORE) { - DBG1(DBG_IKE, "initiating EAP-Identity request"); + DBG1(DBG_IKE, "initiating %N method (id 0x%02X)", + eap_type_names, EAP_IDENTITY, + this->method->get_identifier(this->method)); return out; } this->method->destroy(this->method); @@ -216,23 +218,12 @@ static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this, */ static void replace_eap_identity(private_eap_authenticator_t *this) { - enumerator_t *enumerator; - auth_rule_t rule; + identification_t *eap_identity; auth_cfg_t *cfg; - void *ptr; + eap_identity = this->eap_identity->clone(this->eap_identity); cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); - enumerator = cfg->create_enumerator(cfg); - while (enumerator->enumerate(enumerator, &rule, &ptr)) - { - if (rule == AUTH_RULE_EAP_IDENTITY) - { - cfg->replace(cfg, enumerator, AUTH_RULE_EAP_IDENTITY, - this->eap_identity->clone(this->eap_identity)); - break; - } - } - enumerator->destroy(enumerator); + cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, eap_identity); } /** @@ -349,8 +340,8 @@ static eap_payload_t* client_process_eap(private_eap_authenticator_t *this, { id = this->ike_sa->get_my_id(this->ike_sa); } - DBG1(DBG_IKE, "server requested %N, sending '%Y'", - eap_type_names, type, id); + DBG1(DBG_IKE, "server requested %N (id 0x%02X), sending '%Y'", + eap_type_names, type, in->get_identifier(in), id); this->eap_identity = id->clone(id); this->method = load_method(this, type, vendor, EAP_PEER); diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index dc42ba787..2130a5998 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2010 Tobias Brunner + * Copyright (C) 2006-2011 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005 Jan Hutter @@ -657,6 +657,55 @@ METHOD(child_sa_t, install, status_t, return status; } +/** + * Install 3 policies: out, in and forward + */ +static status_t install_policies_internal(private_child_sa_t *this, + host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, + traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, + ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority) +{ + status_t status = SUCCESS; + status |= hydra->kernel_interface->add_policy(hydra->kernel_interface, + my_addr, other_addr, my_ts, other_ts, + POLICY_OUT, type, other_sa, + this->mark_out, priority); + + status |= hydra->kernel_interface->add_policy(hydra->kernel_interface, + other_addr, my_addr, other_ts, my_ts, + POLICY_IN, type, my_sa, + this->mark_in, priority); + if (this->mode != MODE_TRANSPORT) + { + status |= hydra->kernel_interface->add_policy(hydra->kernel_interface, + other_addr, my_addr, other_ts, my_ts, + POLICY_FWD, type, my_sa, + this->mark_in, priority); + } + return status; +} + +/** + * Delete 3 policies: out, in and forward + */ +static void del_policies_internal(private_child_sa_t *this, + traffic_selector_t *my_ts, traffic_selector_t *other_ts, + policy_priority_t priority) +{ + hydra->kernel_interface->del_policy(hydra->kernel_interface, + my_ts, other_ts, POLICY_OUT, this->reqid, + this->mark_out, priority); + hydra->kernel_interface->del_policy(hydra->kernel_interface, + other_ts, my_ts, POLICY_IN, this->reqid, + this->mark_in, priority); + if (this->mode != MODE_TRANSPORT) + { + hydra->kernel_interface->del_policy(hydra->kernel_interface, + other_ts, my_ts, POLICY_FWD, this->reqid, + this->mark_in, priority); + } +} + METHOD(child_sa_t, add_policies, status_t, private_child_sa_t *this, linked_list_t *my_ts_list, linked_list_t *other_ts_list) @@ -664,7 +713,6 @@ METHOD(child_sa_t, add_policies, status_t, enumerator_t *enumerator; traffic_selector_t *my_ts, *other_ts; status_t status = SUCCESS; - bool routed = (this->state == CHILD_CREATED); /* apply traffic selectors */ enumerator = my_ts_list->create_enumerator(my_ts_list); @@ -682,6 +730,7 @@ METHOD(child_sa_t, add_policies, status_t, if (this->config->install_policy(this->config)) { + policy_priority_t priority; ipsec_sa_cfg_t my_sa = { .mode = this->mode, .reqid = this->reqid, @@ -708,31 +757,28 @@ METHOD(child_sa_t, add_policies, status_t, other_sa.ah.spi = this->other_spi; } + priority = this->state == CHILD_CREATED ? POLICY_PRIORITY_ROUTED + : POLICY_PRIORITY_DEFAULT; + /* enumerate pairs of traffic selectors */ enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { - /* install 3 policies: out, in and forward */ - status |= hydra->kernel_interface->add_policy( - hydra->kernel_interface, - this->my_addr, this->other_addr, my_ts, other_ts, - POLICY_OUT, POLICY_IPSEC, &other_sa, - this->mark_out, routed); - - status |= hydra->kernel_interface->add_policy( - hydra->kernel_interface, - this->other_addr, this->my_addr, other_ts, my_ts, - POLICY_IN, POLICY_IPSEC, &my_sa, - this->mark_in, routed); - if (this->mode != MODE_TRANSPORT) + /* install outbound drop policy to avoid packets leaving unencrypted + * when updating policies */ + if (priority == POLICY_PRIORITY_DEFAULT) { - status |= hydra->kernel_interface->add_policy( - hydra->kernel_interface, - this->other_addr, this->my_addr, other_ts, my_ts, - POLICY_FWD, POLICY_IPSEC, &my_sa, - this->mark_in, routed); + status |= install_policies_internal(this, this->my_addr, + this->other_addr, my_ts, other_ts, + &my_sa, &other_sa, POLICY_DROP, + POLICY_PRIORITY_FALLBACK); } + /* install policies */ + status |= install_policies_internal(this, this->my_addr, + this->other_addr, my_ts, other_ts, + &my_sa, &other_sa, POLICY_IPSEC, priority); + if (status != SUCCESS) { break; @@ -769,7 +815,7 @@ METHOD(child_sa_t, update, status_t, if (!transport_proxy_mode) { - /* update our (initator) SA */ + /* update our (initiator) SA */ if (this->my_spi) { if (hydra->kernel_interface->update_sa(hydra->kernel_interface, @@ -835,26 +881,22 @@ METHOD(child_sa_t, update, status_t, enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { + traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL; /* remove old policies first */ - hydra->kernel_interface->del_policy(hydra->kernel_interface, - my_ts, other_ts, POLICY_OUT, this->mark_out, FALSE); - hydra->kernel_interface->del_policy(hydra->kernel_interface, - other_ts, my_ts, POLICY_IN, this->mark_in, FALSE); - if (this->mode != MODE_TRANSPORT) - { - hydra->kernel_interface->del_policy(hydra->kernel_interface, - other_ts, my_ts, POLICY_FWD, this->mark_in, FALSE); - } + del_policies_internal(this, my_ts, other_ts, + POLICY_PRIORITY_DEFAULT); - /* check whether we have to update a "dynamic" traffic selector */ + /* check if we have to update a "dynamic" traffic selector */ if (!me->ip_equals(me, this->my_addr) && my_ts->is_host(my_ts, this->my_addr)) { + old_my_ts = my_ts->clone(my_ts); my_ts->set_address(my_ts, me); } if (!other->ip_equals(other, this->other_addr) && other_ts->is_host(other_ts, this->other_addr)) { + old_other_ts = other_ts->clone(other_ts); other_ts->set_address(other_ts, other); } @@ -862,22 +904,28 @@ METHOD(child_sa_t, update, status_t, * correctly */ if (vip) { - hydra->kernel_interface->del_ip(hydra->kernel_interface, vip); - hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, me); + hydra->kernel_interface->del_ip(hydra->kernel_interface, + vip); + hydra->kernel_interface->add_ip(hydra->kernel_interface, + vip, me); } /* reinstall updated policies */ - hydra->kernel_interface->add_policy(hydra->kernel_interface, - me, other, my_ts, other_ts, POLICY_OUT, POLICY_IPSEC, - &other_sa, this->mark_out, FALSE); - hydra->kernel_interface->add_policy(hydra->kernel_interface, - other, me, other_ts, my_ts, POLICY_IN, POLICY_IPSEC, - &my_sa, this->mark_in, FALSE); - if (this->mode != MODE_TRANSPORT) + install_policies_internal(this, me, other, my_ts, other_ts, + &my_sa, &other_sa, POLICY_IPSEC, + POLICY_PRIORITY_DEFAULT); + + /* update fallback policies after the new policy is in place */ + if (old_my_ts || old_other_ts) { - hydra->kernel_interface->add_policy(hydra->kernel_interface, - other, me, other_ts, my_ts, POLICY_FWD, POLICY_IPSEC, - &my_sa, this->mark_in, FALSE); + del_policies_internal(this, old_my_ts ?: my_ts, + old_other_ts ?: other_ts, + POLICY_PRIORITY_FALLBACK); + install_policies_internal(this, me, other, my_ts, other_ts, + &my_sa, &other_sa, POLICY_DROP, + POLICY_PRIORITY_FALLBACK); + DESTROY_IF(old_my_ts); + DESTROY_IF(old_other_ts); } } enumerator->destroy(enumerator); @@ -910,7 +958,10 @@ METHOD(child_sa_t, destroy, void, { enumerator_t *enumerator; traffic_selector_t *my_ts, *other_ts; - bool unrouted = (this->state == CHILD_ROUTED); + policy_priority_t priority; + + priority = this->state == CHILD_ROUTED ? POLICY_PRIORITY_ROUTED + : POLICY_PRIORITY_DEFAULT; set_state(this, CHILD_DESTROYING); @@ -942,14 +993,11 @@ METHOD(child_sa_t, destroy, void, enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { - hydra->kernel_interface->del_policy(hydra->kernel_interface, - my_ts, other_ts, POLICY_OUT, this->mark_out, unrouted); - hydra->kernel_interface->del_policy(hydra->kernel_interface, - other_ts, my_ts, POLICY_IN, this->mark_in, unrouted); - if (this->mode != MODE_TRANSPORT) + del_policies_internal(this, my_ts, other_ts, priority); + if (priority == POLICY_PRIORITY_DEFAULT) { - hydra->kernel_interface->del_policy(hydra->kernel_interface, - other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted); + del_policies_internal(this, my_ts, other_ts, + POLICY_PRIORITY_FALLBACK); } } enumerator->destroy(enumerator); diff --git a/src/libcharon/sa/connect_manager.c b/src/libcharon/sa/connect_manager.c index 972cc98ad..7b6ca430f 100644 --- a/src/libcharon/sa/connect_manager.c +++ b/src/libcharon/sa/connect_manager.c @@ -130,25 +130,24 @@ static void endpoint_pair_destroy(endpoint_pair_t *this) static endpoint_pair_t *endpoint_pair_create(endpoint_notify_t *initiator, endpoint_notify_t *responder, bool initiator_is_local) { - endpoint_pair_t *this = malloc_thing(endpoint_pair_t); - - this->id = 0; + endpoint_pair_t *this; u_int32_t pi = initiator->get_priority(initiator); u_int32_t pr = responder->get_priority(responder); - this->priority = pow(2, 32) * min(pi, pr) + 2 * max(pi, pr) + (pi > pr ? 1 : 0); - this->local = initiator_is_local ? initiator->get_base(initiator) - : responder->get_base(responder); + INIT(this, + .priority = pow(2, 32) * min(pi, pr) + 2 * max(pi, pr) + + (pi > pr ? 1 : 0), + .local = initiator_is_local ? initiator->get_base(initiator) + : responder->get_base(responder), + .remote = initiator_is_local ? responder->get_host(responder) + : initiator->get_host(initiator), + .state = CHECK_WAITING, + ); + this->local = this->local->clone(this->local); - this->remote = initiator_is_local ? responder->get_host(responder) - : initiator->get_host(initiator); this->remote = this->remote->clone(this->remote); - this->state = CHECK_WAITING; - this->retransmitted = 0; - this->packet = NULL; - return this; } @@ -239,23 +238,24 @@ static check_list_t *check_list_create(identification_t *initiator, linked_list_t *initiator_endpoints, bool is_initiator) { - check_list_t *this = malloc_thing(check_list_t); - - this->connect_id = chunk_clone(connect_id); - - this->initiator.id = initiator->clone(initiator); - this->initiator.key = chunk_clone(initiator_key); - this->initiator.endpoints = initiator_endpoints->clone_offset(initiator_endpoints, offsetof(endpoint_notify_t, clone)); - - this->responder.id = responder->clone(responder); - this->responder.key = chunk_empty; - this->responder.endpoints = NULL; - - this->pairs = linked_list_create(); - this->triggered = linked_list_create(); - this->state = CHECK_NONE; - this->is_initiator = is_initiator; - this->is_finishing = FALSE; + check_list_t *this; + + INIT(this, + .connect_id = chunk_clone(connect_id), + .initiator = { + .id = initiator->clone(initiator), + .key = chunk_clone(initiator_key), + .endpoints = initiator_endpoints->clone_offset(initiator_endpoints, + offsetof(endpoint_notify_t, clone)), + }, + .responder = { + .id = responder->clone(responder), + }, + .pairs = linked_list_create(), + .triggered = linked_list_create(), + .state = CHECK_NONE, + .is_initiator = is_initiator, + ); return this; } @@ -294,11 +294,13 @@ static void initiated_destroy(initiated_t *this) static initiated_t *initiated_create(identification_t *id, identification_t *peer_id) { - initiated_t *this = malloc_thing(initiated_t); + initiated_t *this; - this->id = id->clone(id); - this->peer_id = peer_id->clone(peer_id); - this->mediated = linked_list_create(); + INIT(this, + .id = id->clone(id), + .peer_id = peer_id->clone(peer_id), + .mediated = linked_list_create(), + ); return this; } @@ -351,16 +353,11 @@ static void check_destroy(check_t *this) */ static check_t *check_create() { - check_t *this = malloc_thing(check_t); - - this->connect_id = chunk_empty; - this->auth = chunk_empty; - this->endpoint_raw = chunk_empty; - this->src = NULL; - this->dst = NULL; - this->endpoint = NULL; + check_t *this; - this->mid = 0; + INIT(this, + .mid = 0, + ); return this; } @@ -396,10 +393,12 @@ static void callback_data_destroy(callback_data_t *this) static callback_data_t *callback_data_create(private_connect_manager_t *connect_manager, chunk_t connect_id) { - callback_data_t *this = malloc_thing(callback_data_t); - this->connect_manager = connect_manager; - this->connect_id = chunk_clone(connect_id); - this->mid = 0; + callback_data_t *this; + INIT(this, + .connect_manager = connect_manager, + .connect_id = chunk_clone(connect_id), + .mid = 0, + ); return this; } @@ -443,11 +442,11 @@ static void initiate_data_destroy(initiate_data_t *this) static initiate_data_t *initiate_data_create(check_list_t *checklist, initiated_t *initiated) { - initiate_data_t *this = malloc_thing(initiate_data_t); - - this->checklist = checklist; - this->initiated = initiated; - + initiate_data_t *this; + INIT(this, + .checklist = checklist, + .initiated = initiated, + ); return this; } @@ -476,19 +475,19 @@ static status_t get_initiated_by_ids(private_connect_manager_t *this, static void remove_initiated(private_connect_manager_t *this, initiated_t *initiated) { - iterator_t *iterator; + enumerator_t *enumerator; initiated_t *current; - iterator = this->initiated->create_iterator(this->initiated, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = this->initiated->create_enumerator(this->initiated); + while (enumerator->enumerate(enumerator, (void**)¤t)) { if (current == initiated) { - iterator->remove(iterator); + this->initiated->remove_at(this->initiated, enumerator); break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } /** @@ -514,19 +513,19 @@ static status_t get_checklist_by_id(private_connect_manager_t *this, static void remove_checklist(private_connect_manager_t *this, check_list_t *checklist) { - iterator_t *iterator; + enumerator_t *enumerator; check_list_t *current; - iterator = this->checklists->create_iterator(this->checklists, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = this->checklists->create_enumerator(this->checklists); + while (enumerator->enumerate(enumerator, (void**)¤t)) { if (current == checklist) { - iterator->remove(iterator); + this->checklists->remove_at(this->checklists, enumerator); break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } /** @@ -550,26 +549,15 @@ static status_t endpoints_contain(linked_list_t *endpoints, host_t *host, */ static void insert_pair_by_priority(linked_list_t *pairs, endpoint_pair_t *pair) { - iterator_t *iterator; + enumerator_t *enumerator = pairs->create_enumerator(pairs); endpoint_pair_t *current; - bool inserted = FALSE; - - iterator = pairs->create_iterator(pairs, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) - { - if (current->priority < pair->priority) - { - iterator->insert_before(iterator, pair); - inserted = TRUE; - break; - } - } - iterator->destroy(iterator); - - if (!inserted) + while (enumerator->enumerate(enumerator, (void**)¤t) && + current->priority >= pair->priority) { - pairs->insert_last(pairs, pair); + continue; } + pairs->insert_before(pairs, enumerator, pair); + enumerator->destroy(enumerator); } /** @@ -631,14 +619,14 @@ static bool match_waiting_pair(endpoint_pair_t *current) static status_t get_triggered_pair(check_list_t *checklist, endpoint_pair_t **pair) { - iterator_t *iterator; + enumerator_t *enumerator; endpoint_pair_t *current; status_t status = NOT_FOUND; - iterator = checklist->triggered->create_iterator(checklist->triggered, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = checklist->triggered->create_enumerator(checklist->triggered); + while (enumerator->enumerate(enumerator, (void**)¤t)) { - iterator->remove(iterator); + checklist->triggered->remove_at(checklist->triggered, enumerator); if (current->state == CHECK_WAITING) { @@ -650,7 +638,7 @@ static status_t get_triggered_pair(check_list_t *checklist, break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return status; } @@ -660,17 +648,17 @@ static status_t get_triggered_pair(check_list_t *checklist, */ static void print_checklist(check_list_t *checklist) { - iterator_t *iterator; + enumerator_t *enumerator; endpoint_pair_t *current; DBG1(DBG_IKE, "pairs on checklist %#B:", &checklist->connect_id); - iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = checklist->pairs->create_enumerator(checklist->pairs); + while (enumerator->enumerate(enumerator, (void**)¤t)) { DBG1(DBG_IKE, " * %#H - %#H (%d)", current->local, current->remote, current->priority); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } /** @@ -679,17 +667,17 @@ static void print_checklist(check_list_t *checklist) */ static void prune_pairs(linked_list_t *pairs) { - iterator_t *iterator, *search; + enumerator_t *enumerator, *search; endpoint_pair_t *current, *other; u_int32_t id = 0; - iterator = pairs->create_iterator(pairs, TRUE); - search = pairs->create_iterator(pairs, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = pairs->create_enumerator(pairs); + search = pairs->create_enumerator(pairs); + while (enumerator->enumerate(enumerator, (void**)¤t)) { current->id = ++id; - while (search->iterate(search, (void**)&other)) + while (search->enumerate(search, (void**)&other)) { if (current == other) { @@ -705,14 +693,14 @@ static void prune_pairs(linked_list_t *pairs) * 'current', remove it */ DBG1(DBG_IKE, "pruning endpoint pair %#H - %#H with priority %d", other->local, other->remote, other->priority); - search->remove(search); + pairs->remove_at(pairs, search); endpoint_pair_destroy(other); } } - search->reset(search); + pairs->reset_enumerator(pairs, search); } search->destroy(search); - iterator->destroy(iterator); + enumerator->destroy(enumerator); } /** @@ -721,16 +709,16 @@ static void prune_pairs(linked_list_t *pairs) static void build_pairs(check_list_t *checklist) { /* FIXME: limit endpoints and pairs */ - iterator_t *iterator_i, *iterator_r; + enumerator_t *enumerator_i, *enumerator_r; endpoint_notify_t *initiator, *responder; - iterator_i = checklist->initiator.endpoints->create_iterator( - checklist->initiator.endpoints, TRUE); - while (iterator_i->iterate(iterator_i, (void**)&initiator)) + enumerator_i = checklist->initiator.endpoints->create_enumerator( + checklist->initiator.endpoints); + while (enumerator_i->enumerate(enumerator_i, (void**)&initiator)) { - iterator_r = checklist->responder.endpoints->create_iterator( - checklist->responder.endpoints, TRUE); - while (iterator_r->iterate(iterator_r, (void**)&responder)) + enumerator_r = checklist->responder.endpoints->create_enumerator( + checklist->responder.endpoints); + while (enumerator_r->enumerate(enumerator_r, (void**)&responder)) { if (initiator->get_family(initiator) != responder->get_family(responder)) { @@ -740,9 +728,9 @@ static void build_pairs(check_list_t *checklist) insert_pair_by_priority(checklist->pairs, endpoint_pair_create( initiator, responder, checklist->is_initiator)); } - iterator_r->destroy(iterator_r); + enumerator_r->destroy(enumerator_r); } - iterator_i->destroy(iterator_i); + enumerator_i->destroy(enumerator_i); print_checklist(checklist); @@ -895,19 +883,19 @@ static job_requeue_t initiator_finish(callback_data_t *data) static void update_checklist_state(private_connect_manager_t *this, check_list_t *checklist) { - iterator_t *iterator; + enumerator_t *enumerator; endpoint_pair_t *current; bool in_progress = FALSE, succeeded = FALSE; - iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = checklist->pairs->create_enumerator(checklist->pairs); + while (enumerator->enumerate(enumerator, (void**)¤t)) { switch(current->state) { case CHECK_WAITING: /* at least one is still waiting -> checklist remains * in waiting state */ - iterator->destroy(iterator); + enumerator->destroy(enumerator); return; case CHECK_IN_PROGRESS: in_progress = TRUE; @@ -919,7 +907,7 @@ static void update_checklist_state(private_connect_manager_t *this, break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); if (checklist->is_initiator && succeeded && !checklist->is_finishing) { @@ -1185,8 +1173,9 @@ static job_requeue_t initiate_mediated(initiate_data_t *data) if (get_best_valid_pair(checklist, &pair) == SUCCESS) { ike_sa_id_t *waiting_sa; - iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE); - while (iterator->iterate(iterator, (void**)&waiting_sa)) + enumerator_t *enumerator = initiated->mediated->create_enumerator( + initiated->mediated); + while (enumerator->enumerate(enumerator, (void**)&waiting_sa)) { ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa); if (sa->initiate_mediated(sa, pair->local, pair->remote, checklist->connect_id) != SUCCESS) @@ -1199,7 +1188,7 @@ static job_requeue_t initiate_mediated(initiate_data_t *data) charon->ike_sa_manager->checkin(charon->ike_sa_manager, sa); } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } else { @@ -1355,10 +1344,8 @@ static void process_request(private_connect_manager_t *this, check_t *check, check_destroy(response); } -/** - * Implementation of connect_manager_t.process_check. - */ -static void process_check(private_connect_manager_t *this, message_t *message) +METHOD(connect_manager_t, process_check, void, + private_connect_manager_t *this, message_t *message) { if (message->parse_body(message, NULL) != SUCCESS) { @@ -1421,12 +1408,9 @@ static void process_check(private_connect_manager_t *this, message_t *message) check_destroy(check); } -/** - * Implementation of connect_manager_t.check_and_register. - */ -static bool check_and_register(private_connect_manager_t *this, - identification_t *id, identification_t *peer_id, - ike_sa_id_t *mediated_sa) +METHOD(connect_manager_t, check_and_register, bool, + private_connect_manager_t *this, identification_t *id, + identification_t *peer_id, ike_sa_id_t *mediated_sa) { initiated_t *initiated; bool already_there = TRUE; @@ -1455,12 +1439,9 @@ static bool check_and_register(private_connect_manager_t *this, return already_there; } -/** - * Implementation of connect_manager_t.check_and_initiate. - */ -static void check_and_initiate(private_connect_manager_t *this, - ike_sa_id_t *mediation_sa, identification_t *id, - identification_t *peer_id) +METHOD(connect_manager_t, check_and_initiate, void, + private_connect_manager_t *this, ike_sa_id_t *mediation_sa, + identification_t *id, identification_t *peer_id) { initiated_t *initiated; @@ -1474,27 +1455,23 @@ static void check_and_initiate(private_connect_manager_t *this, } ike_sa_id_t *waiting_sa; - iterator_t *iterator = initiated->mediated->create_iterator( - initiated->mediated, TRUE); - while (iterator->iterate(iterator, (void**)&waiting_sa)) + enumerator_t *enumerator = initiated->mediated->create_enumerator( + initiated->mediated); + while (enumerator->enumerate(enumerator, (void**)&waiting_sa)) { job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa, waiting_sa); lib->processor->queue_job(lib->processor, job); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); this->mutex->unlock(this->mutex); } -/** - * Implementation of connect_manager_t.set_initiator_data. - */ -static status_t set_initiator_data(private_connect_manager_t *this, - identification_t *initiator, - identification_t *responder, - chunk_t connect_id, chunk_t key, - linked_list_t *endpoints, bool is_initiator) +METHOD(connect_manager_t, set_initiator_data, status_t, + private_connect_manager_t *this, identification_t *initiator, + identification_t *responder, chunk_t connect_id, chunk_t key, + linked_list_t *endpoints, bool is_initiator) { check_list_t *checklist; @@ -1517,12 +1494,9 @@ static status_t set_initiator_data(private_connect_manager_t *this, return SUCCESS; } -/** - * Implementation of connect_manager_t.set_responder_data. - */ -static status_t set_responder_data(private_connect_manager_t *this, - chunk_t connect_id, chunk_t key, - linked_list_t *endpoints) +METHOD(connect_manager_t, set_responder_data, status_t, + private_connect_manager_t *this, chunk_t connect_id, chunk_t key, + linked_list_t *endpoints) { check_list_t *checklist; @@ -1551,10 +1525,8 @@ static status_t set_responder_data(private_connect_manager_t *this, return SUCCESS; } -/** - * Implementation of connect_manager_t.stop_checks. - */ -static status_t stop_checks(private_connect_manager_t *this, chunk_t connect_id) +METHOD(connect_manager_t, stop_checks, status_t, + private_connect_manager_t *this, chunk_t connect_id) { check_list_t *checklist; @@ -1578,16 +1550,16 @@ static status_t stop_checks(private_connect_manager_t *this, chunk_t connect_id) return SUCCESS; } -/** - * Implementation of connect_manager_t.destroy. - */ -static void destroy(private_connect_manager_t *this) +METHOD(connect_manager_t, destroy, void, + private_connect_manager_t *this) { this->mutex->lock(this->mutex); - this->hasher->destroy(this->hasher); - this->checklists->destroy_function(this->checklists, (void*)check_list_destroy); - this->initiated->destroy_function(this->initiated, (void*)initiated_destroy); + this->checklists->destroy_function(this->checklists, + (void*)check_list_destroy); + this->initiated->destroy_function(this->initiated, + (void*)initiated_destroy); + DESTROY_IF(this->hasher); this->mutex->unlock(this->mutex); this->mutex->destroy(this->mutex); @@ -1599,28 +1571,30 @@ static void destroy(private_connect_manager_t *this) */ connect_manager_t *connect_manager_create() { - private_connect_manager_t *this = malloc_thing(private_connect_manager_t); - - this->public.destroy = (void(*)(connect_manager_t*))destroy; - this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*))check_and_register; - this->public.check_and_initiate = (void(*)(connect_manager_t*,ike_sa_id_t*,identification_t*,identification_t*))check_and_initiate; - this->public.set_initiator_data = (status_t(*)(connect_manager_t*,identification_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))set_initiator_data; - this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data; - this->public.process_check = (void(*)(connect_manager_t*,message_t*))process_check; - this->public.stop_checks = (status_t(*)(connect_manager_t*,chunk_t))stop_checks; + private_connect_manager_t *this; + + INIT(this, + .public = { + .destroy = _destroy, + .check_and_register = _check_and_register, + .check_and_initiate = _check_and_initiate, + .set_initiator_data = _set_initiator_data, + .set_responder_data = _set_responder_data, + .process_check = _process_check, + .stop_checks = _stop_checks, + }, + .hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .checklists = linked_list_create(), + .initiated = linked_list_create(), + ); - this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); if (this->hasher == NULL) { DBG1(DBG_IKE, "unable to create connect manager, SHA1 not supported"); - free(this); + destroy(this); return NULL; } - this->checklists = linked_list_create(); - this->initiated = linked_list_create(); - - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - - return (connect_manager_t*)this; + return &this->public; } diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 2fc186fe8..07d19381d 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2008 Tobias Brunner + * Copyright (C) 2006-2012 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -208,9 +208,9 @@ struct private_ike_sa_t { linked_list_t *attributes; /** - * list of peers additional addresses, transmitted via MOBIKE + * list of peer's addresses, additional ones transmitted via MOBIKE */ - linked_list_t *additional_addresses; + linked_list_t *peer_addresses; /** * previously value of received DESTINATION_IP hash @@ -246,6 +246,11 @@ struct private_ike_sa_t { * remote host address to be used for IKE, set via MIGRATE kernel message */ host_t *remote_host; + + /** + * TRUE if we are currently reauthenticating this IKE_SA + */ + bool is_reauthenticating; }; /** @@ -349,8 +354,8 @@ METHOD(ike_sa_t, get_peer_cfg, peer_cfg_t*, METHOD(ike_sa_t, set_peer_cfg, void, private_ike_sa_t *this, peer_cfg_t *peer_cfg) { - DESTROY_IF(this->peer_cfg); peer_cfg->get_ref(peer_cfg); + DESTROY_IF(this->peer_cfg); this->peer_cfg = peer_cfg; if (this->ike_cfg == NULL) @@ -559,6 +564,10 @@ METHOD(ike_sa_t, send_dpd, status_t, job_t *job; time_t diff, delay; + if (this->state == IKE_PASSIVE) + { + return INVALID_STATE; + } delay = this->peer_cfg->get_dpd(this->peer_cfg); if (this->task_manager->busy(this->task_manager)) { @@ -615,6 +624,8 @@ METHOD(ike_sa_t, get_state, ike_sa_state_t, METHOD(ike_sa_t, set_state, void, private_ike_sa_t *this, ike_sa_state_t state) { + bool trigger_dpd = FALSE; + DBG2(DBG_IKE, "IKE_SA %s[%d] state change: %N => %N", get_name(this), this->unique_id, ike_sa_state_names, this->state, @@ -675,28 +686,20 @@ METHOD(ike_sa_t, set_state, void, lib->scheduler->schedule_job(lib->scheduler, job, t); DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t); } - - /* start DPD checks */ - if (this->peer_cfg->get_dpd(this->peer_cfg)) - { - send_dpd(this); - } + trigger_dpd = this->peer_cfg->get_dpd(this->peer_cfg); } break; } - case IKE_DELETING: - { - /* delete may fail if a packet gets lost, so set a timeout */ - job_t *job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE); - lib->scheduler->schedule_job(lib->scheduler, job, - HALF_OPEN_IKE_SA_TIMEOUT); - break; - } default: break; } charon->bus->ike_state_change(charon->bus, &this->public, state); this->state = state; + + if (trigger_dpd) + { + send_dpd(this); + } } METHOD(ike_sa_t, reset, void, @@ -768,17 +771,37 @@ METHOD(ike_sa_t, get_virtual_ip, host_t*, } } -METHOD(ike_sa_t, add_additional_address, void, +METHOD(ike_sa_t, add_peer_address, void, private_ike_sa_t *this, host_t *host) { - this->additional_addresses->insert_last(this->additional_addresses, host); + this->peer_addresses->insert_last(this->peer_addresses, host); } -METHOD(ike_sa_t, create_additional_address_iterator, iterator_t*, +METHOD(ike_sa_t, create_peer_address_enumerator, enumerator_t*, private_ike_sa_t *this) { - return this->additional_addresses->create_iterator( - this->additional_addresses, TRUE); + if (this->peer_addresses->get_count(this->peer_addresses)) + { + return this->peer_addresses->create_enumerator(this->peer_addresses); + } + /* in case we don't have MOBIKE */ + return enumerator_create_single(this->other_host, NULL); +} + +METHOD(ike_sa_t, clear_peer_addresses, void, + private_ike_sa_t *this) +{ + enumerator_t *enumerator; + host_t *host; + + enumerator = this->peer_addresses->create_enumerator(this->peer_addresses); + while (enumerator->enumerate(enumerator, (void**)&host)) + { + this->peer_addresses->remove_at(this->peer_addresses, + enumerator); + host->destroy(host); + } + enumerator->destroy(enumerator); } METHOD(ike_sa_t, has_mapping_changed, bool, @@ -857,7 +880,7 @@ METHOD(ike_sa_t, update_hosts, void, if (!other->equals(other, this->other_host)) { - /* update others adress if we are NOT NATed */ + /* update others address if we are NOT NATed */ if (force || !has_condition(this, COND_NAT_HERE)) { set_other_host(this, other->clone(other)); @@ -869,11 +892,11 @@ METHOD(ike_sa_t, update_hosts, void, /* update all associated CHILD_SAs, if required */ if (update) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (child_sa->update(child_sa, this->my_host, this->other_host, this->my_virtual_ip, @@ -884,7 +907,7 @@ METHOD(ike_sa_t, update_hosts, void, child_sa->get_spi(child_sa, TRUE)); } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } } @@ -1094,7 +1117,11 @@ METHOD(ike_sa_t, initiate, status_t, if (this->state == IKE_CREATED) { - resolve_hosts(this); + if (this->my_host->is_anyaddr(this->my_host) || + this->other_host->is_anyaddr(this->other_host)) + { + resolve_hosts(this); + } if (this->other_host->is_anyaddr(this->other_host) #ifdef ME @@ -1104,6 +1131,7 @@ METHOD(ike_sa_t, initiate, status_t, { child_cfg->destroy(child_cfg); DBG1(DBG_IKE, "unable to initiate to %%any"); + charon->bus->alert(charon->bus, ALERT_PEER_ADDR_FAILED); return DESTROY_ME; } @@ -1289,7 +1317,8 @@ METHOD(ike_sa_t, process_message, status_t, /* add a timeout if peer does not establish it completely */ job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, FALSE); lib->scheduler->schedule_job(lib->scheduler, job, - HALF_OPEN_IKE_SA_TIMEOUT); + lib->settings->get_int(lib->settings, + "charon.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT)); } this->stats[STAT_INBOUND] = time_monotonic(NULL); status = this->task_manager->process_message(this->task_manager, @@ -1376,11 +1405,11 @@ METHOD(ike_sa_t, add_child_sa, void, METHOD(ike_sa_t, get_child_sa, child_sa_t*, private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi, bool inbound) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *current, *found = NULL; - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, (void**)¤t)) { if (current->get_spi(current, inbound) == spi && current->get_protocol(current) == protocol) @@ -1388,14 +1417,26 @@ METHOD(ike_sa_t, get_child_sa, child_sa_t*, found = current; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return found; } -METHOD(ike_sa_t, create_child_sa_iterator, iterator_t*, +METHOD(ike_sa_t, get_child_count, int, + private_ike_sa_t *this) +{ + return this->child_sas->get_count(this->child_sas); +} + +METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*, private_ike_sa_t *this) { - return this->child_sas->create_iterator(this->child_sas, TRUE); + return this->child_sas->create_enumerator(this->child_sas); +} + +METHOD(ike_sa_t, remove_child_sa, void, + private_ike_sa_t *this, enumerator_t *enumerator) +{ + this->child_sas->remove_at(this->child_sas, enumerator); } METHOD(ike_sa_t, rekey_child_sa, status_t, @@ -1403,6 +1444,11 @@ METHOD(ike_sa_t, rekey_child_sa, status_t, { child_rekey_t *child_rekey; + if (this->state == IKE_PASSIVE) + { + return INVALID_STATE; + } + child_rekey = child_rekey_create(&this->public, protocol, spi); this->task_manager->queue_task(this->task_manager, &child_rekey->task); return this->task_manager->initiate(this->task_manager); @@ -1413,6 +1459,11 @@ METHOD(ike_sa_t, delete_child_sa, status_t, { child_delete_t *child_delete; + if (this->state == IKE_PASSIVE) + { + return INVALID_STATE; + } + child_delete = child_delete_create(&this->public, protocol, spi); this->task_manager->queue_task(this->task_manager, &child_delete->task); return this->task_manager->initiate(this->task_manager); @@ -1421,23 +1472,23 @@ METHOD(ike_sa_t, delete_child_sa, status_t, METHOD(ike_sa_t, destroy_child_sa, status_t, private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; status_t status = NOT_FOUND; - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (child_sa->get_protocol(child_sa) == protocol && child_sa->get_spi(child_sa, TRUE) == spi) { + this->child_sas->remove_at(this->child_sas, enumerator); child_sa->destroy(child_sa); - iterator->remove(iterator); status = SUCCESS; break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return status; } @@ -1472,6 +1523,10 @@ METHOD(ike_sa_t, rekey, status_t, { ike_rekey_t *ike_rekey; + if (this->state == IKE_PASSIVE) + { + return INVALID_STATE; + } ike_rekey = ike_rekey_create(&this->public, TRUE); this->task_manager->queue_task(this->task_manager, &ike_rekey->task); @@ -1483,6 +1538,10 @@ METHOD(ike_sa_t, reauth, status_t, { task_t *task; + if (this->state == IKE_PASSIVE) + { + return INVALID_STATE; + } /* we can't reauthenticate as responder when we use EAP or virtual IPs. * If the peer does not support RFC4478, there is no way to keep the * IKE_SA up. */ @@ -1497,17 +1556,26 @@ METHOD(ike_sa_t, reauth, status_t, #endif /* ME */ ) { - time_t now = time_monotonic(NULL); + time_t del, now; - DBG1(DBG_IKE, "IKE_SA will timeout in %V", - &now, &this->stats[STAT_DELETE]); + del = this->stats[STAT_DELETE]; + now = time_monotonic(NULL); + DBG1(DBG_IKE, "IKE_SA %s[%d] will timeout in %V", + get_name(this), this->unique_id, &now, &del); return FAILED; } else { - DBG1(DBG_IKE, "reauthenticating actively"); + DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d] actively", + get_name(this), this->unique_id); } } + else + { + DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d]", + get_name(this), this->unique_id); + } + this->is_reauthenticating = TRUE; task = (task_t*)ike_reauth_create(&this->public); this->task_manager->queue_task(this->task_manager, task); @@ -1520,45 +1588,64 @@ METHOD(ike_sa_t, reestablish, status_t, ike_sa_t *new; host_t *host; action_t action; - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; child_cfg_t *child_cfg; bool restart = FALSE; status_t status = FAILED; - /* check if we have children to keep up at all */ - iterator = create_child_sa_iterator(this); - while (iterator->iterate(iterator, (void**)&child_sa)) - { - if (this->state == IKE_DELETING) + if (this->is_reauthenticating) + { /* only reauthenticate if we have children */ + if (this->child_sas->get_count(this->child_sas) == 0 +#ifdef ME + /* allow reauth of mediation connections without CHILD_SAs */ + && !this->peer_cfg->is_mediation(this->peer_cfg) +#endif /* ME */ + ) { - action = child_sa->get_close_action(child_sa); + DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA " + "to recreate"); } else { - action = child_sa->get_dpd_action(child_sa); + restart = TRUE; } - switch (action) + } + else + { /* check if we have children to keep up at all */ + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { - case ACTION_RESTART: - restart = TRUE; - break; - case ACTION_ROUTE: - charon->traps->install(charon->traps, this->peer_cfg, - child_sa->get_config(child_sa)); - break; - default: - break; + if (this->state == IKE_DELETING) + { + action = child_sa->get_close_action(child_sa); + } + else + { + action = child_sa->get_dpd_action(child_sa); + } + switch (action) + { + case ACTION_RESTART: + restart = TRUE; + break; + case ACTION_ROUTE: + charon->traps->install(charon->traps, this->peer_cfg, + child_sa->get_config(child_sa)); + break; + default: + break; + } } - } - iterator->destroy(iterator); + enumerator->destroy(enumerator); #ifdef ME - /* mediation connections have no children, keep them up anyway */ - if (this->peer_cfg->is_mediation(this->peer_cfg)) - { - restart = TRUE; - } + /* mediation connections have no children, keep them up anyway */ + if (this->peer_cfg->is_mediation(this->peer_cfg)) + { + restart = TRUE; + } #endif /* ME */ + } if (!restart) { return FAILED; @@ -1598,16 +1685,37 @@ METHOD(ike_sa_t, reestablish, status_t, else #endif /* ME */ { - iterator = create_child_sa_iterator(this); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { - if (this->state == IKE_DELETING) + if (this->is_reauthenticating) { - action = child_sa->get_close_action(child_sa); + switch (child_sa->get_state(child_sa)) + { + case CHILD_ROUTED: + { /* move routed child directly */ + this->child_sas->remove_at(this->child_sas, enumerator); + new->add_child_sa(new, child_sa); + action = ACTION_NONE; + break; + } + default: + { /* initiate/queue all other CHILD_SAs */ + action = ACTION_RESTART; + break; + } + } } else - { - action = child_sa->get_dpd_action(child_sa); + { /* only restart CHILD_SAs that are configured accordingly */ + if (this->state == IKE_DELETING) + { + action = child_sa->get_close_action(child_sa); + } + else + { + action = child_sa->get_dpd_action(child_sa); + } } switch (action) { @@ -1626,7 +1734,7 @@ METHOD(ike_sa_t, reestablish, status_t, break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } if (status == DESTROY_ME) @@ -1680,6 +1788,10 @@ static void requeue_init_tasks(private_ike_sa_t *this) METHOD(ike_sa_t, retransmit, status_t, private_ike_sa_t *this, u_int32_t message_id) { + if (this->state == IKE_PASSIVE) + { + return INVALID_STATE; + } this->stats[STAT_OUTBOUND] = time_monotonic(NULL); if (this->task_manager->retransmit(this->task_manager, message_id) != SUCCESS) { @@ -1696,6 +1808,7 @@ METHOD(ike_sa_t, retransmit, status_t, DBG1(DBG_IKE, "peer not responding, trying again (%d/%d)", this->keyingtry + 1, tries); reset(this); + resolve_hosts(this); requeue_init_tasks(this); return this->task_manager->initiate(this->task_manager); } @@ -1704,6 +1817,12 @@ METHOD(ike_sa_t, retransmit, status_t, } case IKE_DELETING: DBG1(DBG_IKE, "proper IKE_SA delete failed, peer not responding"); + if (this->is_reauthenticating) + { + DBG1(DBG_IKE, "delete during reauthentication failed, " + "trying to reestablish IKE_SA anyway"); + reestablish(this); + } break; case IKE_REKEYING: DBG1(DBG_IKE, "rekeying IKE_SA failed, peer not responding"); @@ -1717,35 +1836,67 @@ METHOD(ike_sa_t, retransmit, status_t, return SUCCESS; } -METHOD(ike_sa_t, set_auth_lifetime, void, +METHOD(ike_sa_t, set_auth_lifetime, status_t, private_ike_sa_t *this, u_int32_t lifetime) { - u_int32_t reduction = this->peer_cfg->get_over_time(this->peer_cfg); - u_int32_t reauth_time = time_monotonic(NULL) + lifetime - reduction; + u_int32_t diff, hard, soft, now; + ike_auth_lifetime_t *task; + bool send_update; - if (lifetime < reduction) + diff = this->peer_cfg->get_over_time(this->peer_cfg); + now = time_monotonic(NULL); + hard = now + lifetime; + soft = hard - diff; + + /* check if we have to send an AUTH_LIFETIME to enforce the new lifetime. + * We send the notify in IKE_AUTH if not yet ESTABLISHED. */ + send_update = this->state == IKE_ESTABLISHED && + !has_condition(this, COND_ORIGINAL_INITIATOR) && + (this->other_virtual_ip != NULL || + has_condition(this, COND_EAP_AUTHENTICATED)); + + if (lifetime < diff) { - DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, starting reauthentication", - lifetime); - lib->processor->queue_job(lib->processor, + this->stats[STAT_REAUTH] = now; + + if (!send_update) + { + DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, " + "starting reauthentication", lifetime); + lib->processor->queue_job(lib->processor, (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE)); + } } else if (this->stats[STAT_REAUTH] == 0 || - this->stats[STAT_REAUTH] > reauth_time) + this->stats[STAT_REAUTH] > soft) { - this->stats[STAT_REAUTH] = reauth_time; - DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication" - " in %ds", lifetime, lifetime - reduction); - lib->scheduler->schedule_job(lib->scheduler, + this->stats[STAT_REAUTH] = soft; + if (!send_update) + { + DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling " + "reauthentication in %ds", lifetime, lifetime - diff); + lib->scheduler->schedule_job(lib->scheduler, (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), - lifetime - reduction); + lifetime - diff); + } } else { DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, " "reauthentication already scheduled in %ds", lifetime, this->stats[STAT_REAUTH] - time_monotonic(NULL)); + send_update = FALSE; } + /* give at least some seconds to reauthenticate */ + this->stats[STAT_DELETE] = max(hard, now + 10); + + if (send_update) + { + task = ike_auth_lifetime_create(&this->public, TRUE); + this->task_manager->queue_task(this->task_manager, &task->task); + return this->task_manager->initiate(this->task_manager); + } + return SUCCESS; } /** @@ -1776,26 +1927,21 @@ static bool is_any_path_valid(private_ike_sa_t *this) { bool valid = FALSE; enumerator_t *enumerator; - host_t *src, *addr; + host_t *src = NULL, *addr; + DBG1(DBG_IKE, "old path is not available anymore, try to find another"); - src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, - this->other_host, NULL); - if (!src) + enumerator = create_peer_address_enumerator(this); + while (enumerator->enumerate(enumerator, &addr)) { - 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 = hydra->kernel_interface->get_source_addr( + hydra->kernel_interface, addr, NULL); + if (src) { - DBG1(DBG_IKE, "looking for a route to %H ...", addr); - src = hydra->kernel_interface->get_source_addr( - hydra->kernel_interface, addr, NULL); - if (src) - { - break; - } + break; } - enumerator->destroy(enumerator); } + enumerator->destroy(enumerator); if (src) { valid = TRUE; @@ -1874,6 +2020,8 @@ METHOD(ike_sa_t, roam, status_t, return SUCCESS; } DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change"); + /* since our previous path is not valid anymore, try and find a new one */ + resolve_hosts(this); return reauth(this); } @@ -1902,6 +2050,8 @@ METHOD(ike_sa_t, inherit, void, private_ike_sa_t *other = (private_ike_sa_t*)other_public; child_sa_t *child_sa; attribute_entry_t *entry; + enumerator_t *enumerator; + auth_cfg_t *cfg; /* apply hosts and ids */ this->my_host->destroy(this->my_host); @@ -1925,6 +2075,20 @@ METHOD(ike_sa_t, inherit, void, other->other_virtual_ip = NULL; } + /* authentication information */ + enumerator = other->my_auths->create_enumerator(other->my_auths); + while (enumerator->enumerate(enumerator, &cfg)) + { + this->my_auths->insert_last(this->my_auths, cfg->clone(cfg)); + } + enumerator->destroy(enumerator); + enumerator = other->other_auths->create_enumerator(other->other_auths); + while (enumerator->enumerate(enumerator, &cfg)) + { + this->other_auths->insert_last(this->other_auths, cfg->clone(cfg)); + } + enumerator->destroy(enumerator); + /* ... and configuration attributes */ while (other->attributes->remove_last(other->attributes, (void**)&entry) == SUCCESS) @@ -2023,8 +2187,8 @@ METHOD(ike_sa_t, destroy, void, } this->other_virtual_ip->destroy(this->other_virtual_ip); } - this->additional_addresses->destroy_offset(this->additional_addresses, - offsetof(host_t, destroy)); + this->peer_addresses->destroy_offset(this->peer_addresses, + offsetof(host_t, destroy)); #ifdef ME if (this->is_mediation_server) { @@ -2101,8 +2265,9 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) .has_condition = _has_condition, .set_pending_updates = _set_pending_updates, .get_pending_updates = _get_pending_updates, - .create_additional_address_iterator = _create_additional_address_iterator, - .add_additional_address = _add_additional_address, + .create_peer_address_enumerator = _create_peer_address_enumerator, + .add_peer_address = _add_peer_address, + .clear_peer_addresses = _clear_peer_addresses, .has_mapping_changed = _has_mapping_changed, .retransmit = _retransmit, .delete = _delete_, @@ -2112,7 +2277,9 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) .get_keymat = _get_keymat, .add_child_sa = _add_child_sa, .get_child_sa = _get_child_sa, - .create_child_sa_iterator = _create_child_sa_iterator, + .get_child_count = _get_child_count, + .create_child_sa_enumerator = _create_child_sa_enumerator, + .remove_child_sa = _remove_child_sa, .rekey_child_sa = _rekey_child_sa, .delete_child_sa = _delete_child_sa, .destroy_child_sa = _destroy_child_sa, @@ -2156,13 +2323,13 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) .other_auth = auth_cfg_create(), .my_auths = linked_list_create(), .other_auths = linked_list_create(), - .task_manager = task_manager_create(&this->public), .unique_id = ++unique_id, - .additional_addresses = linked_list_create(), + .peer_addresses = linked_list_create(), .attributes = linked_list_create(), .keepalive_interval = lib->settings->get_time(lib->settings, "charon.keep_alive", KEEPALIVE_INTERVAL), ); + this->task_manager = task_manager_create(&this->public); this->my_host->set_port(this->my_host, IKEV2_UDP_PORT); return &this->public; diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 69a74d8b7..537565e89 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2008 Tobias Brunner + * Copyright (C) 2006-2012 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -97,6 +97,11 @@ enum ike_extension_t { * peer supports EAP-only authentication, draft-eronen-ipsec-ikev2-eap-auth */ EXT_EAP_ONLY_AUTHENTICATION = (1<<5), + + /** + * peer is probably a Windows 7 RAS client + */ + EXT_MS_WINDOWS = (1<<6), }; /** @@ -260,14 +265,14 @@ struct ike_sa_t { * * Returned ike_sa_id_t object is not getting cloned! * - * @return ike_sa's ike_sa_id_t + * @return ike_sa's ike_sa_id_t */ ike_sa_id_t* (*get_id) (ike_sa_t *this); /** * Get the numerical ID uniquely defining this IKE_SA. * - * @return unique ID + * @return unique ID */ u_int32_t (*get_unique_id) (ike_sa_t *this); @@ -469,14 +474,19 @@ struct ike_sa_t { * * @param host host to add to list */ - void (*add_additional_address)(ike_sa_t *this, host_t *host); + void (*add_peer_address)(ike_sa_t *this, host_t *host); /** - * Create an iterator over all additional addresses of the peer. + * Create an enumerator over all known addresses of the peer. * - * @return iterator over addresses + * @return enumerator over addresses + */ + enumerator_t* (*create_peer_address_enumerator)(ike_sa_t *this); + + /** + * Remove all known addresses of the peer. */ - iterator_t* (*create_additional_address_iterator)(ike_sa_t *this); + void (*clear_peer_addresses)(ike_sa_t *this); /** * Check if mappings have changed on a NAT for our source address. @@ -567,8 +577,8 @@ struct ike_sa_t { * * @param mediated_cfg peer_cfg of the mediated connection * @return - * - SUCCESS if initialization started - * - DESTROY_ME if initialization failed + * - SUCCESS if initialization started + * - DESTROY_ME if initialization failed */ status_t (*initiate_mediation) (ike_sa_t *this, peer_cfg_t *mediated_cfg); @@ -579,8 +589,8 @@ struct ike_sa_t { * @param other remote endpoint (gets cloned) * @param connect_id connect ID (gets cloned) * @return - * - SUCCESS if initialization started - * - DESTROY_ME if initialization failed + * - SUCCESS if initialization started + * - DESTROY_ME if initialization failed */ status_t (*initiate_mediated) (ike_sa_t *this, host_t *me, host_t *other, chunk_t connect_id); @@ -597,8 +607,8 @@ struct ike_sa_t { * @param endpoints endpoints * @param response TRUE if this is a response * @return - * - SUCCESS if relay started - * - DESTROY_ME if relay failed + * - SUCCESS if relay started + * - DESTROY_ME if relay failed */ status_t (*relay) (ike_sa_t *this, identification_t *requester, chunk_t connect_id, chunk_t connect_key, @@ -611,8 +621,8 @@ struct ike_sa_t { * * @param peer_id ID of the other peer * @return - * - SUCCESS if response started - * - DESTROY_ME if response failed + * - SUCCESS if response started + * - DESTROY_ME if response failed */ status_t (*callback) (ike_sa_t *this, identification_t *peer_id); @@ -624,8 +634,8 @@ struct ike_sa_t { * @param peer_id ID of the other peer * @param connect_id the connect ID supplied by the initiator * @return - * - SUCCESS if response started - * - DESTROY_ME if response failed + * - SUCCESS if response started + * - DESTROY_ME if response failed */ status_t (*respond) (ike_sa_t *this, identification_t *peer_id, chunk_t connect_id); @@ -643,8 +653,8 @@ struct ike_sa_t { * @param tsi source of triggering packet * @param tsr destination of triggering packet. * @return - * - SUCCESS if initialization started - * - DESTROY_ME if initialization failed + * - SUCCESS if initialization started + * - DESTROY_ME if initialization failed */ status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg, u_int32_t reqid, traffic_selector_t *tsi, @@ -658,10 +668,10 @@ struct ike_sa_t { * the IKE SA gets deleted. * * @return - * - SUCCESS if deletion is initialized - * - DESTROY_ME, if the IKE_SA is not in - * an established state and can not be - * deleted (but destroyed). + * - SUCCESS if deletion is initialized + * - DESTROY_ME, if the IKE_SA is not in + * an established state and can not be + * deleted (but destroyed). */ status_t (*delete) (ike_sa_t *this); @@ -684,13 +694,13 @@ struct ike_sa_t { * * Message processing may fail. If a critical failure occurs, * process_message() return DESTROY_ME. Then the caller must - * destroy the IKE_SA immediatly, as it is unusable. + * destroy the IKE_SA immediately, as it is unusable. * - * @param message message to process + * @param message message to process * @return - * - SUCCESS - * - FAILED - * - DESTROY_ME if this IKE_SA MUST be deleted + * - SUCCESS + * - FAILED + * - DESTROY_ME if this IKE_SA MUST be deleted */ status_t (*process_message) (ike_sa_t *this, message_t *message); @@ -700,12 +710,12 @@ struct ike_sa_t { * This method generates all payloads in the message and encrypts/signs * the packet. * - * @param message message to generate + * @param message message to generate * @param packet generated output packet * @return - * - SUCCESS - * - FAILED - * - DESTROY_ME if this IKE_SA MUST be deleted + * - SUCCESS + * - FAILED + * - DESTROY_ME if this IKE_SA MUST be deleted */ status_t (*generate_message) (ike_sa_t *this, message_t *message, packet_t **packet); @@ -715,8 +725,8 @@ struct ike_sa_t { * * @param message_id ID of the request to retransmit * @return - * - SUCCESS - * - NOT_FOUND if request doesn't have to be retransmited + * - SUCCESS + * - NOT_FOUND if request doesn't have to be retransmited */ status_t (*retransmit) (ike_sa_t *this, u_int32_t message_id); @@ -728,8 +738,8 @@ struct ike_sa_t { * other traffic was received. * * @return - * - SUCCESS - * - DESTROY_ME, if peer did not respond + * - SUCCESS + * - DESTROY_ME, if peer did not respond */ status_t (*send_dpd) (ike_sa_t *this); @@ -769,11 +779,25 @@ struct ike_sa_t { u_int32_t spi, bool inbound); /** - * Create an iterator over all CHILD_SAs. + * Get the number of CHILD_SAs. + * + * @return number of CHILD_SAs + */ + int (*get_child_count) (ike_sa_t *this); + + /** + * Create an enumerator over all CHILD_SAs. + * + * @return enumerator + */ + enumerator_t* (*create_child_sa_enumerator) (ike_sa_t *this); + + /** + * Remove the CHILD_SA the given enumerator points to from this IKE_SA. * - * @return iterator + * @param enumerator enumerator pointing to CHILD_SA */ - iterator_t* (*create_child_sa_iterator) (ike_sa_t *this); + void (*remove_child_sa) (ike_sa_t *this, enumerator_t *enumerator); /** * Rekey the CHILD SA with the specified reqid. @@ -783,8 +807,8 @@ struct ike_sa_t { * @param protocol protocol of the SA * @param spi inbound SPI of the CHILD_SA * @return - * - NOT_FOUND, if IKE_SA has no such CHILD_SA - * - SUCCESS, if rekeying initiated + * - NOT_FOUND, if IKE_SA has no such CHILD_SA + * - SUCCESS, if rekeying initiated */ status_t (*rekey_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi); @@ -798,8 +822,8 @@ struct ike_sa_t { * @param protocol protocol of the SA * @param spi inbound SPI of the CHILD_SA * @return - * - NOT_FOUND, if IKE_SA has no such CHILD_SA - * - SUCCESS, if delete message sent + * - NOT_FOUND, if IKE_SA has no such CHILD_SA + * - SUCCESS, if delete message sent */ status_t (*delete_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi); @@ -811,8 +835,8 @@ struct ike_sa_t { * @param protocol protocol of the SA * @param spi inbound SPI of the CHILD_SA * @return - * - NOT_FOUND, if IKE_SA has no such CHILD_SA - * - SUCCESS + * - NOT_FOUND, if IKE_SA has no such CHILD_SA + * - SUCCESS */ status_t (*destroy_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi); @@ -845,11 +869,15 @@ struct ike_sa_t { status_t (*reestablish) (ike_sa_t *this); /** - * Set the lifetime limit received from a AUTH_LIFETIME notify. + * Set the lifetime limit received/to send in a AUTH_LIFETIME notify. + * + * If the IKE_SA is already ESTABLISHED, an INFORMATIONAL is sent with + * an AUTH_LIFETIME notify. The call never fails on unestablished SAs. * * @param lifetime lifetime in seconds + * @return DESTROY_ME to destroy the IKE_SA */ - void (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime); + status_t (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime); /** * Set the virtual IP to use for this IKE_SA and its children. @@ -929,8 +957,8 @@ struct ike_sa_t { /** * Creates an ike_sa_t object with a specific ID. * - * @param ike_sa_id ike_sa_id_t object to associate with new IKE_SA - * @return ike_sa_t object + * @param ike_sa_id ike_sa_id_t object to associate with new IKE_SA + * @return ike_sa_t object */ ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id); diff --git a/src/libcharon/sa/ike_sa_id.c b/src/libcharon/sa/ike_sa_id.c index 94c5405f2..bea4c2124 100644 --- a/src/libcharon/sa/ike_sa_id.c +++ b/src/libcharon/sa/ike_sa_id.c @@ -46,42 +46,32 @@ struct private_ike_sa_id_t { bool is_initiator_flag; }; -/** - * Implementation of ike_sa_id_t.set_responder_spi. - */ -static void set_responder_spi (private_ike_sa_id_t *this, u_int64_t responder_spi) +METHOD(ike_sa_id_t, set_responder_spi, void, + private_ike_sa_id_t *this, u_int64_t responder_spi) { this->responder_spi = responder_spi; } -/** - * Implementation of ike_sa_id_t.set_initiator_spi. - */ -static void set_initiator_spi(private_ike_sa_id_t *this, u_int64_t initiator_spi) +METHOD(ike_sa_id_t, set_initiator_spi, void, + private_ike_sa_id_t *this, u_int64_t initiator_spi) { this->initiator_spi = initiator_spi; } -/** - * Implementation of ike_sa_id_t.get_initiator_spi. - */ -static u_int64_t get_initiator_spi (private_ike_sa_id_t *this) +METHOD(ike_sa_id_t, get_initiator_spi, u_int64_t, + private_ike_sa_id_t *this) { return this->initiator_spi; } -/** - * Implementation of ike_sa_id_t.get_responder_spi. - */ -static u_int64_t get_responder_spi (private_ike_sa_id_t *this) +METHOD(ike_sa_id_t, get_responder_spi, u_int64_t, + private_ike_sa_id_t *this) { return this->responder_spi; } -/** - * Implementation of ike_sa_id_t.equals. - */ -static bool equals (private_ike_sa_id_t *this, private_ike_sa_id_t *other) +METHOD(ike_sa_id_t, equals, bool, + private_ike_sa_id_t *this, private_ike_sa_id_t *other) { if (other == NULL) { @@ -101,28 +91,22 @@ static bool equals (private_ike_sa_id_t *this, private_ike_sa_id_t *other) } } -/** - * Implementation of ike_sa_id_t.replace_values. - */ -static void replace_values(private_ike_sa_id_t *this, private_ike_sa_id_t *other) +METHOD(ike_sa_id_t, replace_values, void, + private_ike_sa_id_t *this, private_ike_sa_id_t *other) { this->initiator_spi = other->initiator_spi; this->responder_spi = other->responder_spi; this->is_initiator_flag = other->is_initiator_flag; } -/** - * Implementation of ike_sa_id_t.is_initiator. - */ -static bool is_initiator(private_ike_sa_id_t *this) +METHOD(ike_sa_id_t, is_initiator, bool, + private_ike_sa_id_t *this) { return this->is_initiator_flag; } -/** - * Implementation of ike_sa_id_t.switch_initiator. - */ -static bool switch_initiator(private_ike_sa_id_t *this) +METHOD(ike_sa_id_t, switch_initiator, bool, + private_ike_sa_id_t *this) { if (this->is_initiator_flag) { @@ -135,18 +119,15 @@ static bool switch_initiator(private_ike_sa_id_t *this) return this->is_initiator_flag; } -/** - * Implementation of ike_sa_id_t.clone. - */ -static ike_sa_id_t* clone_(private_ike_sa_id_t *this) +METHOD(ike_sa_id_t, clone_, ike_sa_id_t*, + private_ike_sa_id_t *this) { - return ike_sa_id_create(this->initiator_spi, this->responder_spi, this->is_initiator_flag); + return ike_sa_id_create(this->initiator_spi, this->responder_spi, + this->is_initiator_flag); } -/** - * Implementation of ike_sa_id_t.destroy. - */ -static void destroy(private_ike_sa_id_t *this) +METHOD(ike_sa_id_t, destroy, void, + private_ike_sa_id_t *this) { free(this); } @@ -154,26 +135,28 @@ static void destroy(private_ike_sa_id_t *this) /* * Described in header. */ -ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiator_flag) +ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, + bool is_initiator_flag) { - private_ike_sa_id_t *this = malloc_thing(private_ike_sa_id_t); - - /* public functions */ - this->public.set_responder_spi = (void(*)(ike_sa_id_t*,u_int64_t)) set_responder_spi; - this->public.set_initiator_spi = (void(*)(ike_sa_id_t*,u_int64_t)) set_initiator_spi; - this->public.get_responder_spi = (u_int64_t(*)(ike_sa_id_t*)) get_responder_spi; - this->public.get_initiator_spi = (u_int64_t(*)(ike_sa_id_t*)) get_initiator_spi; - this->public.equals = (bool(*)(ike_sa_id_t*,ike_sa_id_t*)) equals; - this->public.replace_values = (void(*)(ike_sa_id_t*,ike_sa_id_t*)) replace_values; - this->public.is_initiator = (bool(*)(ike_sa_id_t*)) is_initiator; - this->public.switch_initiator = (bool(*)(ike_sa_id_t*)) switch_initiator; - this->public.clone = (ike_sa_id_t*(*)(ike_sa_id_t*)) clone_; - this->public.destroy = (void(*)(ike_sa_id_t*))destroy; - - /* private data */ - this->initiator_spi = initiator_spi; - this->responder_spi = responder_spi; - this->is_initiator_flag = is_initiator_flag; + private_ike_sa_id_t *this; + + INIT(this, + .public = { + .set_responder_spi = _set_responder_spi, + .set_initiator_spi = _set_initiator_spi, + .get_responder_spi = _get_responder_spi, + .get_initiator_spi = _get_initiator_spi, + .equals = (void*)_equals, + .replace_values = (void*)_replace_values, + .is_initiator = _is_initiator, + .switch_initiator = _switch_initiator, + .clone = _clone_, + .destroy = _destroy, + }, + .initiator_spi = initiator_spi, + .responder_spi = responder_spi, + .is_initiator_flag = is_initiator_flag, + ); return &this->public; } diff --git a/src/libcharon/sa/ike_sa_id.h b/src/libcharon/sa/ike_sa_id.h index a833aa9d6..fb55359bc 100644 --- a/src/libcharon/sa/ike_sa_id.h +++ b/src/libcharon/sa/ike_sa_id.h @@ -30,7 +30,7 @@ typedef struct ike_sa_id_t ike_sa_id_t; * An object of type ike_sa_id_t is used to identify an IKE_SA. * * An IKE_SA is identified by its initiator and responder spi's. - * Additionaly it contains the role of the actual running IKEv2-Daemon + * Additionally it contains the role of the actual running IKEv2 daemon * for the specific IKE_SA (original initiator or responder). */ struct ike_sa_id_t { @@ -40,28 +40,28 @@ struct ike_sa_id_t { * * This function is called when a request or reply of a IKE_SA_INIT is received. * - * @param responder_spi SPI of responder to set + * @param responder_spi SPI of responder to set */ void (*set_responder_spi) (ike_sa_id_t *this, u_int64_t responder_spi); /** * Set the SPI of the initiator. * - * @param initiator_spi SPI to set + * @param initiator_spi SPI to set */ void (*set_initiator_spi) (ike_sa_id_t *this, u_int64_t initiator_spi); /** * Get the initiator SPI. * - * @return SPI of the initiator + * @return SPI of the initiator */ u_int64_t (*get_initiator_spi) (ike_sa_id_t *this); /** * Get the responder SPI. * - * @return SPI of the responder + * @return SPI of the responder */ u_int64_t (*get_responder_spi) (ike_sa_id_t *this); @@ -70,8 +70,8 @@ struct ike_sa_id_t { * * Two ike_sa_id_t objects are equal if both SPI values and the role matches. * - * @param other ike_sa_id_t object to check if equal - * @return TRUE if given ike_sa_id_t are equal, FALSE otherwise + * @param other ike_sa_id_t object to check if equal + * @return TRUE if given ike_sa_id_t are equal, FALSE otherwise */ bool (*equals) (ike_sa_id_t *this, ike_sa_id_t *other); @@ -81,28 +81,28 @@ struct ike_sa_id_t { * * After calling this function, both objects are equal. * - * @param other ike_sa_id_t object from which values will be taken + * @param other ike_sa_id_t object from which values will be taken */ void (*replace_values) (ike_sa_id_t *this, ike_sa_id_t *other); /** * Get the initiator flag. * - * @return TRUE if we are the original initator + * @return TRUE if we are the original initiator */ bool (*is_initiator) (ike_sa_id_t *this); /** * Switche the original initiator flag. * - * @return TRUE if we are the original initator after switch, FALSE otherwise + * @return TRUE if we are the original initiator after switch, FALSE otherwise */ bool (*switch_initiator) (ike_sa_id_t *this); /** * Clones a given ike_sa_id_t object. * - * @return cloned ike_sa_id_t object + * @return cloned ike_sa_id_t object */ ike_sa_id_t *(*clone) (ike_sa_id_t *this); diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index d695c7f7c..731ae6007 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -307,72 +307,72 @@ struct private_ike_sa_manager_t { /** * Public interface of ike_sa_manager_t. */ - ike_sa_manager_t public; - - /** - * Hash table with entries for the ike_sa_t objects. - */ - linked_list_t **ike_sa_table; - - /** - * The size of the hash table. - */ - u_int table_size; - - /** - * Mask to map the hashes to table rows. - */ - u_int table_mask; - - /** - * Segments of the hash table. - */ - segment_t *segments; - - /** - * The number of segments. - */ - u_int segment_count; - - /** - * Mask to map a table row to a segment. - */ - u_int segment_mask; - - /** - * Hash table with half_open_t objects. - */ - linked_list_t **half_open_table; - - /** + ike_sa_manager_t public; + + /** + * Hash table with entries for the ike_sa_t objects. + */ + linked_list_t **ike_sa_table; + + /** + * The size of the hash table. + */ + u_int table_size; + + /** + * Mask to map the hashes to table rows. + */ + u_int table_mask; + + /** + * Segments of the hash table. + */ + segment_t *segments; + + /** + * The number of segments. + */ + u_int segment_count; + + /** + * Mask to map a table row to a segment. + */ + u_int segment_mask; + + /** + * Hash table with half_open_t objects. + */ + linked_list_t **half_open_table; + + /** * Segments of the "half-open" hash table. - */ - shareable_segment_t *half_open_segments; + */ + shareable_segment_t *half_open_segments; - /** - * Hash table with connected_peers_t objects. - */ - linked_list_t **connected_peers_table; + /** + * Hash table with connected_peers_t objects. + */ + linked_list_t **connected_peers_table; - /** - * Segments of the "connected peers" hash table. - */ - shareable_segment_t *connected_peers_segments; + /** + * Segments of the "connected peers" hash table. + */ + shareable_segment_t *connected_peers_segments; - /** - * RNG to get random SPIs for our side - */ - rng_t *rng; + /** + * RNG to get random SPIs for our side + */ + rng_t *rng; - /** - * SHA1 hasher for IKE_SA_INIT retransmit detection - */ - hasher_t *hasher; + /** + * SHA1 hasher for IKE_SA_INIT retransmit detection + */ + hasher_t *hasher; /** * reuse existing IKE_SAs in checkout_by_config */ - bool reuse_ikesa; + bool reuse_ikesa; }; /** @@ -1134,8 +1134,7 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*, private_ike_sa_manager_t *this, u_int32_t id, bool child) { - enumerator_t *enumerator; - iterator_t *children; + enumerator_t *enumerator, *children; entry_t *entry; ike_sa_t *ike_sa = NULL; child_sa_t *child_sa; @@ -1151,8 +1150,8 @@ METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*, /* look for a child with such a reqid ... */ if (child) { - children = entry->ike_sa->create_child_sa_iterator(entry->ike_sa); - while (children->iterate(children, (void**)&child_sa)) + children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa); + while (children->enumerate(children, (void**)&child_sa)) { if (child_sa->get_reqid(child_sa) == id) { @@ -1188,8 +1187,7 @@ METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*, METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*, private_ike_sa_manager_t *this, char *name, bool child) { - enumerator_t *enumerator; - iterator_t *children; + enumerator_t *enumerator, *children; entry_t *entry; ike_sa_t *ike_sa = NULL; child_sa_t *child_sa; @@ -1203,8 +1201,8 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*, /* look for a child with such a policy name ... */ if (child) { - children = entry->ike_sa->create_child_sa_iterator(entry->ike_sa); - while (children->iterate(children, (void**)&child_sa)) + children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa); + while (children->enumerate(children, (void**)&child_sa)) { if (streq(child_sa->get_name(child_sa), name)) { @@ -1238,10 +1236,10 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*, } /** - * enumerator filter function + * enumerator filter function, waiting variant */ -static bool enumerator_filter(private_ike_sa_manager_t *this, - entry_t **in, ike_sa_t **out, u_int *segment) +static bool enumerator_filter_wait(private_ike_sa_manager_t *this, + entry_t **in, ike_sa_t **out, u_int *segment) { if (wait_for_entry(this, *in, *segment)) { @@ -1251,11 +1249,28 @@ static bool enumerator_filter(private_ike_sa_manager_t *this, return FALSE; } +/** + * enumerator filter function, skipping variant + */ +static bool enumerator_filter_skip(private_ike_sa_manager_t *this, + entry_t **in, ike_sa_t **out, u_int *segment) +{ + if (!(*in)->driveout_new_threads && + !(*in)->driveout_waiting_threads && + !(*in)->checked_out) + { + *out = (*in)->ike_sa; + return TRUE; + } + return FALSE; +} + METHOD(ike_sa_manager_t, create_enumerator, enumerator_t*, - private_ike_sa_manager_t* this) + private_ike_sa_manager_t* this, bool wait) { return enumerator_create_filter(create_table_enumerator(this), - (void*)enumerator_filter, this, NULL); + wait ? (void*)enumerator_filter_wait : (void*)enumerator_filter_skip, + this, NULL); } METHOD(ike_sa_manager_t, checkin, void, @@ -1539,14 +1554,30 @@ METHOD(ike_sa_manager_t, has_contact, bool, return found; } -METHOD(ike_sa_manager_t, get_half_open_count, int, +METHOD(ike_sa_manager_t, get_count, u_int, + private_ike_sa_manager_t *this) +{ + u_int segment, count = 0; + mutex_t *mutex; + + for (segment = 0; segment < this->segment_count; segment++) + { + mutex = this->segments[segment & this->segment_mask].mutex; + mutex->lock(mutex); + count += this->segments[segment].count; + mutex->unlock(mutex); + } + return count; +} + +METHOD(ike_sa_manager_t, get_half_open_count, u_int, private_ike_sa_manager_t *this, host_t *ip) { linked_list_t *list; u_int segment, row; rwlock_t *lock; chunk_t addr; - int count = 0; + u_int count = 0; if (ip) { @@ -1728,6 +1759,7 @@ ike_sa_manager_t *ike_sa_manager_create() .create_enumerator = _create_enumerator, .checkin = _checkin, .checkin_and_destroy = _checkin_and_destroy, + .get_count = _get_count, .get_half_open_count = _get_half_open_count, .flush = _flush, .destroy = _destroy, diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h index ec157ab3a..5e542e7df 100644 --- a/src/libcharon/sa/ike_sa_manager.h +++ b/src/libcharon/sa/ike_sa_manager.h @@ -162,9 +162,10 @@ struct ike_sa_manager_t { * While enumerating an IKE_SA, it is temporarily checked out and * automatically checked in after the current enumeration step. * + * @param wait TRUE to wait for checked out SAs, FALSE to skip * @return enumerator over all IKE_SAs. */ - enumerator_t *(*create_enumerator) (ike_sa_manager_t* this); + enumerator_t *(*create_enumerator) (ike_sa_manager_t* this, bool wait); /** * Checkin the SA after usage. @@ -191,6 +192,13 @@ struct ike_sa_manager_t { void (*checkin_and_destroy) (ike_sa_manager_t* this, ike_sa_t *ike_sa); /** + * Get the number of IKE_SAs currently registered. + * + * @return number of registered IKE_SAs + */ + u_int (*get_count)(ike_sa_manager_t *this); + + /** * Get the number of IKE_SAs which are in the connecting state. * * To prevent the server from resource exhaustion, cookies and other @@ -203,7 +211,7 @@ struct ike_sa_manager_t { * @param ip NULL for all, IP for half open IKE_SAs with IP * @return number of half open IKE_SAs */ - int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip); + u_int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip); /** * Delete all existing IKE_SAs and destroy them immediately. diff --git a/src/libcharon/sa/keymat.c b/src/libcharon/sa/keymat.c index 33ece24b2..d762fa34e 100644 --- a/src/libcharon/sa/keymat.c +++ b/src/libcharon/sa/keymat.c @@ -99,7 +99,9 @@ keylen_entry_t keylen_enc[] = { */ keylen_entry_t keylen_int[] = { {AUTH_HMAC_MD5_96, 128}, + {AUTH_HMAC_MD5_128, 128}, {AUTH_HMAC_SHA1_96, 160}, + {AUTH_HMAC_SHA1_160, 160}, {AUTH_HMAC_SHA2_256_96, 256}, {AUTH_HMAC_SHA2_256_128, 256}, {AUTH_HMAC_SHA2_384_192, 384}, diff --git a/src/libcharon/sa/keymat.h b/src/libcharon/sa/keymat.h index 11e0fa79a..6c2b5d4b5 100644 --- a/src/libcharon/sa/keymat.h +++ b/src/libcharon/sa/keymat.h @@ -40,7 +40,12 @@ struct keymat_t { * * The diffie hellman is either for IKE negotiation/rekeying or * CHILD_SA rekeying (using PFS). The resulting DH object must be passed - * to derive_keys or to derive_child_keys and destroyed after use + * to derive_keys or to derive_child_keys and destroyed after use. + * + * Only DH objects allocated through this method are passed to other + * keymat_t methods, allowing private DH implementations. In some cases + * (such as retrying with a COOKIE), a DH object allocated from a different + * keymat_t instance may be passed to other methods. * * @param group diffie hellman group * @return DH object, NULL if group not supported diff --git a/src/libcharon/sa/mediation_manager.c b/src/libcharon/sa/mediation_manager.c index 2fbab7c7c..60eeb5d4b 100644 --- a/src/libcharon/sa/mediation_manager.c +++ b/src/libcharon/sa/mediation_manager.c @@ -53,13 +53,12 @@ static void peer_destroy(peer_t *this) */ static peer_t *peer_create(identification_t *id, ike_sa_id_t* ike_sa_id) { - peer_t *this = malloc_thing(peer_t); - - /* clone everything */ - this->id = id->clone(id); - this->ike_sa_id = ike_sa_id ? ike_sa_id->clone(ike_sa_id) : NULL; - this->requested_by = linked_list_create(); - + peer_t *this; + INIT(this, + .id = id->clone(id), + .ike_sa_id = ike_sa_id ? ike_sa_id->clone(ike_sa_id) : NULL, + .requested_by = linked_list_create(), + ); return this; } @@ -90,19 +89,19 @@ struct private_mediation_manager_t { */ static void register_peer(peer_t *peer, identification_t *peer_id) { - iterator_t *iterator; + enumerator_t *enumerator; identification_t *current; - iterator = peer->requested_by->create_iterator(peer->requested_by, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = peer->requested_by->create_enumerator(peer->requested_by); + while (enumerator->enumerate(enumerator, (void**)¤t)) { if (peer_id->equals(peer_id, current)) { - iterator->destroy(iterator); + enumerator->destroy(enumerator); return; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); peer->requested_by->insert_last(peer->requested_by, peer_id->clone(peer_id)); @@ -114,12 +113,12 @@ static void register_peer(peer_t *peer, identification_t *peer_id) static status_t get_peer_by_id(private_mediation_manager_t *this, identification_t *id, peer_t **peer) { - iterator_t *iterator; + enumerator_t *enumerator; peer_t *current; status_t status = NOT_FOUND; - iterator = this->peers->create_iterator(this->peers, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = this->peers->create_enumerator(this->peers); + while (enumerator->enumerate(enumerator, (void**)¤t)) { if (id->equals(id, current->id)) { @@ -131,7 +130,7 @@ static status_t get_peer_by_id(private_mediation_manager_t *this, break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return status; } @@ -144,52 +143,50 @@ static status_t get_peer_by_id(private_mediation_manager_t *this, static void unregister_peer(private_mediation_manager_t *this, identification_t *peer_id) { - iterator_t *iterator, *iterator_r; + enumerator_t *enumerator, *enumerator_r; peer_t *peer; identification_t *registered; - iterator = this->peers->create_iterator(this->peers, TRUE); - while (iterator->iterate(iterator, (void**)&peer)) + enumerator = this->peers->create_enumerator(this->peers); + while (enumerator->enumerate(enumerator, (void**)&peer)) { - iterator_r = peer->requested_by->create_iterator(peer->requested_by, - TRUE); - while (iterator_r->iterate(iterator_r, (void**)®istered)) + enumerator_r = peer->requested_by->create_enumerator(peer->requested_by); + while (enumerator_r->enumerate(enumerator_r, (void**)®istered)) { if (peer_id->equals(peer_id, registered)) { - iterator_r->remove(iterator_r); + peer->requested_by->remove_at(peer->requested_by, enumerator_r); registered->destroy(registered); break; } } - iterator_r->destroy(iterator_r); + enumerator_r->destroy(enumerator_r); - if (!peer->ike_sa_id && !peer->requested_by->get_count(peer->requested_by)) + if (!peer->ike_sa_id && + !peer->requested_by->get_count(peer->requested_by)) { - iterator->remove(iterator); + this->peers->remove_at(this->peers, enumerator); peer_destroy(peer); break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } -/** - * Implementation of mediation_manager_t.remove - */ -static void remove_sa(private_mediation_manager_t *this, ike_sa_id_t *ike_sa_id) +METHOD(mediation_manager_t, remove_sa, void, + private_mediation_manager_t *this, ike_sa_id_t *ike_sa_id) { - iterator_t *iterator; + enumerator_t *enumerator; peer_t *peer; this->mutex->lock(this->mutex); - iterator = this->peers->create_iterator(this->peers, TRUE); - while (iterator->iterate(iterator, (void**)&peer)) + enumerator = this->peers->create_enumerator(this->peers); + while (enumerator->enumerate(enumerator, (void**)&peer)) { if (ike_sa_id->equals(ike_sa_id, peer->ike_sa_id)) { - iterator->remove(iterator); + this->peers->remove_at(this->peers, enumerator); unregister_peer(this, peer->id); @@ -197,24 +194,23 @@ static void remove_sa(private_mediation_manager_t *this, ike_sa_id_t *ike_sa_id) break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); this->mutex->unlock(this->mutex); } -/** - * Implementation of mediation_manager_t.update_sa_id - */ -static void update_sa_id(private_mediation_manager_t *this, identification_t *peer_id, ike_sa_id_t *ike_sa_id) +METHOD(mediation_manager_t, update_sa_id, void, + private_mediation_manager_t *this, identification_t *peer_id, + ike_sa_id_t *ike_sa_id) { - iterator_t *iterator; + enumerator_t *enumerator; peer_t *peer; bool found = FALSE; this->mutex->lock(this->mutex); - iterator = this->peers->create_iterator(this->peers, TRUE); - while (iterator->iterate(iterator, (void**)&peer)) + enumerator = this->peers->create_enumerator(this->peers); + while (enumerator->enumerate(enumerator, (void**)&peer)) { if (peer_id->equals(peer_id, peer->id)) { @@ -223,7 +219,7 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); if (!found) { @@ -248,11 +244,8 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe this->mutex->unlock(this->mutex); } -/** - * Implementation of mediation_manager_t.check. - */ -static ike_sa_id_t *check(private_mediation_manager_t *this, - identification_t *peer_id) +METHOD(mediation_manager_t, check, ike_sa_id_t*, + private_mediation_manager_t *this, identification_t *peer_id) { peer_t *peer; ike_sa_id_t *ike_sa_id; @@ -272,11 +265,9 @@ static ike_sa_id_t *check(private_mediation_manager_t *this, return ike_sa_id; } -/** - * Implementation of mediation_manager_t.check_and_register. - */ -static ike_sa_id_t *check_and_register(private_mediation_manager_t *this, - identification_t *peer_id, identification_t *requester) +METHOD(mediation_manager_t, check_and_register, ike_sa_id_t*, + private_mediation_manager_t *this, identification_t *peer_id, + identification_t *requester) { peer_t *peer; ike_sa_id_t *ike_sa_id; @@ -307,10 +298,8 @@ static ike_sa_id_t *check_and_register(private_mediation_manager_t *this, return ike_sa_id; } -/** - * Implementation of mediation_manager_t.destroy. - */ -static void destroy(private_mediation_manager_t *this) +METHOD(mediation_manager_t, destroy, void, + private_mediation_manager_t *this) { this->mutex->lock(this->mutex); @@ -326,16 +315,18 @@ static void destroy(private_mediation_manager_t *this) */ mediation_manager_t *mediation_manager_create() { - private_mediation_manager_t *this = malloc_thing(private_mediation_manager_t); - - this->public.destroy = (void(*)(mediation_manager_t*))destroy; - this->public.remove = (void(*)(mediation_manager_t*,ike_sa_id_t*))remove_sa; - this->public.update_sa_id = (void(*)(mediation_manager_t*,identification_t*,ike_sa_id_t*))update_sa_id; - this->public.check = (ike_sa_id_t*(*)(mediation_manager_t*,identification_t*))check; - 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_TYPE_DEFAULT); - - return (mediation_manager_t*)this; + private_mediation_manager_t *this; + + INIT(this, + .public = { + .destroy = _destroy, + .remove = _remove_sa, + .update_sa_id = _update_sa_id, + .check = _check, + .check_and_register = _check_and_register, + }, + .peers = linked_list_create(), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + ); + return &this->public; } diff --git a/src/libcharon/sa/shunt_manager.c b/src/libcharon/sa/shunt_manager.c new file mode 100644 index 000000000..52b2ecd62 --- /dev/null +++ b/src/libcharon/sa/shunt_manager.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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. + */ + +#include "shunt_manager.h" + +#include <hydra.h> +#include <daemon.h> +#include <threading/rwlock.h> +#include <utils/linked_list.h> + + +typedef struct private_shunt_manager_t private_shunt_manager_t; + +/** + * Private data of an shunt_manager_t object. + */ +struct private_shunt_manager_t { + + /** + * Public shunt_manager_t interface. + */ + shunt_manager_t public; + + /** + * Installed shunts, as child_cfg_t + */ + linked_list_t *shunts; +}; + +/** + * Install in and out shunt policies in the kernel + */ +static bool install_shunt_policy(child_cfg_t *child) +{ + enumerator_t *e_my_ts, *e_other_ts; + linked_list_t *my_ts_list, *other_ts_list; + traffic_selector_t *my_ts, *other_ts; + host_t *host_any; + policy_type_t policy_type; + status_t status = SUCCESS; + ipsec_sa_cfg_t sa = { .mode = MODE_TRANSPORT }; + + policy_type = (child->get_mode(child) == MODE_PASS) ? + POLICY_PASS : POLICY_DROP; + my_ts_list = child->get_traffic_selectors(child, TRUE, NULL, NULL); + other_ts_list = child->get_traffic_selectors(child, FALSE, NULL, NULL); + host_any = host_create_any(AF_INET); + + /* enumerate pairs of traffic selectors */ + e_my_ts = my_ts_list->create_enumerator(my_ts_list); + while (e_my_ts->enumerate(e_my_ts, &my_ts)) + { + e_other_ts = other_ts_list->create_enumerator(other_ts_list); + while (e_other_ts->enumerate(e_other_ts, &other_ts)) + { + /* install out policy */ + status |= hydra->kernel_interface->add_policy( + hydra->kernel_interface, host_any, host_any, + my_ts, other_ts, POLICY_OUT, policy_type, + &sa, child->get_mark(child, FALSE), + POLICY_PRIORITY_DEFAULT); + + /* install in policy */ + status |= hydra->kernel_interface->add_policy( + hydra->kernel_interface, host_any, host_any, + other_ts, my_ts, POLICY_IN, policy_type, + &sa, child->get_mark(child, TRUE), + POLICY_PRIORITY_DEFAULT); + + /* install forward policy */ + status |= hydra->kernel_interface->add_policy( + hydra->kernel_interface, host_any, host_any, + other_ts, my_ts, POLICY_FWD, policy_type, + &sa, child->get_mark(child, TRUE), + POLICY_PRIORITY_DEFAULT); + } + e_other_ts->destroy(e_other_ts); + } + e_my_ts->destroy(e_my_ts); + + my_ts_list->destroy_offset(my_ts_list, + offsetof(traffic_selector_t, destroy)); + other_ts_list->destroy_offset(other_ts_list, + offsetof(traffic_selector_t, destroy)); + host_any->destroy(host_any); + + return status == SUCCESS; +} + +METHOD(shunt_manager_t, install, bool, + private_shunt_manager_t *this, child_cfg_t *child) +{ + enumerator_t *enumerator; + child_cfg_t *child_cfg; + bool found = FALSE; + + /* check if not already installed */ + enumerator = this->shunts->create_enumerator(this->shunts); + while (enumerator->enumerate(enumerator, &child_cfg)) + { + if (streq(child_cfg->get_name(child_cfg), child->get_name(child))) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + if (found) + { + DBG1(DBG_CFG, "shunt %N policy '%s' already installed", + ipsec_mode_names, child->get_mode(child), child->get_name(child)); + return TRUE; + } + this->shunts->insert_last(this->shunts, child->get_ref(child)); + + return install_shunt_policy(child); +} + +/** + * Uninstall in and out shunt policies in the kernel + */ +static void uninstall_shunt_policy(child_cfg_t *child) +{ + enumerator_t *e_my_ts, *e_other_ts; + linked_list_t *my_ts_list, *other_ts_list; + traffic_selector_t *my_ts, *other_ts; + status_t status = SUCCESS; + + my_ts_list = child->get_traffic_selectors(child, TRUE, NULL, NULL); + other_ts_list = child->get_traffic_selectors(child, FALSE, NULL, NULL); + + /* enumerate pairs of traffic selectors */ + e_my_ts = my_ts_list->create_enumerator(my_ts_list); + while (e_my_ts->enumerate(e_my_ts, &my_ts)) + { + e_other_ts = other_ts_list->create_enumerator(other_ts_list); + while (e_other_ts->enumerate(e_other_ts, &other_ts)) + { + /* uninstall out policy */ + status |= hydra->kernel_interface->del_policy( + hydra->kernel_interface, my_ts, other_ts, + POLICY_OUT, 0, child->get_mark(child, FALSE), + POLICY_PRIORITY_DEFAULT); + + /* uninstall in policy */ + status |= hydra->kernel_interface->del_policy( + hydra->kernel_interface, other_ts, my_ts, + POLICY_IN, 0, child->get_mark(child, TRUE), + POLICY_PRIORITY_DEFAULT); + + /* uninstall forward policy */ + status |= hydra->kernel_interface->del_policy( + hydra->kernel_interface, other_ts, my_ts, + POLICY_FWD, 0, child->get_mark(child, TRUE), + POLICY_PRIORITY_DEFAULT); + } + e_other_ts->destroy(e_other_ts); + } + e_my_ts->destroy(e_my_ts); + + my_ts_list->destroy_offset(my_ts_list, + offsetof(traffic_selector_t, destroy)); + other_ts_list->destroy_offset(other_ts_list, + offsetof(traffic_selector_t, destroy)); + + if (status != SUCCESS) + { + DBG1(DBG_CFG, "uninstalling shunt %N 'policy %s' failed", + ipsec_mode_names, child->get_mode(child), child->get_name(child)); + } +} + +METHOD(shunt_manager_t, uninstall, bool, + private_shunt_manager_t *this, char *name) +{ + enumerator_t *enumerator; + child_cfg_t *child, *found = NULL; + + enumerator = this->shunts->create_enumerator(this->shunts); + while (enumerator->enumerate(enumerator, &child)) + { + if (streq(name, child->get_name(child))) + { + this->shunts->remove_at(this->shunts, enumerator); + found = child; + break; + } + } + enumerator->destroy(enumerator); + + if (!found) + { + return FALSE; + } + uninstall_shunt_policy(child); + return TRUE; +} + +METHOD(shunt_manager_t, create_enumerator, enumerator_t*, + private_shunt_manager_t *this) +{ + return this->shunts->create_enumerator(this->shunts); +} + +METHOD(shunt_manager_t, destroy, void, + private_shunt_manager_t *this) +{ + child_cfg_t *child; + + while (this->shunts->remove_last(this->shunts, (void**)&child) == SUCCESS) + { + uninstall_shunt_policy(child); + child->destroy(child); + } + this->shunts->destroy(this->shunts); + free(this); +} + +/** + * See header + */ +shunt_manager_t *shunt_manager_create() +{ + private_shunt_manager_t *this; + + INIT(this, + .public = { + .install = _install, + .uninstall = _uninstall, + .create_enumerator = _create_enumerator, + .destroy = _destroy, + }, + .shunts = linked_list_create(), + ); + + return &this->public; +} + diff --git a/src/libcharon/sa/shunt_manager.h b/src/libcharon/sa/shunt_manager.h new file mode 100644 index 000000000..12ff08558 --- /dev/null +++ b/src/libcharon/sa/shunt_manager.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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 shunt_manager shunt_manager + * @{ @ingroup sa + */ + +#ifndef SHUNT_MANAGER_H_ +#define SHUNT_MANAGER_H_ + +#include <library.h> +#include <utils/enumerator.h> +#include <config/child_cfg.h> + +typedef struct shunt_manager_t shunt_manager_t; + +/** + * Manage PASS and DROP shunt policy excepting traffic from IPsec SAs. + */ +struct shunt_manager_t { + + /** + * Install a policy as a shunt. + * + * @param child child configuration to install as a shunt + * @return TRUE if installed successfully + */ + bool (*install)(shunt_manager_t *this, child_cfg_t *child); + + /** + * Uninstall a shunt policy. + * + * @param name name of child configuration to uninstall as a shunt + * @return TRUE if uninstalled successfully + */ + bool (*uninstall)(shunt_manager_t *this, char *name); + + /** + * Create an enumerator over all installed shunts. + * + * @return enumerator over (child_sa_t) + */ + enumerator_t* (*create_enumerator)(shunt_manager_t *this); + + /** + * Destroy a shunt_manager_t. + */ + void (*destroy)(shunt_manager_t *this); +}; + +/** + * Create a shunt_manager instance. + */ +shunt_manager_t *shunt_manager_create(); + +#endif /** SHUNT_MANAGER_H_ @}*/ diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c index f07d2e384..022a5e3d6 100644 --- a/src/libcharon/sa/task_manager.c +++ b/src/libcharon/sa/task_manager.c @@ -159,15 +159,15 @@ struct private_task_manager_t { */ static void flush(private_task_manager_t *this) { - this->queued_tasks->destroy_offset(this->queued_tasks, - offsetof(task_t, destroy)); - this->queued_tasks = linked_list_create(); this->passive_tasks->destroy_offset(this->passive_tasks, offsetof(task_t, destroy)); this->passive_tasks = linked_list_create(); this->active_tasks->destroy_offset(this->active_tasks, offsetof(task_t, destroy)); this->active_tasks = linked_list_create(); + this->queued_tasks->destroy_offset(this->queued_tasks, + offsetof(task_t, destroy)); + this->queued_tasks = linked_list_create(); } /** @@ -175,23 +175,23 @@ static void flush(private_task_manager_t *this) */ static bool activate_task(private_task_manager_t *this, task_type_t type) { - iterator_t *iterator; + enumerator_t *enumerator; task_t *task; bool found = FALSE; - iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE); - while (iterator->iterate(iterator, (void**)&task)) + enumerator = this->queued_tasks->create_enumerator(this->queued_tasks); + while (enumerator->enumerate(enumerator, (void**)&task)) { if (task->get_type(task) == type) { DBG2(DBG_IKE, " activating %N task", task_type_names, type); - iterator->remove(iterator); + this->queued_tasks->remove_at(this->queued_tasks, enumerator); this->active_tasks->insert_last(this->active_tasks, task); found = TRUE; break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return found; } @@ -202,14 +202,14 @@ METHOD(task_manager_t, retransmit, status_t, { u_int32_t timeout; job_t *job; - iterator_t *iterator; + enumerator_t *enumerator; packet_t *packet; task_t *task; ike_mobike_t *mobike = NULL; /* check if we are retransmitting a MOBIKE routability check */ - iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE); - while (iterator->iterate(iterator, (void*)&task)) + enumerator = this->active_tasks->create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, (void*)&task)) { if (task->get_type(task) == IKE_MOBIKE) { @@ -221,7 +221,7 @@ METHOD(task_manager_t, retransmit, status_t, break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); if (mobike == NULL) { @@ -282,7 +282,7 @@ METHOD(task_manager_t, retransmit, status_t, METHOD(task_manager_t, initiate, status_t, private_task_manager_t *this) { - iterator_t *iterator; + enumerator_t *enumerator; task_t *task; message_t *message; host_t *me, *other; @@ -366,6 +366,11 @@ METHOD(task_manager_t, initiate, status_t, exchange = INFORMATIONAL; break; } + if (activate_task(this, IKE_AUTH_LIFETIME)) + { + exchange = INFORMATIONAL; + break; + } #ifdef ME if (activate_task(this, IKE_ME)) { @@ -387,8 +392,8 @@ METHOD(task_manager_t, initiate, status_t, else { DBG2(DBG_IKE, "reinitiating already active tasks"); - iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE); - while (iterator->iterate(iterator, (void**)&task)) + enumerator = this->active_tasks->create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, (void**)&task)) { DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task)); switch (task->get_type(task)) @@ -406,12 +411,13 @@ METHOD(task_manager_t, initiate, status_t, break; case IKE_MOBIKE: exchange = INFORMATIONAL; + break; default: continue; } break; } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } if (exchange == 0) @@ -432,14 +438,14 @@ METHOD(task_manager_t, initiate, status_t, this->initiating.type = exchange; this->initiating.retransmitted = 0; - iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE); - while (iterator->iterate(iterator, (void*)&task)) + enumerator = this->active_tasks->create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, (void*)&task)) { switch (task->build(task, message)) { case SUCCESS: /* task completed, remove it */ - iterator->remove(iterator); + this->active_tasks->remove_at(this->active_tasks, enumerator); task->destroy(task); break; case NEED_MORE: @@ -454,13 +460,13 @@ METHOD(task_manager_t, initiate, status_t, /* FALL */ case DESTROY_ME: /* critical failure, destroy IKE_SA */ - iterator->destroy(iterator); + enumerator->destroy(enumerator); message->destroy(message); flush(this); return DESTROY_ME; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); /* update exchange type if a task changed it */ this->initiating.type = message->get_exchange_type(message); @@ -487,7 +493,7 @@ METHOD(task_manager_t, initiate, status_t, static status_t process_response(private_task_manager_t *this, message_t *message) { - iterator_t *iterator; + enumerator_t *enumerator; task_t *task; if (message->get_exchange_type(message) != this->initiating.type) @@ -501,14 +507,14 @@ static status_t process_response(private_task_manager_t *this, /* catch if we get resetted while processing */ this->reset = FALSE; - iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE); - while (iterator->iterate(iterator, (void*)&task)) + enumerator = this->active_tasks->create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, (void*)&task)) { switch (task->process(task, message)) { case SUCCESS: /* task completed, remove it */ - iterator->remove(iterator); + this->active_tasks->remove_at(this->active_tasks, enumerator); task->destroy(task); break; case NEED_MORE: @@ -520,19 +526,19 @@ static status_t process_response(private_task_manager_t *this, /* FALL */ case DESTROY_ME: /* critical failure, destroy IKE_SA */ - iterator->remove(iterator); - iterator->destroy(iterator); + this->active_tasks->remove_at(this->active_tasks, enumerator); + enumerator->destroy(enumerator); task->destroy(task); return DESTROY_ME; } if (this->reset) { /* start all over again if we were reset */ this->reset = FALSE; - iterator->destroy(iterator); + enumerator->destroy(enumerator); return initiate(this); } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); this->initiating.mid++; this->initiating.type = EXCHANGE_TYPE_UNDEFINED; @@ -547,7 +553,7 @@ static status_t process_response(private_task_manager_t *this, */ static bool handle_collisions(private_task_manager_t *this, task_t *task) { - iterator_t *iterator; + enumerator_t *enumerator; task_t *active; task_type_t type; @@ -558,8 +564,8 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task) type == CHILD_DELETE || type == IKE_DELETE || type == IKE_REAUTH) { /* find an exchange collision, and notify these tasks */ - iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE); - while (iterator->iterate(iterator, (void**)&active)) + enumerator = this->active_tasks->create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, (void**)&active)) { switch (active->get_type(active)) { @@ -583,10 +589,10 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task) default: continue; } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return TRUE; } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } return FALSE; } @@ -596,11 +602,11 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task) */ static status_t build_response(private_task_manager_t *this, message_t *request) { - iterator_t *iterator; + enumerator_t *enumerator; task_t *task; message_t *message; host_t *me, *other; - bool delete = FALSE; + bool delete = FALSE, hook = FALSE; status_t status; me = request->get_destination(request); @@ -614,14 +620,14 @@ static status_t build_response(private_task_manager_t *this, message_t *request) message->set_message_id(message, this->responding.mid); message->set_request(message, FALSE); - iterator = this->passive_tasks->create_iterator(this->passive_tasks, TRUE); - while (iterator->iterate(iterator, (void*)&task)) + enumerator = this->passive_tasks->create_enumerator(this->passive_tasks); + while (enumerator->enumerate(enumerator, (void*)&task)) { switch (task->build(task, message)) { case SUCCESS: /* task completed, remove it */ - iterator->remove(iterator); + this->passive_tasks->remove_at(this->passive_tasks, enumerator); if (!handle_collisions(this, task)) { task->destroy(task); @@ -631,12 +637,13 @@ static status_t build_response(private_task_manager_t *this, message_t *request) /* processed, but task needs another exchange */ if (handle_collisions(this, task)) { - iterator->remove(iterator); + this->passive_tasks->remove_at(this->passive_tasks, + enumerator); } break; case FAILED: default: - charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + hook = TRUE; /* FALL */ case DESTROY_ME: /* destroy IKE_SA, but SEND response first */ @@ -648,7 +655,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request) break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); /* remove resonder SPI if IKE_SA_INIT failed */ if (delete && request->get_exchange_type(request) == IKE_SA_INIT) @@ -673,6 +680,10 @@ static status_t build_response(private_task_manager_t *this, message_t *request) this->responding.packet->clone(this->responding.packet)); if (delete) { + if (hook) + { + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + } return DESTROY_ME; } return SUCCESS; @@ -685,7 +696,6 @@ static status_t process_request(private_task_manager_t *this, message_t *message) { enumerator_t *enumerator; - iterator_t *iterator; task_t *task = NULL; payload_t *payload; notify_payload_t *notify; @@ -854,14 +864,14 @@ static status_t process_request(private_task_manager_t *this, } /* let the tasks process the message */ - iterator = this->passive_tasks->create_iterator(this->passive_tasks, TRUE); - while (iterator->iterate(iterator, (void*)&task)) + enumerator = this->passive_tasks->create_enumerator(this->passive_tasks); + while (enumerator->enumerate(enumerator, (void*)&task)) { switch (task->process(task, message)) { case SUCCESS: /* task completed, remove it */ - iterator->remove(iterator); + this->passive_tasks->remove_at(this->passive_tasks, enumerator); task->destroy(task); break; case NEED_MORE: @@ -873,13 +883,13 @@ static status_t process_request(private_task_manager_t *this, /* FALL */ case DESTROY_ME: /* critical failure, destroy IKE_SA */ - iterator->remove(iterator); - iterator->destroy(iterator); + this->passive_tasks->remove_at(this->passive_tasks, enumerator); + enumerator->destroy(enumerator); task->destroy(task); return DESTROY_ME; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return build_response(this, message); } @@ -978,20 +988,20 @@ METHOD(task_manager_t, queue_task, void, { if (task->get_type(task) == IKE_MOBIKE) { /* there is no need to queue more than one mobike task */ - iterator_t *iterator; + enumerator_t *enumerator; task_t *current; - iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE); - while (iterator->iterate(iterator, (void**)¤t)) + enumerator = this->queued_tasks->create_enumerator(this->queued_tasks); + while (enumerator->enumerate(enumerator, (void**)¤t)) { if (current->get_type(current) == IKE_MOBIKE) { - iterator->destroy(iterator); + enumerator->destroy(enumerator); task->destroy(task); return; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task)); this->queued_tasks->insert_last(this->queued_tasks, task); diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c index fc02a334b..67c29d31f 100644 --- a/src/libcharon/sa/tasks/child_create.c +++ b/src/libcharon/sa/tasks/child_create.c @@ -213,13 +213,13 @@ static bool ts_list_is_host(linked_list_t *list, host_t *host) { traffic_selector_t *ts; bool is_host = TRUE; - iterator_t *iterator = list->create_iterator(list, TRUE); + enumerator_t *enumerator = list->create_enumerator(list); - while (is_host && iterator->iterate(iterator, (void**)&ts)) + while (is_host && enumerator->enumerate(enumerator, (void**)&ts)) { is_host = is_host && ts->is_host(ts, host); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return is_host; } @@ -886,6 +886,10 @@ static void handle_child_sa_failure(private_child_create_t *this, delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE), 100); } + else + { + DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA"); + } } METHOD(task_t, build_r, status_t, diff --git a/src/libcharon/sa/tasks/child_delete.c b/src/libcharon/sa/tasks/child_delete.c index e6834a93c..dc4b30dd3 100644 --- a/src/libcharon/sa/tasks/child_delete.c +++ b/src/libcharon/sa/tasks/child_delete.c @@ -73,11 +73,11 @@ struct private_child_delete_t { static void build_payloads(private_child_delete_t *this, message_t *message) { delete_payload_t *ah = NULL, *esp = NULL; - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { protocol_id_t protocol = child_sa->get_protocol(child_sa); u_int32_t spi = child_sa->get_spi(child_sa, TRUE); @@ -109,7 +109,7 @@ static void build_payloads(private_child_delete_t *this, message_t *message) } child_sa->set_state(child_sa, CHILD_DELETING); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } /** @@ -186,7 +186,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message) */ static status_t destroy_and_reestablish(private_child_delete_t *this) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; child_cfg_t *child_cfg; protocol_id_t protocol; @@ -194,8 +194,8 @@ static status_t destroy_and_reestablish(private_child_delete_t *this) action_t action; status_t status = SUCCESS; - iterator = this->child_sas->create_iterator(this->child_sas, TRUE); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { /* signal child down event if we are not rekeying */ if (!this->rekeyed) @@ -231,7 +231,7 @@ static status_t destroy_and_reestablish(private_child_delete_t *this) break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); return status; } @@ -240,12 +240,12 @@ static status_t destroy_and_reestablish(private_child_delete_t *this) */ static void log_children(private_child_delete_t *this) { - iterator_t *iterator; + enumerator_t *enumerator; 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)) + enumerator = this->child_sas->create_enumerator(this->child_sas); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in); child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out); @@ -258,13 +258,11 @@ static void log_children(private_child_delete_t *this) child_sa->get_traffic_selectors(child_sa, TRUE), child_sa->get_traffic_selectors(child_sa, FALSE)); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } -/** - * Implementation of task_t.build for initiator - */ -static status_t build_i(private_child_delete_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_child_delete_t *this, message_t *message) { child_sa_t *child_sa; @@ -291,10 +289,8 @@ static status_t build_i(private_child_delete_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_child_delete_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_child_delete_t *this, message_t *message) { /* flush the list before adding new SAs */ this->child_sas->destroy(this->child_sas); @@ -305,20 +301,16 @@ static status_t process_i(private_child_delete_t *this, message_t *message) return destroy_and_reestablish(this); } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_r(private_child_delete_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_child_delete_t *this, message_t *message) { process_payloads(this, message); log_children(this); return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_child_delete_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_child_delete_t *this, message_t *message) { /* if we are rekeying, we send an empty informational */ if (this->ike_sa->get_state(this->ike_sa) != IKE_REKEYING) @@ -329,28 +321,22 @@ static status_t build_r(private_child_delete_t *this, message_t *message) return destroy_and_reestablish(this); } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_child_delete_t *this) +METHOD(task_t, get_type, task_type_t, + private_child_delete_t *this) { return CHILD_DELETE; } -/** - * Implementation of child_delete_t.get_child - */ -static child_sa_t* get_child(private_child_delete_t *this) +METHOD(child_delete_t , get_child, child_sa_t*, + private_child_delete_t *this) { child_sa_t *child_sa = NULL; this->child_sas->get_first(this->child_sas, (void**)&child_sa); return child_sa; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_child_delete_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_child_delete_t *this, ike_sa_t *ike_sa) { this->check_delete_action = FALSE; this->ike_sa = ike_sa; @@ -359,10 +345,8 @@ static void migrate(private_child_delete_t *this, ike_sa_t *ike_sa) this->child_sas = linked_list_create(); } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_child_delete_t *this) +METHOD(task_t, destroy, void, + private_child_delete_t *this) { this->child_sas->destroy(this->child_sas); free(this); @@ -374,30 +358,33 @@ static void destroy(private_child_delete_t *this) child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol, u_int32_t spi) { - private_child_delete_t *this = malloc_thing(private_child_delete_t); - - this->public.get_child = (child_sa_t*(*)(child_delete_t*))get_child; - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; - - this->ike_sa = ike_sa; - this->check_delete_action = FALSE; - this->child_sas = linked_list_create(); - this->protocol = protocol; - this->spi = spi; - this->rekeyed = FALSE; + private_child_delete_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + .get_child = _get_child, + }, + .ike_sa = ike_sa, + .child_sas = linked_list_create(), + .protocol = protocol, + .spi = spi, + ); if (protocol != PROTO_NONE) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; this->initiator = TRUE; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; this->initiator = FALSE; } return &this->public; diff --git a/src/libcharon/sa/tasks/child_rekey.c b/src/libcharon/sa/tasks/child_rekey.c index b39a5fc67..76d185590 100644 --- a/src/libcharon/sa/tasks/child_rekey.c +++ b/src/libcharon/sa/tasks/child_rekey.c @@ -128,10 +128,8 @@ static void find_child(private_child_rekey_t *this, message_t *message) } } -/** - * Implementation of task_t.build for initiator - */ -static status_t build_i(private_child_rekey_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_child_rekey_t *this, message_t *message) { notify_payload_t *notify; u_int32_t reqid; @@ -175,10 +173,8 @@ static status_t build_i(private_child_rekey_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_r(private_child_rekey_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_child_rekey_t *this, message_t *message) { /* let the CHILD_CREATE task process the message */ this->child_create->task.process(&this->child_create->task, message); @@ -188,10 +184,8 @@ static status_t process_r(private_child_rekey_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_child_rekey_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_child_rekey_t *this, message_t *message) { u_int32_t reqid; @@ -252,7 +246,10 @@ static child_sa_t *handle_collision(private_child_rekey_t *this) { /* disable close action for the redundand child */ child_sa = other->child_create->get_child(other->child_create); - child_sa->set_close_action(child_sa, ACTION_NONE); + if (child_sa) + { + child_sa->set_close_action(child_sa, ACTION_NONE); + } } } else @@ -284,10 +281,8 @@ static child_sa_t *handle_collision(private_child_rekey_t *this) return to_delete; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_child_rekey_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_child_rekey_t *this, message_t *message) { protocol_id_t protocol; u_int32_t spi; @@ -314,7 +309,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) if (message->get_payload(message, SECURITY_ASSOCIATION) == NULL) { /* establishing new child failed, reuse old. but not when we - * recieved a delete in the meantime */ + * received a delete in the meantime */ if (!(this->collision && this->collision->get_type(this->collision) == CHILD_DELETE)) { @@ -364,18 +359,14 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_child_rekey_t *this) +METHOD(task_t, get_type, task_type_t, + private_child_rekey_t *this) { return CHILD_REKEY; } -/** - * Implementation of child_rekey_t.collide - */ -static void collide(private_child_rekey_t *this, task_t *other) +METHOD(child_rekey_t, collide, void, + private_child_rekey_t *this, task_t *other) { /* the task manager only detects exchange collision, but not if * the collision is for the same child. we check it here. */ @@ -418,10 +409,8 @@ static void collide(private_child_rekey_t *this, task_t *other) this->collision = other; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_child_rekey_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_child_rekey_t *this, ike_sa_t *ike_sa) { if (this->child_create) { @@ -437,10 +426,8 @@ static void migrate(private_child_rekey_t *this, ike_sa_t *ike_sa) this->collision = NULL; } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_child_rekey_t *this) +METHOD(task_t, destroy, void, + private_child_rekey_t *this) { if (this->child_create) { @@ -460,34 +447,36 @@ static void destroy(private_child_rekey_t *this) child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol, u_int32_t spi) { - private_child_rekey_t *this = malloc_thing(private_child_rekey_t); - - this->public.collide = (void (*)(child_rekey_t*,task_t*))collide; - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_child_rekey_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + .collide = _collide, + }, + .ike_sa = ike_sa, + .protocol = protocol, + .spi = spi, + ); + if (protocol != PROTO_NONE) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; this->initiator = TRUE; this->child_create = NULL; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; this->initiator = FALSE; this->child_create = child_create_create(ike_sa, NULL, TRUE, NULL, NULL); } - this->ike_sa = ike_sa; - this->child_sa = NULL; - this->protocol = protocol; - this->spi = spi; - this->collision = NULL; - this->child_delete = NULL; - this->other_child_destroyed = FALSE; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_auth.c b/src/libcharon/sa/tasks/ike_auth.c index 0756c7d60..665468fe8 100644 --- a/src/libcharon/sa/tasks/ike_auth.c +++ b/src/libcharon/sa/tasks/ike_auth.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -417,10 +418,14 @@ METHOD(task_t, build_i, status_t, cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE); idi = cfg->get(cfg, AUTH_RULE_IDENTITY); - if (!idi) - { - DBG1(DBG_CFG, "configuration misses IDi"); - return FAILED; + if (!idi || idi->get_type(idi) == ID_ANY) + { /* ID_ANY is invalid as IDi, use local IP address instead */ + host_t *me; + + DBG1(DBG_CFG, "no IDi configured, fall back on IP address"); + me = this->ike_sa->get_my_host(this->ike_sa); + idi = identification_create_from_sockaddr(me->get_sockaddr(me)); + cfg->add(cfg, AUTH_RULE_IDENTITY, idi); } this->ike_sa->set_my_id(this->ike_sa, idi->clone(idi)); id_payload = id_payload_create_from_identification(ID_INITIATOR, idi); @@ -669,8 +674,7 @@ METHOD(task_t, build_r, status_t, if (this->authentication_failed || this->peer_cfg == NULL) { - message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty); - return FAILED; + goto peer_auth_failed; } if (this->my_auth == NULL && this->do_another_auth) @@ -688,11 +692,14 @@ METHOD(task_t, build_r, status_t, if (id->get_type(id) == ID_ANY) { /* no IDr received, apply configured ID */ if (!id_cfg || id_cfg->contains_wildcards(id_cfg)) - { - DBG1(DBG_CFG, "IDr not configured and negotiation failed"); - message->add_notify(message, TRUE, AUTHENTICATION_FAILED, - chunk_empty); - return FAILED; + { /* no ID configured, use local IP address */ + host_t *me; + + DBG1(DBG_CFG, "no IDr configured, fall back on IP address"); + me = this->ike_sa->get_my_host(this->ike_sa); + id_cfg = identification_create_from_sockaddr( + me->get_sockaddr(me)); + cfg->add(cfg, AUTH_RULE_IDENTITY, id_cfg); } this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg)); id = id_cfg; @@ -702,9 +709,7 @@ METHOD(task_t, build_r, status_t, if (id_cfg && !id->matches(id, id_cfg)) { DBG1(DBG_CFG, "received IDr %Y, but require %Y", id, id_cfg); - message->add_notify(message, TRUE, AUTHENTICATION_FAILED, - chunk_empty); - return FAILED; + goto peer_auth_failed; } } @@ -726,9 +731,7 @@ METHOD(task_t, build_r, status_t, { DBG1(DBG_IKE, "configured EAP-only authentication, but peer " "does not support it"); - message->add_notify(message, TRUE, AUTHENTICATION_FAILED, - chunk_empty); - return FAILED; + goto peer_auth_failed; } } else @@ -741,9 +744,7 @@ METHOD(task_t, build_r, status_t, this->reserved); if (!this->my_auth) { - message->add_notify(message, TRUE, AUTHENTICATION_FAILED, - chunk_empty); - return FAILED; + goto peer_auth_failed; } } } @@ -759,12 +760,11 @@ METHOD(task_t, build_r, status_t, case NEED_MORE: break; default: - if (!message->get_payload(message, EXTENSIBLE_AUTHENTICATION)) + if (message->get_payload(message, EXTENSIBLE_AUTHENTICATION)) { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */ - message->add_notify(message, TRUE, AUTHENTICATION_FAILED, - chunk_empty); + goto peer_auth_failed_no_notify; } - return FAILED; + goto peer_auth_failed; } } if (this->my_auth) @@ -802,7 +802,7 @@ METHOD(task_t, build_r, status_t, if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager, this->ike_sa, FALSE)) { - DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy"); + DBG1(DBG_IKE, "cancelling IKE_SA setup due to uniqueness policy"); message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty); return FAILED; @@ -810,9 +810,7 @@ METHOD(task_t, build_r, status_t, if (!charon->bus->authorize(charon->bus, TRUE)) { DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling"); - message->add_notify(message, TRUE, AUTHENTICATION_FAILED, - chunk_empty); - return FAILED; + goto peer_auth_failed; } DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]", this->ike_sa->get_name(this->ike_sa), @@ -826,6 +824,13 @@ METHOD(task_t, build_r, status_t, return SUCCESS; } return NEED_MORE; + +peer_auth_failed: + message->add_notify(message, TRUE, AUTHENTICATION_FAILED, + chunk_empty); +peer_auth_failed_no_notify: + charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED); + return FAILED; } METHOD(task_t, process_i, status_t, @@ -908,7 +913,7 @@ METHOD(task_t, process_i, status_t, if (!id_payload) { DBG1(DBG_IKE, "IDr payload missing"); - return FAILED; + goto peer_auth_failed; } id = id_payload->get_identification(id_payload); get_reserved_id_bytes(this, id_payload); @@ -926,7 +931,7 @@ METHOD(task_t, process_i, status_t, this->reserved); if (!this->other_auth) { - return FAILED; + goto peer_auth_failed; } } else @@ -944,7 +949,7 @@ METHOD(task_t, process_i, status_t, case NEED_MORE: return NEED_MORE; default: - return FAILED; + goto peer_auth_failed; } this->other_auth->destroy(this->other_auth); this->other_auth = NULL; @@ -953,7 +958,7 @@ METHOD(task_t, process_i, status_t, if (!charon->bus->authorize(charon->bus, FALSE)) { DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling"); - return FAILED; + goto peer_auth_failed; } /* store authentication information, reset authenticator */ @@ -986,7 +991,7 @@ METHOD(task_t, process_i, status_t, if (!this->my_auth || !this->my_auth->is_mutual(this->my_auth)) { DBG1(DBG_IKE, "do not allow non-mutual EAP-only authentication"); - return FAILED; + goto peer_auth_failed; } DBG1(DBG_IKE, "allow mutual EAP-only authentication"); } @@ -999,12 +1004,13 @@ METHOD(task_t, process_i, status_t, { if (!update_cfg_candidates(this, TRUE)) { - return FAILED; + goto peer_auth_failed; } if (!charon->bus->authorize(charon->bus, TRUE)) { - DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling"); - return FAILED; + DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, " + "cancelling"); + goto peer_auth_failed; } DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]", this->ike_sa->get_name(this->ike_sa), @@ -1018,6 +1024,10 @@ METHOD(task_t, process_i, status_t, return SUCCESS; } return NEED_MORE; + +peer_auth_failed: + charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED); + return FAILED; } METHOD(task_t, get_type, task_type_t, diff --git a/src/libcharon/sa/tasks/ike_auth.h b/src/libcharon/sa/tasks/ike_auth.h index bba46d961..132907941 100644 --- a/src/libcharon/sa/tasks/ike_auth.h +++ b/src/libcharon/sa/tasks/ike_auth.h @@ -49,7 +49,7 @@ struct ike_auth_t { * Create a new task of type IKE_AUTHENTICATE. * * @param ike_sa IKE_SA this task works for - * @param initiator TRUE if thask is the initator of an exchange + * @param initiator TRUE if task is the initiator of an exchange * @return ike_auth task to handle by the task_manager */ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator); diff --git a/src/libcharon/sa/tasks/ike_auth_lifetime.c b/src/libcharon/sa/tasks/ike_auth_lifetime.c index 75ff35168..a57cfd075 100644 --- a/src/libcharon/sa/tasks/ike_auth_lifetime.c +++ b/src/libcharon/sa/tasks/ike_auth_lifetime.c @@ -75,10 +75,8 @@ static void process_payloads(private_ike_auth_lifetime_t *this, message_t *messa } } -/** - * Implementation of task_t.process for initiator - */ -static status_t build_i(private_ike_auth_lifetime_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_auth_lifetime_t *this, message_t *message) { if (message->get_exchange_type(message) == INFORMATIONAL) { @@ -88,10 +86,8 @@ static status_t build_i(private_ike_auth_lifetime_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_auth_lifetime_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_auth_lifetime_t *this, message_t *message) { if (message->get_exchange_type(message) == INFORMATIONAL) { @@ -101,10 +97,8 @@ static status_t process_r(private_ike_auth_lifetime_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_auth_lifetime_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_auth_lifetime_t *this, message_t *message) { if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) @@ -115,10 +109,8 @@ static status_t build_r(private_ike_auth_lifetime_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_auth_lifetime_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_auth_lifetime_t *this, message_t *message) { if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) @@ -129,26 +121,20 @@ static status_t process_i(private_ike_auth_lifetime_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_auth_lifetime_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_auth_lifetime_t *this) { return IKE_AUTH_LIFETIME; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_auth_lifetime_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_auth_lifetime_t *this, ike_sa_t *ike_sa) { this->ike_sa = ike_sa; } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_auth_lifetime_t *this) +METHOD(task_t, destroy, void, + private_ike_auth_lifetime_t *this) { free(this); } @@ -158,25 +144,30 @@ static void destroy(private_ike_auth_lifetime_t *this) */ ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_auth_lifetime_t *this = malloc_thing(private_ike_auth_lifetime_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_ike_auth_lifetime_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + ); if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } - this->ike_sa = ike_sa; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_cert_post.c b/src/libcharon/sa/tasks/ike_cert_post.c index cc810a49a..94af50eae 100644 --- a/src/libcharon/sa/tasks/ike_cert_post.c +++ b/src/libcharon/sa/tasks/ike_cert_post.c @@ -87,6 +87,7 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, if (enumerator->enumerate(enumerator, &url)) { payload = cert_payload_create_from_hash_and_url(hash, url); + DBG1(DBG_IKE, "sending hash-and-url \"%s\"", url); } else { @@ -167,28 +168,22 @@ static void build_certs(private_ike_cert_post_t *this, message_t *message) } } -/** - * Implementation of task_t.process for initiator - */ -static status_t build_i(private_ike_cert_post_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_cert_post_t *this, message_t *message) { build_certs(this, message); return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_cert_post_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_cert_post_t *this, message_t *message) { return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_cert_post_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_cert_post_t *this, message_t *message) { build_certs(this, message); @@ -199,10 +194,8 @@ static status_t build_r(private_ike_cert_post_t *this, message_t *message) return SUCCESS; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_cert_post_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_cert_post_t *this, message_t *message) { if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED) { /* stay alive, we might have additional rounds with CERTS */ @@ -211,26 +204,20 @@ static status_t process_i(private_ike_cert_post_t *this, message_t *message) return SUCCESS; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_cert_post_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_cert_post_t *this) { return IKE_CERT_POST; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_cert_post_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_cert_post_t *this, ike_sa_t *ike_sa) { this->ike_sa = ike_sa; } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_cert_post_t *this) +METHOD(task_t, destroy, void, + private_ike_cert_post_t *this) { free(this); } @@ -240,26 +227,31 @@ static void destroy(private_ike_cert_post_t *this) */ ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_cert_post_t *this = malloc_thing(private_ike_cert_post_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_ike_cert_post_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .initiator = initiator, + ); if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } - this->ike_sa = ike_sa; - this->initiator = initiator; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_cert_post.h b/src/libcharon/sa/tasks/ike_cert_post.h index a21f45927..b3881a01a 100644 --- a/src/libcharon/sa/tasks/ike_cert_post.h +++ b/src/libcharon/sa/tasks/ike_cert_post.h @@ -45,7 +45,7 @@ struct ike_cert_post_t { * of the certificate request. * * @param ike_sa IKE_SA this task works for - * @param initiator TRUE if thask is the original initator + * @param initiator TRUE if task is the original initiator * @return ike_cert_post task to handle by the task_manager */ ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator); diff --git a/src/libcharon/sa/tasks/ike_cert_pre.c b/src/libcharon/sa/tasks/ike_cert_pre.c index a59b8dcce..b33aebe46 100644 --- a/src/libcharon/sa/tasks/ike_cert_pre.c +++ b/src/libcharon/sa/tasks/ike_cert_pre.c @@ -51,7 +51,7 @@ struct private_ike_cert_pre_t { bool do_http_lookup; /** - * wheter this is the final authentication round + * whether this is the final authentication round */ bool final; }; @@ -424,10 +424,8 @@ static bool final_auth(message_t *message) return TRUE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t build_i(private_ike_cert_pre_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_cert_pre_t *this, message_t *message) { if (message->get_message_id(message) == 1) { /* initiator sends CERTREQs in first IKE_AUTH */ @@ -436,10 +434,8 @@ static status_t build_i(private_ike_cert_pre_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_cert_pre_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_cert_pre_t *this, message_t *message) { if (message->get_exchange_type(message) != IKE_SA_INIT) { /* handle certreqs/certs in any IKE_AUTH, just in case */ @@ -450,10 +446,8 @@ static status_t process_r(private_ike_cert_pre_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_cert_pre_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_cert_pre_t *this, message_t *message) { if (message->get_exchange_type(message) == IKE_SA_INIT) { @@ -466,10 +460,8 @@ static status_t build_r(private_ike_cert_pre_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_cert_pre_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_cert_pre_t *this, message_t *message) { if (message->get_exchange_type(message) == IKE_SA_INIT) { @@ -484,26 +476,20 @@ static status_t process_i(private_ike_cert_pre_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_cert_pre_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_cert_pre_t *this) { return IKE_CERT_PRE; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_cert_pre_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_cert_pre_t *this, ike_sa_t *ike_sa) { this->ike_sa = ike_sa; } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_cert_pre_t *this) +METHOD(task_t, destroy, void, + private_ike_cert_pre_t *this) { free(this); } @@ -513,27 +499,30 @@ static void destroy(private_ike_cert_pre_t *this) */ ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_cert_pre_t *this = malloc_thing(private_ike_cert_pre_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_ike_cert_pre_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .initiator = initiator, + ); if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } - this->ike_sa = ike_sa; - this->initiator = initiator; - this->do_http_lookup = FALSE; - this->final = FALSE; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_cert_pre.h b/src/libcharon/sa/tasks/ike_cert_pre.h index 1541b80e5..4b2d0d470 100644 --- a/src/libcharon/sa/tasks/ike_cert_pre.h +++ b/src/libcharon/sa/tasks/ike_cert_pre.h @@ -45,7 +45,7 @@ struct ike_cert_pre_t { * of the certificate request. * * @param ike_sa IKE_SA this task works for - * @param initiator TRUE if thask is the original initator + * @param initiator TRUE if task is the original initiator * @return ike_cert_pre task to handle by the task_manager */ ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator); diff --git a/src/libcharon/sa/tasks/ike_config.c b/src/libcharon/sa/tasks/ike_config.c index a61663c48..4ef9c56a5 100644 --- a/src/libcharon/sa/tasks/ike_config.c +++ b/src/libcharon/sa/tasks/ike_config.c @@ -174,6 +174,11 @@ static void process_attribute(private_ike_config_t *this, } break; } + case INTERNAL_IP4_SERVER: + case INTERNAL_IP6_SERVER: + /* assume it's a Windows client if we see proprietary attributes */ + this->ike_sa->enable_extension(this->ike_sa, EXT_MS_WINDOWS); + /* fall */ default: { if (this->initiator) @@ -225,10 +230,8 @@ static void process_payloads(private_ike_config_t *this, message_t *message) enumerator->destroy(enumerator); } -/** - * Implementation of task_t.process for initiator - */ -static status_t build_i(private_ike_config_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_config_t *this, message_t *message) { if (message->get_message_id(message) == 1) { /* in first IKE_AUTH only */ @@ -287,10 +290,8 @@ static status_t build_i(private_ike_config_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_config_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_config_t *this, message_t *message) { if (message->get_message_id(message) == 1) { /* in first IKE_AUTH only */ @@ -299,10 +300,8 @@ static status_t process_r(private_ike_config_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_config_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_config_t *this, message_t *message) { if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) { /* in last IKE_AUTH exchange */ @@ -366,10 +365,8 @@ static status_t build_r(private_ike_config_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_config_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_config_t *this, message_t *message) { if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) { /* in last IKE_AUTH exchange */ @@ -385,18 +382,14 @@ static status_t process_i(private_ike_config_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_config_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_config_t *this) { return IKE_CONFIG; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_config_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_config_t *this, ike_sa_t *ike_sa) { DESTROY_IF(this->virtual_ip); @@ -406,10 +399,8 @@ static void migrate(private_ike_config_t *this, ike_sa_t *ike_sa) this->requested = linked_list_create(); } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_config_t *this) +METHOD(task_t, destroy, void, + private_ike_config_t *this) { DESTROY_IF(this->virtual_ip); this->requested->destroy_function(this->requested, free); @@ -421,26 +412,30 @@ static void destroy(private_ike_config_t *this) */ ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_config_t *this = malloc_thing(private_ike_config_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; - - this->initiator = initiator; - this->ike_sa = ike_sa; - this->virtual_ip = NULL; - this->requested = linked_list_create(); + private_ike_config_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + }, + .initiator = initiator, + .ike_sa = ike_sa, + .requested = linked_list_create(), + ); if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } return &this->public; diff --git a/src/libcharon/sa/tasks/ike_delete.c b/src/libcharon/sa/tasks/ike_delete.c index 130948836..d79674fe4 100644 --- a/src/libcharon/sa/tasks/ike_delete.c +++ b/src/libcharon/sa/tasks/ike_delete.c @@ -52,10 +52,8 @@ struct private_ike_delete_t { bool simultaneous; }; -/** - * Implementation of task_t.build for initiator - */ -static status_t build_i(private_ike_delete_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_delete_t *this, message_t *message) { delete_payload_t *delete_payload; @@ -83,10 +81,8 @@ static status_t build_i(private_ike_delete_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_delete_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_delete_t *this, message_t *message) { DBG0(DBG_IKE, "IKE_SA deleted"); if (!this->rekeyed) @@ -97,10 +93,8 @@ static status_t process_i(private_ike_delete_t *this, message_t *message) return DESTROY_ME; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_delete_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_delete_t *this, message_t *message) { /* we don't even scan the payloads, as the message wouldn't have * come so far without being correct */ @@ -134,16 +128,14 @@ static status_t process_r(private_ike_delete_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_delete_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_delete_t *this, message_t *message) { DBG0(DBG_IKE, "IKE_SA deleted"); if (this->simultaneous) { - /* wait for peer's response for our delete request, but set a timeout */ + /* wait for peer's response for our delete request */ return SUCCESS; } if (!this->rekeyed) @@ -154,27 +146,21 @@ static status_t build_r(private_ike_delete_t *this, message_t *message) return DESTROY_ME; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_delete_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_delete_t *this) { return IKE_DELETE; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_delete_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_delete_t *this, ike_sa_t *ike_sa) { this->ike_sa = ike_sa; this->simultaneous = FALSE; } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_delete_t *this) +METHOD(task_t, destroy, void, + private_ike_delete_t *this) { free(this); } @@ -184,27 +170,30 @@ static void destroy(private_ike_delete_t *this) */ ike_delete_t *ike_delete_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_delete_t *this = malloc_thing(private_ike_delete_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_ike_delete_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .initiator = initiator, + ); if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } - this->ike_sa = ike_sa; - this->initiator = initiator; - this->rekeyed = FALSE; - this->simultaneous = FALSE; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_dpd.c b/src/libcharon/sa/tasks/ike_dpd.c index 4c6ba7662..106eff87c 100644 --- a/src/libcharon/sa/tasks/ike_dpd.c +++ b/src/libcharon/sa/tasks/ike_dpd.c @@ -31,44 +31,33 @@ struct private_ike_dpd_t { ike_dpd_t public; }; -/** - * Implementation of task_t.build for initiator - * Implementation of task_t.process for responder - */ -static status_t return_need_more(private_ike_dpd_t *this, message_t *message) +METHOD(task_t, return_need_more, status_t, + private_ike_dpd_t *this, message_t *message) { return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - * Implementation of task_t.build for responder - */ -static status_t return_success(private_ike_dpd_t *this, message_t *message) +METHOD(task_t, return_success, status_t, + private_ike_dpd_t *this, message_t *message) { return SUCCESS; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_dpd_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_dpd_t *this) { return IKE_DPD; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_dpd_t *this, ike_sa_t *ike_sa) + +METHOD(task_t, migrate, void, + private_ike_dpd_t *this, ike_sa_t *ike_sa) { } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_dpd_t *this) +METHOD(task_t, destroy, void, + private_ike_dpd_t *this) { free(this); } @@ -78,21 +67,27 @@ static void destroy(private_ike_dpd_t *this) */ ike_dpd_t *ike_dpd_create(bool initiator) { - private_ike_dpd_t *this = malloc_thing(private_ike_dpd_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_ike_dpd_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + }, + ); if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))return_need_more; - this->public.task.process = (status_t(*)(task_t*,message_t*))return_success; + this->public.task.build = _return_need_more; + this->public.task.process = _return_success; } else { - this->public.task.build = (status_t(*)(task_t*,message_t*))return_success; - this->public.task.process = (status_t(*)(task_t*,message_t*))return_need_more; + this->public.task.build = _return_success; + this->public.task.process = _return_need_more; } return &this->public; diff --git a/src/libcharon/sa/tasks/ike_dpd.h b/src/libcharon/sa/tasks/ike_dpd.h index 36388d15b..a9f68c31c 100644 --- a/src/libcharon/sa/tasks/ike_dpd.h +++ b/src/libcharon/sa/tasks/ike_dpd.h @@ -43,7 +43,7 @@ struct ike_dpd_t { /** * Create a new ike_dpd task. * - * @param initiator TRUE if thask is the original initator + * @param initiator TRUE if task is the original initiator * @return ike_dpd task to handle by the task_manager */ ike_dpd_t *ike_dpd_create(bool initiator); diff --git a/src/libcharon/sa/tasks/ike_init.c b/src/libcharon/sa/tasks/ike_init.c index dd4a5f5c0..dd8a4b086 100644 --- a/src/libcharon/sa/tasks/ike_init.c +++ b/src/libcharon/sa/tasks/ike_init.c @@ -112,7 +112,7 @@ static void build_payloads(private_ike_init_t *this, message_t *message) linked_list_t *proposal_list; ike_sa_id_t *id; proposal_t *proposal; - iterator_t *iterator; + enumerator_t *enumerator; id = this->ike_sa->get_id(this->ike_sa); @@ -124,12 +124,12 @@ static void build_payloads(private_ike_init_t *this, message_t *message) if (this->old_sa) { /* include SPI of new IKE_SA when we are rekeying */ - iterator = proposal_list->create_iterator(proposal_list, TRUE); - while (iterator->iterate(iterator, (void**)&proposal)) + enumerator = proposal_list->create_enumerator(proposal_list); + while (enumerator->enumerate(enumerator, (void**)&proposal)) { proposal->set_spi(proposal, id->get_initiator_spi(id)); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } sa_payload = sa_payload_create_from_proposal_list(proposal_list); @@ -221,10 +221,8 @@ static void process_payloads(private_ike_init_t *this, message_t *message) enumerator->destroy(enumerator); } -/** - * Implementation of task_t.process for initiator - */ -static status_t build_i(private_ike_init_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_init_t *this, message_t *message) { rng_t *rng; @@ -287,10 +285,8 @@ static status_t build_i(private_ike_init_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_init_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_init_t *this, message_t *message) { rng_t *rng; @@ -361,10 +357,8 @@ static bool derive_keys(private_ike_init_t *this, return TRUE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_init_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_init_t *this, message_t *message) { /* check if we have everything we need */ if (this->proposal == NULL || @@ -409,10 +403,8 @@ static status_t build_r(private_ike_init_t *this, message_t *message) return SUCCESS; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_init_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_init_t *this, message_t *message) { enumerator_t *enumerator; payload_t *payload; @@ -510,34 +502,14 @@ static status_t process_i(private_ike_init_t *this, message_t *message) return SUCCESS; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_init_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_init_t *this) { return IKE_INIT; } -/** - * Implementation of task_t.get_type - */ -static chunk_t get_lower_nonce(private_ike_init_t *this) -{ - if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr, - min(this->my_nonce.len, this->other_nonce.len)) < 0) - { - return this->my_nonce; - } - else - { - return this->other_nonce; - } -} - -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_init_t *this, ike_sa_t *ike_sa) { DESTROY_IF(this->proposal); chunk_free(&this->other_nonce); @@ -545,14 +517,15 @@ static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa) this->ike_sa = ike_sa; this->keymat = ike_sa->get_keymat(ike_sa); this->proposal = NULL; - DESTROY_IF(this->dh); - this->dh = this->keymat->create_dh(this->keymat, this->dh_group); + if (this->dh && this->dh->get_dh_group(this->dh) != this->dh_group) + { /* reset DH value only if group changed (INVALID_KE_PAYLOAD) */ + this->dh->destroy(this->dh); + this->dh = this->keymat->create_dh(this->keymat, this->dh_group); + } } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_init_t *this) +METHOD(task_t, destroy, void, + private_ike_init_t *this) { DESTROY_IF(this->dh); DESTROY_IF(this->proposal); @@ -562,40 +535,53 @@ static void destroy(private_ike_init_t *this) free(this); } +METHOD(ike_init_t, get_lower_nonce, chunk_t, + private_ike_init_t *this) +{ + if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr, + min(this->my_nonce.len, this->other_nonce.len)) < 0) + { + return this->my_nonce; + } + else + { + return this->other_nonce; + } +} + /* * Described in header. */ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa) { - private_ike_init_t *this = malloc_thing(private_ike_init_t); + private_ike_init_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + .get_lower_nonce = _get_lower_nonce, + }, + .ike_sa = ike_sa, + .initiator = initiator, + .dh_group = MODP_NONE, + .keymat = ike_sa->get_keymat(ike_sa), + .old_sa = old_sa, + ); - this->public.get_lower_nonce = (chunk_t(*)(ike_init_t*))get_lower_nonce; - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } - this->ike_sa = ike_sa; - this->initiator = initiator; - this->dh_group = MODP_NONE; - this->dh = NULL; - this->keymat = ike_sa->get_keymat(ike_sa); - this->my_nonce = chunk_empty; - this->other_nonce = chunk_empty; - this->cookie = chunk_empty; - this->proposal = NULL; - this->config = NULL; - this->old_sa = old_sa; - this->retry = 0; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_init.h b/src/libcharon/sa/tasks/ike_init.h index 7bd784cff..4b7f60416 100644 --- a/src/libcharon/sa/tasks/ike_init.h +++ b/src/libcharon/sa/tasks/ike_init.h @@ -51,7 +51,7 @@ struct ike_init_t { * Create a new IKE_INIT task. * * @param ike_sa IKE_SA this task works for (new one when rekeying) - * @param initiator TRUE if thask is the original initator + * @param initiator TRUE if task is the original initiator * @param old_sa old IKE_SA when we are rekeying * @return ike_init task to handle by the task_manager */ diff --git a/src/libcharon/sa/tasks/ike_me.c b/src/libcharon/sa/tasks/ike_me.c index 1de6ae8fc..8f90efcc3 100644 --- a/src/libcharon/sa/tasks/ike_me.c +++ b/src/libcharon/sa/tasks/ike_me.c @@ -111,15 +111,15 @@ struct private_ike_me_t { */ static void add_endpoints_to_message(message_t *message, linked_list_t *endpoints) { - iterator_t *iterator; + enumerator_t *enumerator; endpoint_notify_t *endpoint; - iterator = endpoints->create_iterator(endpoints, TRUE); - while (iterator->iterate(iterator, (void**)&endpoint)) + enumerator = endpoints->create_enumerator(endpoints); + while (enumerator->enumerate(enumerator, (void**)&endpoint)) { message->add_payload(message, (payload_t*)endpoint->build_notify(endpoint)); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } /** @@ -242,10 +242,8 @@ static void process_payloads(private_ike_me_t *this, message_t *message) enumerator->destroy(enumerator); } -/** - * Implementation of task_t.build for initiator - */ -static status_t build_i(private_ike_me_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_me_t *this, message_t *message) { switch(message->get_exchange_type(message)) { @@ -321,10 +319,8 @@ static status_t build_i(private_ike_me_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_me_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_me_t *this, message_t *message) { switch(message->get_exchange_type(message)) { @@ -381,10 +377,8 @@ static status_t process_r(private_ike_me_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_me_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_me_t *this, message_t *message) { switch(message->get_exchange_type(message)) { @@ -440,10 +434,8 @@ static status_t build_r(private_ike_me_t *this, message_t *message) return SUCCESS; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_me_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_me_t *this, message_t *message) { switch(message->get_exchange_type(message)) { @@ -520,9 +512,10 @@ static status_t process_i(private_ike_me_t *this, message_t *message) } /** - * Implementation of task_t.build for initiator (mediation server) + * For mediation server */ -static status_t build_i_ms(private_ike_me_t *this, message_t *message) +METHOD(task_t, build_i_ms, status_t, + private_ike_me_t *this, message_t *message) { switch(message->get_exchange_type(message)) { @@ -559,9 +552,10 @@ static status_t build_i_ms(private_ike_me_t *this, message_t *message) } /** - * Implementation of task_t.process for responder (mediation server) + * For mediation server */ -static status_t process_r_ms(private_ike_me_t *this, message_t *message) +METHOD(task_t, process_r_ms, status_t, + private_ike_me_t *this, message_t *message) { switch(message->get_exchange_type(message)) { @@ -632,9 +626,10 @@ static status_t process_r_ms(private_ike_me_t *this, message_t *message) } /** - * Implementation of task_t.build for responder (mediation server) + * For mediation server */ -static status_t build_r_ms(private_ike_me_t *this, message_t *message) +METHOD(task_t, build_r_ms, status_t, + private_ike_me_t *this, message_t *message) { switch(message->get_exchange_type(message)) { @@ -703,9 +698,10 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message) } /** - * Implementation of task_t.process for initiator (mediation server) + * For mediation server */ -static status_t process_i_ms(private_ike_me_t *this, message_t *message) +METHOD(task_t, process_i_ms, status_t, + private_ike_me_t *this, message_t *message) { /* FIXME: theoretically we should be prepared to receive a ME_CONNECT_FAILED * here if the responding peer is not able to proceed. in this case we shall @@ -714,40 +710,30 @@ static status_t process_i_ms(private_ike_me_t *this, message_t *message) return SUCCESS; } -/** - * Implementation of ike_me.connect - */ -static void me_connect(private_ike_me_t *this, identification_t *peer_id) +METHOD(ike_me_t, me_connect, void, + private_ike_me_t *this, identification_t *peer_id) { this->peer_id = peer_id->clone(peer_id); } -/** - * Implementation of ike_me.respond - */ -static void me_respond(private_ike_me_t *this, identification_t *peer_id, - chunk_t connect_id) +METHOD(ike_me_t, me_respond, void, + private_ike_me_t *this, identification_t *peer_id, chunk_t connect_id) { this->peer_id = peer_id->clone(peer_id); this->connect_id = chunk_clone(connect_id); this->response = TRUE; } -/** - * Implementation of ike_me.callback - */ -static void me_callback(private_ike_me_t *this, identification_t *peer_id) +METHOD(ike_me_t, me_callback, void, + private_ike_me_t *this, identification_t *peer_id) { this->peer_id = peer_id->clone(peer_id); this->callback = TRUE; } -/** - * Implementation of ike_me.relay - */ -static void relay(private_ike_me_t *this, identification_t *requester, - chunk_t connect_id, chunk_t connect_key, - linked_list_t *endpoints, bool response) +METHOD(ike_me_t, relay, void, + private_ike_me_t *this, identification_t *requester, chunk_t connect_id, + chunk_t connect_key, linked_list_t *endpoints, bool response) { this->peer_id = requester->clone(requester); this->connect_id = chunk_clone(connect_id); @@ -761,26 +747,20 @@ static void relay(private_ike_me_t *this, identification_t *requester, this->response = response; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_me_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_me_t *this) { return IKE_ME; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_me_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_me_t *this, ike_sa_t *ike_sa) { this->ike_sa = ike_sa; } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_me_t *this) +METHOD(task_t, destroy, void, + private_ike_me_t *this) { DESTROY_IF(this->peer_id); @@ -801,23 +781,37 @@ static void destroy(private_ike_me_t *this) */ ike_me_t *ike_me_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_me_t *this = malloc_thing(private_ike_me_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_ike_me_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + .connect = _me_connect, + .respond = _me_respond, + .callback = _me_callback, + .relay = _relay, + }, + .ike_sa = ike_sa, + .initiator = initiator, + .local_endpoints = linked_list_create(), + .remote_endpoints = linked_list_create(), + ); if (ike_sa->has_condition(ike_sa, COND_ORIGINAL_INITIATOR)) { if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } } else @@ -825,36 +819,15 @@ ike_me_t *ike_me_create(ike_sa_t *ike_sa, bool initiator) /* mediation server */ if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_ms; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i_ms; + this->public.task.build = _build_i_ms; + this->public.task.process = _process_i_ms; } else { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_r_ms; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_r_ms; + this->public.task.build = _build_r_ms; + this->public.task.process = _process_r_ms; } } - this->public.connect = (void(*)(ike_me_t*,identification_t*))me_connect; - this->public.respond = (void(*)(ike_me_t*,identification_t*,chunk_t))me_respond; - this->public.callback = (void(*)(ike_me_t*,identification_t*))me_callback; - this->public.relay = (void(*)(ike_me_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))relay; - - this->ike_sa = ike_sa; - this->initiator = initiator; - - this->peer_id = NULL; - this->connect_id = chunk_empty; - this->connect_key = chunk_empty; - this->local_endpoints = linked_list_create(); - this->remote_endpoints = linked_list_create(); - this->mediation = FALSE; - this->response = FALSE; - this->callback = FALSE; - this->failed = FALSE; - this->invalid_syntax = FALSE; - - this->mediated_cfg = NULL; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_mobike.c b/src/libcharon/sa/tasks/ike_mobike.c index 5b12eaaac..fb1100028 100644 --- a/src/libcharon/sa/tasks/ike_mobike.c +++ b/src/libcharon/sa/tasks/ike_mobike.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2010-2012 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -79,24 +80,6 @@ struct private_ike_mobike_t { }; /** - * flush the IKE_SAs list of additional addresses - */ -static void flush_additional_addresses(private_ike_mobike_t *this) -{ - iterator_t *iterator; - host_t *host; - - iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa); - while (iterator->iterate(iterator, (void**)&host)) - { - iterator->remove(iterator); - host->destroy(host); - } - iterator->destroy(iterator); -} - - -/** * read notifys from message and evaluate them */ static void process_payloads(private_ike_mobike_t *this, message_t *message) @@ -152,13 +135,17 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message) { if (first) { /* an ADDITIONAL_*_ADDRESS means replace, so flush once */ - flush_additional_addresses(this); + this->ike_sa->clear_peer_addresses(this->ike_sa); first = FALSE; + /* add the peer's current address to the list */ + host = message->get_source(message); + this->ike_sa->add_peer_address(this->ike_sa, + host->clone(host)); } data = notify->get_notification_data(notify); host = host_create_from_chunk(family, data, 0); DBG2(DBG_IKE, "got additional MOBIKE peer address: %H", host); - this->ike_sa->add_additional_address(this->ike_sa, host); + this->ike_sa->add_peer_address(this->ike_sa, host); this->addresses_updated = TRUE; break; } @@ -169,7 +156,10 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message) } case NO_ADDITIONAL_ADDRESSES: { - flush_additional_addresses(this); + this->ike_sa->clear_peer_addresses(this->ike_sa); + /* add the peer's current address to the list */ + host = message->get_source(message); + this->ike_sa->add_peer_address(this->ike_sa, host->clone(host)); this->addresses_updated = TRUE; break; } @@ -256,11 +246,11 @@ static void build_cookie(private_ike_mobike_t *this, message_t *message) */ static void update_children(private_ike_mobike_t *this) { - iterator_t *iterator; + enumerator_t *enumerator; child_sa_t *child_sa; - iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (child_sa->update(child_sa, this->ike_sa->get_my_host(this->ike_sa), @@ -273,7 +263,7 @@ static void update_children(private_ike_mobike_t *this) child_sa->get_spi(child_sa, TRUE)); } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } /** @@ -296,7 +286,7 @@ METHOD(ike_mobike_t, transmit, void, private_ike_mobike_t *this, packet_t *packet) { host_t *me, *other, *me_old, *other_old; - iterator_t *iterator; + enumerator_t *enumerator; ike_cfg_t *ike_cfg; packet_t *copy; @@ -309,19 +299,8 @@ METHOD(ike_mobike_t, transmit, void, other_old = this->ike_sa->get_other_host(this->ike_sa); ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); - me = hydra->kernel_interface->get_source_addr( - hydra->kernel_interface, other_old, NULL); - if (me) - { - apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg)); - DBG1(DBG_IKE, "checking original path %#H - %#H", me, other_old); - copy = packet->clone(packet); - copy->set_source(copy, me); - charon->sender->send(charon->sender, copy); - } - - iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa); - while (iterator->iterate(iterator, (void**)&other)) + enumerator = this->ike_sa->create_peer_address_enumerator(this->ike_sa); + while (enumerator->enumerate(enumerator, (void**)&other)) { me = hydra->kernel_interface->get_source_addr( hydra->kernel_interface, other, NULL); @@ -343,7 +322,7 @@ METHOD(ike_mobike_t, transmit, void, charon->sender->send(charon->sender, copy); } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } METHOD(task_t, build_i, status_t, diff --git a/src/libcharon/sa/tasks/ike_natd.c b/src/libcharon/sa/tasks/ike_natd.c index 7839b52eb..f06a518fa 100644 --- a/src/libcharon/sa/tasks/ike_natd.c +++ b/src/libcharon/sa/tasks/ike_natd.c @@ -256,10 +256,8 @@ static void process_payloads(private_ike_natd_t *this, message_t *message) } } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_natd_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_natd_t *this, message_t *message) { process_payloads(this, message); @@ -281,10 +279,8 @@ static status_t process_i(private_ike_natd_t *this, message_t *message) return SUCCESS; } -/** - * Implementation of task_t.process for initiator - */ -static status_t build_i(private_ike_natd_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_natd_t *this, message_t *message) { notify_payload_t *notify; enumerator_t *enumerator; @@ -345,15 +341,13 @@ static status_t build_i(private_ike_natd_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_natd_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_natd_t *this, message_t *message) { notify_payload_t *notify; host_t *me, *other; - /* only add notifies on successfull responses. */ + /* only add notifies on successful responses. */ if (message->get_exchange_type(message) == IKE_SA_INIT && message->get_payload(message, SECURITY_ASSOCIATION) == NULL) { @@ -380,28 +374,22 @@ static status_t build_r(private_ike_natd_t *this, message_t *message) return SUCCESS; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_natd_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_natd_t *this, message_t *message) { process_payloads(this, message); return NEED_MORE; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_natd_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_natd_t *this) { return IKE_NATD; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_natd_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_natd_t *this, ike_sa_t *ike_sa) { this->ike_sa = ike_sa; this->src_seen = FALSE; @@ -411,21 +399,17 @@ static void migrate(private_ike_natd_t *this, ike_sa_t *ike_sa) this->mapping_changed = FALSE; } -/** - * Implementation of ike_natd_t.has_mapping_changed - */ -static bool has_mapping_changed(private_ike_natd_t *this) +METHOD(task_t, destroy, void, + private_ike_natd_t *this) { - return this->mapping_changed; + DESTROY_IF(this->hasher); + free(this); } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_natd_t *this) +METHOD(ike_natd_t, has_mapping_changed, bool, + private_ike_natd_t *this) { - DESTROY_IF(this->hasher); - free(this); + return this->mapping_changed; } /* @@ -433,33 +417,32 @@ static void destroy(private_ike_natd_t *this) */ ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_natd_t *this = malloc_thing(private_ike_natd_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_ike_natd_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + .has_mapping_changed = _has_mapping_changed, + }, + .ike_sa = ike_sa, + .initiator = initiator, + .hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1), + ); if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } - this->public.has_mapping_changed = (bool(*)(ike_natd_t*))has_mapping_changed; - - this->ike_sa = ike_sa; - this->initiator = initiator; - this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - this->src_seen = FALSE; - this->dst_seen = FALSE; - this->src_matched = FALSE; - this->dst_matched = FALSE; - this->mapping_changed = FALSE; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_natd.h b/src/libcharon/sa/tasks/ike_natd.h index 97b652ead..68114af42 100644 --- a/src/libcharon/sa/tasks/ike_natd.h +++ b/src/libcharon/sa/tasks/ike_natd.h @@ -51,7 +51,7 @@ struct ike_natd_t { * Create a new ike_natd task. * * @param ike_sa IKE_SA this task works for - * @param initiator TRUE if thask is the original initator + * @param initiator TRUE if task is the original initiator * @return ike_natd task to handle by the task_manager */ ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator); diff --git a/src/libcharon/sa/tasks/ike_reauth.c b/src/libcharon/sa/tasks/ike_reauth.c index ac89c358b..48002d81c 100644 --- a/src/libcharon/sa/tasks/ike_reauth.c +++ b/src/libcharon/sa/tasks/ike_reauth.c @@ -42,134 +42,44 @@ struct private_ike_reauth_t { ike_delete_t *ike_delete; }; -/** - * Implementation of task_t.build for initiator - */ -static status_t build_i(private_ike_reauth_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_reauth_t *this, message_t *message) { return this->ike_delete->task.build(&this->ike_delete->task, message); } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_reauth_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_reauth_t *this, message_t *message) { - ike_sa_t *new; - host_t *host; - iterator_t *iterator; - child_sa_t *child_sa; - peer_cfg_t *peer_cfg; - /* process delete response first */ this->ike_delete->task.process(&this->ike_delete->task, message); - peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); - - /* reauthenticate only if we have children */ - iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa); - if (iterator->get_count(iterator) == 0 -#ifdef ME - /* we allow peers to reauth mediation connections (without children) */ - && !peer_cfg->is_mediation(peer_cfg) -#endif /* ME */ - ) + /* reestablish the IKE_SA with all children */ + if (this->ike_sa->reestablish(this->ike_sa) != SUCCESS) { - DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA to recreate"); - iterator->destroy(iterator); + DBG1(DBG_IKE, "reauthenticating IKE_SA failed"); return FAILED; } - new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, TRUE); - - new->set_peer_cfg(new, peer_cfg); - host = this->ike_sa->get_other_host(this->ike_sa); - new->set_other_host(new, host->clone(host)); - host = this->ike_sa->get_my_host(this->ike_sa); - new->set_my_host(new, host->clone(host)); - /* if we already have a virtual IP, we reuse it */ - host = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE); - if (host) - { - new->set_virtual_ip(new, TRUE, host); - } - -#ifdef ME - /* we initiate the new IKE_SA of the mediation connection without CHILD_SA */ - if (peer_cfg->is_mediation(peer_cfg)) - { - if (new->initiate(new, NULL, 0, NULL, NULL) == DESTROY_ME) - { - charon->ike_sa_manager->checkin_and_destroy( - charon->ike_sa_manager, new); - /* set threads active IKE_SA after checkin */ - charon->bus->set_sa(charon->bus, this->ike_sa); - DBG1(DBG_IKE, "reauthenticating IKE_SA failed"); - return FAILED; - } - } -#endif /* ME */ - - while (iterator->iterate(iterator, (void**)&child_sa)) - { - switch (child_sa->get_state(child_sa)) - { - case CHILD_ROUTED: - { - /* move routed child directly */ - iterator->remove(iterator); - new->add_child_sa(new, child_sa); - break; - } - default: - { - /* initiate/queue all child SAs */ - child_cfg_t *child_cfg = child_sa->get_config(child_sa); - child_cfg->get_ref(child_cfg); - if (new->initiate(new, child_cfg, 0, NULL, NULL) == DESTROY_ME) - { - iterator->destroy(iterator); - charon->ike_sa_manager->checkin_and_destroy( - charon->ike_sa_manager, new); - /* set threads active IKE_SA after checkin */ - charon->bus->set_sa(charon->bus, this->ike_sa); - DBG1(DBG_IKE, "reauthenticating IKE_SA failed"); - return FAILED; - } - break; - } - } - } - iterator->destroy(iterator); - charon->ike_sa_manager->checkin(charon->ike_sa_manager, new); - /* set threads active IKE_SA after checkin */ - charon->bus->set_sa(charon->bus, this->ike_sa); - - /* we always return failed to delete the obsolete IKE_SA */ - return FAILED; + /* we always destroy the obsolete IKE_SA */ + return DESTROY_ME; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_reauth_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_reauth_t *this) { return IKE_REAUTH; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_reauth_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_reauth_t *this, ike_sa_t *ike_sa) { this->ike_delete->task.migrate(&this->ike_delete->task, ike_sa); this->ike_sa = ike_sa; } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_reauth_t *this) +METHOD(task_t, destroy, void, + private_ike_reauth_t *this) { this->ike_delete->task.destroy(&this->ike_delete->task); free(this); @@ -180,16 +90,21 @@ static void destroy(private_ike_reauth_t *this) */ ike_reauth_t *ike_reauth_create(ike_sa_t *ike_sa) { - private_ike_reauth_t *this = malloc_thing(private_ike_reauth_t); - - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; - - this->ike_sa = ike_sa; - this->ike_delete = ike_delete_create(ike_sa, TRUE); + private_ike_reauth_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .build = _build_i, + .process = _process_i, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .ike_delete = ike_delete_create(ike_sa, TRUE), + ); return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c index c055dabc1..826d6e192 100644 --- a/src/libcharon/sa/tasks/ike_rekey.c +++ b/src/libcharon/sa/tasks/ike_rekey.c @@ -147,8 +147,8 @@ METHOD(task_t, build_i, status_t, METHOD(task_t, process_r, status_t, private_ike_rekey_t *this, message_t *message) { + enumerator_t *enumerator; peer_cfg_t *peer_cfg; - iterator_t *iterator; child_sa_t *child_sa; if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING) @@ -157,8 +157,8 @@ METHOD(task_t, process_r, status_t, return NEED_MORE; } - iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa); - while (iterator->iterate(iterator, (void**)&child_sa)) + enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa); + while (enumerator->enumerate(enumerator, (void**)&child_sa)) { switch (child_sa->get_state(child_sa)) { @@ -167,13 +167,13 @@ METHOD(task_t, process_r, status_t, case CHILD_DELETING: /* we do not allow rekeying while we have children in-progress */ DBG1(DBG_IKE, "peer initiated rekeying, but a child is half-open"); - iterator->destroy(iterator); + enumerator->destroy(enumerator); return NEED_MORE; default: break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); this->new_sa = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, FALSE); diff --git a/src/libcharon/sa/tasks/ike_vendor.h b/src/libcharon/sa/tasks/ike_vendor.h index dcdd37424..6c353c447 100644 --- a/src/libcharon/sa/tasks/ike_vendor.h +++ b/src/libcharon/sa/tasks/ike_vendor.h @@ -42,7 +42,7 @@ struct ike_vendor_t { * Create a ike_vendor instance. * * @param ike_sa IKE_SA this task works for - * @param initiator TRUE if thask is the original initator + * @param initiator TRUE if task is the original initiator */ ike_vendor_t *ike_vendor_create(ike_sa_t *ike_sa, bool initiator); diff --git a/src/libcharon/sa/tasks/task.h b/src/libcharon/sa/tasks/task.h index 4468f2ebe..d57085954 100644 --- a/src/libcharon/sa/tasks/task.h +++ b/src/libcharon/sa/tasks/task.h @@ -89,7 +89,7 @@ extern enum_name_t *task_type_names; * A responder does the opposite; it calls process() first to handle an incoming * request and secondly calls build() to build an appropriate response. * Both methods return either SUCCESS, NEED_MORE or FAILED. A SUCCESS indicates - * that the task completed, even when the task completed unsuccesfully. The + * that the task completed, even when the task completed unsuccessfully. The * manager then removes the task from the list. A NEED_MORE is returned when * the task needs further build()/process() calls to complete, the manager * leaves the taks in the queue. A returned FAILED indicates a critical failure. @@ -102,7 +102,7 @@ struct task_t { * * @param message message to add payloads to * @return - * - FAILED if a critical error occured + * - FAILED if a critical error occurred * - DESTROY_ME if IKE_SA has been properly deleted * - NEED_MORE if another call to build/process needed * - SUCCESS if task completed @@ -114,7 +114,7 @@ struct task_t { * * @param message message to read payloads from * @return - * - FAILED if a critical error occured + * - FAILED if a critical error occurred * - 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/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index f91eff077..86d9f4c22 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2011 Tobias Brunner * Copyright (C) 2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -74,8 +75,10 @@ typedef struct { peer_cfg_t *peer_cfg; /** ref to instanciated CHILD_SA */ child_sa_t *child_sa; + /** TRUE if an acquire is pending */ + bool pending; /** pending IKE_SA connecting upon acquire */ - ike_sa_t *pending; + ike_sa_t *ike_sa; } entry_t; /** @@ -88,11 +91,8 @@ static void destroy_entry(entry_t *entry) free(entry); } -/** - * Implementation of trap_manager_t.install - */ -static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer, - child_cfg_t *child) +METHOD(trap_manager_t, install, u_int32_t, + private_trap_manager_t *this, peer_cfg_t *peer, child_cfg_t *child) { entry_t *entry; ike_cfg_t *ike_cfg; @@ -158,8 +158,8 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer, 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. */ + * could iterate all proposals for a best guess (TODO). But as we + * support ESP only for now, we set it 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); @@ -173,10 +173,10 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer, } reqid = child_sa->get_reqid(child_sa); - entry = malloc_thing(entry_t); - entry->child_sa = child_sa; - entry->peer_cfg = peer->get_ref(peer); - entry->pending = NULL; + INIT(entry, + .child_sa = child_sa, + .peer_cfg = peer->get_ref(peer), + ); this->lock->write_lock(this->lock); this->traps->insert_last(this->traps, entry); @@ -185,10 +185,8 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer, return reqid; } -/** - * Implementation of trap_manager_t.uninstall - */ -static bool uninstall(private_trap_manager_t *this, u_int32_t reqid) +METHOD(trap_manager_t, uninstall, bool, + private_trap_manager_t *this, u_int32_t reqid) { enumerator_t *enumerator; entry_t *entry, *found = NULL; @@ -234,10 +232,8 @@ static bool trap_filter(rwlock_t *lock, entry_t **entry, peer_cfg_t **peer_cfg, return TRUE; } -/** - * Implementation of trap_manager_t.create_enumerator - */ -static enumerator_t* create_enumerator(private_trap_manager_t *this) +METHOD(trap_manager_t, create_enumerator, enumerator_t*, + private_trap_manager_t *this) { this->lock->read_lock(this->lock); return enumerator_create_filter(this->traps->create_enumerator(this->traps), @@ -245,11 +241,9 @@ static enumerator_t* create_enumerator(private_trap_manager_t *this) (void*)this->lock->unlock); } -/** - * Implementation of trap_manager_t.acquire - */ -static void acquire(private_trap_manager_t *this, u_int32_t reqid, - traffic_selector_t *src, traffic_selector_t *dst) +METHOD(trap_manager_t, acquire, void, + private_trap_manager_t *this, u_int32_t reqid, + traffic_selector_t *src, traffic_selector_t *dst) { enumerator_t *enumerator; entry_t *entry, *found = NULL; @@ -272,35 +266,46 @@ static void acquire(private_trap_manager_t *this, u_int32_t reqid, if (!found) { DBG1(DBG_CFG, "trap not found, unable to acquire reqid %d",reqid); + this->lock->unlock(this->lock); + return; } - else if (found->pending) + if (!cas_bool(&found->pending, FALSE, TRUE)) { DBG1(DBG_CFG, "ignoring acquire, connection attempt pending"); + this->lock->unlock(this->lock); + return; } - else + peer = found->peer_cfg->get_ref(found->peer_cfg); + child = found->child_sa->get_config(found->child_sa); + child = child->get_ref(child); + reqid = found->child_sa->get_reqid(found->child_sa); + /* don't hold the lock while checking out the IKE_SA */ + this->lock->unlock(this->lock); + + ike_sa = charon->ike_sa_manager->checkout_by_config( + charon->ike_sa_manager, peer); + if (ike_sa->get_peer_cfg(ike_sa) == NULL) { - child = found->child_sa->get_config(found->child_sa); - peer = found->peer_cfg; - ike_sa = charon->ike_sa_manager->checkout_by_config( - charon->ike_sa_manager, peer); - if (ike_sa->get_peer_cfg(ike_sa) == NULL) - { - ike_sa->set_peer_cfg(ike_sa, peer); - } - child->get_ref(child); - reqid = found->child_sa->get_reqid(found->child_sa); - if (ike_sa->initiate(ike_sa, child, reqid, src, dst) != DESTROY_ME) - { - found->pending = ike_sa; - charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); - } - else + ike_sa->set_peer_cfg(ike_sa, peer); + } + if (ike_sa->initiate(ike_sa, child, reqid, src, dst) != DESTROY_ME) + { + /* make sure the entry is still there */ + this->lock->read_lock(this->lock); + if (this->traps->find_first(this->traps, NULL, + (void**)&found) == SUCCESS) { - charon->ike_sa_manager->checkin_and_destroy( - charon->ike_sa_manager, ike_sa); + found->ike_sa = ike_sa; } + this->lock->unlock(this->lock); + charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); } - this->lock->unlock(this->lock); + else + { + charon->ike_sa_manager->checkin_and_destroy( + charon->ike_sa_manager, ike_sa); + } + peer->destroy(peer); } /** @@ -316,7 +321,7 @@ static void complete(private_trap_manager_t *this, ike_sa_t *ike_sa, enumerator = this->traps->create_enumerator(this->traps); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->pending != ike_sa) + if (entry->ike_sa != ike_sa) { continue; } @@ -325,17 +330,15 @@ static void complete(private_trap_manager_t *this, ike_sa_t *ike_sa, { continue; } - entry->pending = NULL; + entry->ike_sa = NULL; + entry->pending = FALSE; } enumerator->destroy(enumerator); this->lock->unlock(this->lock); } -/** - * Implementation of listener_t.ike_state_change - */ -static bool ike_state_change(trap_listener_t *listener, ike_sa_t *ike_sa, - ike_sa_state_t state) +METHOD(listener_t, ike_state_change, bool, + trap_listener_t *listener, ike_sa_t *ike_sa, ike_sa_state_t state) { switch (state) { @@ -347,11 +350,9 @@ static bool ike_state_change(trap_listener_t *listener, ike_sa_t *ike_sa, } } -/** - * Implementation of listener_t.child_state_change - */ -static bool child_state_change(trap_listener_t *listener, ike_sa_t *ike_sa, - child_sa_t *child_sa, child_sa_state_t state) +METHOD(listener_t, child_state_change, bool, + trap_listener_t *listener, ike_sa_t *ike_sa, child_sa_t *child_sa, + child_sa_state_t state) { switch (state) { @@ -364,14 +365,24 @@ static bool child_state_change(trap_listener_t *listener, ike_sa_t *ike_sa, } } -/** - * Implementation of trap_manager_t.destroy. - */ -static void destroy(private_trap_manager_t *this) +METHOD(trap_manager_t, flush, void, + private_trap_manager_t *this) +{ + linked_list_t *traps; + /* since destroying the CHILD_SA results in events which require a read + * lock we cannot destroy the list while holding the write lock */ + this->lock->write_lock(this->lock); + traps = this->traps; + this->traps = linked_list_create(); + this->lock->unlock(this->lock); + traps->destroy_function(traps, (void*)destroy_entry); +} + +METHOD(trap_manager_t, destroy, void, + private_trap_manager_t *this) { charon->bus->remove_listener(charon->bus, &this->listener.listener); - this->traps->invoke_function(this->traps, (void*)destroy_entry); - this->traps->destroy(this->traps); + this->traps->destroy_function(this->traps, (void*)destroy_entry); this->lock->destroy(this->lock); free(this); } @@ -379,24 +390,29 @@ static void destroy(private_trap_manager_t *this) /** * See header */ -trap_manager_t *trap_manager_create() +trap_manager_t *trap_manager_create(void) { - private_trap_manager_t *this = malloc_thing(private_trap_manager_t); - - this->public.install = (u_int(*)(trap_manager_t*, peer_cfg_t *peer, child_cfg_t *child))install; - this->public.uninstall = (bool(*)(trap_manager_t*, u_int32_t id))uninstall; - this->public.create_enumerator = (enumerator_t*(*)(trap_manager_t*))create_enumerator; - this->public.acquire = (void(*)(trap_manager_t*, u_int32_t reqid, traffic_selector_t *src, traffic_selector_t *dst))acquire; - this->public.destroy = (void(*)(trap_manager_t*))destroy; - - this->traps = linked_list_create(); - this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); - - /* register listener for IKE state changes */ - this->listener.traps = this; - memset(&this->listener.listener, 0, sizeof(listener_t)); - this->listener.listener.ike_state_change = (void*)ike_state_change; - this->listener.listener.child_state_change = (void*)child_state_change; + private_trap_manager_t *this; + + INIT(this, + .public = { + .install = _install, + .uninstall = _uninstall, + .create_enumerator = _create_enumerator, + .acquire = _acquire, + .flush = _flush, + .destroy = _destroy, + }, + .listener = { + .traps = this, + .listener = { + .ike_state_change = _ike_state_change, + .child_state_change = _child_state_change, + }, + }, + .traps = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); charon->bus->add_listener(charon->bus, &this->listener.listener); return &this->public; diff --git a/src/libcharon/sa/trap_manager.h b/src/libcharon/sa/trap_manager.h index 37b42e2b0..928b2a49f 100644 --- a/src/libcharon/sa/trap_manager.h +++ b/src/libcharon/sa/trap_manager.h @@ -68,6 +68,11 @@ struct trap_manager_t { traffic_selector_t *src, traffic_selector_t *dst); /** + * Clear any installed trap. + */ + void (*flush)(trap_manager_t *this); + + /** * Destroy a trap_manager_t. */ void (*destroy)(trap_manager_t *this); diff --git a/src/libcharon/tnc/imc/imc.h b/src/libcharon/tnc/imc/imc.h deleted file mode 100644 index fe8f25b0f..000000000 --- a/src/libcharon/tnc/imc/imc.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Steffen - * HSR 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 imc imc - * @ingroup tnc - * - * @defgroup imct imc - * @{ @ingroup imc - */ - -#ifndef IMC_H_ -#define IMC_H_ - -#include <tnc/tncifimc.h> -#include <library.h> - -typedef struct imc_t imc_t; - -/** - * Controls a single Integrity Measurement Collector (IMC) - */ -struct imc_t { - - /** - * The TNC Client calls this function to initialize the IMC and agree on - * the API version number to be used. It also supplies the IMC ID, an IMC - * identifier that the IMC must use when calling TNC Client callback functions. - * - * @param imcID IMC ID assigned by TNCC - * @param minVersion minimum API version supported by TNCC - * @param maxVersion maximum API version supported by TNCC - * @param OutActualVersion mutually supported API version number - * @return TNC result code - */ - TNC_Result (*initialize)(TNC_IMCID imcID, - TNC_Version minVersion, - TNC_Version maxVersion, - TNC_Version *OutActualVersion); - - /** - * The TNC Client calls this function to inform the IMC that the state of - * the network connection identified by connectionID has changed to newState. - * - * @param imcID IMC ID assigned by TNCC - * @param connectionID network connection ID assigned by TNCC - * @param newState new network connection state - * @return TNC result code - */ - TNC_Result (*notify_connection_change)(TNC_IMCID imcID, - TNC_ConnectionID connectionID, - TNC_ConnectionState newState); - - /** - * The TNC Client calls this function to indicate that an Integrity Check - * Handshake is beginning and solicit messages from IMCs for the first batch. - * - * @param imcID IMC ID assigned by TNCC - * @param connectionID network connection ID assigned by TNCC - * @return TNC result code - */ - TNC_Result (*begin_handshake)(TNC_IMCID imcID, - TNC_ConnectionID connectionID); - - /** - * The TNC Client calls this function to deliver a message to the IMC. - * The message is contained in the buffer referenced by message and contains - * the number of octets indicated by messageLength. The type of the message - * is indicated by messageType. - * - * @param imcID IMC ID assigned by TNCS - * @param connectionID network connection ID assigned by TNCC - * @param message reference to buffer containing message - * @param messageLength number of octets in message - * @param messageType message type of message - * @return TNC result code - */ - TNC_Result (*receive_message)(TNC_IMCID imcID, - TNC_ConnectionID connectionID, - TNC_BufferReference message, - TNC_UInt32 messageLength, - TNC_MessageType messageType); - - /** - * The TNC Client calls this function to notify IMCs that all IMV messages - * received in a batch have been delivered and this is the IMC’s last chance - * to send a message in the batch of IMC messages currently being collected. - * - * @param imcID IMC ID assigned by TNCC - * @param connectionID network connection ID assigned by TNCC - * @return TNC result code - */ - TNC_Result (*batch_ending)(TNC_IMCID imcID, - TNC_ConnectionID connectionID); - - /** - * The TNC Client calls this function to close down the IMC when all work is - * complete or the IMC reports TNC_RESULT_FATAL. - * - * @param imcID IMC ID assigned by TNCC - * @return TNC result code - */ - TNC_Result (*terminate)(TNC_IMCID imcID); - - /** - * IMVs implementing the UNIX/Linux Dynamic Linkage platform binding MUST - * define this additional function. The TNC Server MUST call the function - * immediately after calling TNC_IMV_Initialize to provide a pointer to the - * TNCS bind function. The IMV can then use the TNCS bind function to obtain - * pointers to any other TNCS functions. - * - * @param imcID IMC ID assigned by TNCC - * @param bindFunction pointer to TNC_TNCC_BindFunction - * @return TNC result code - */ - TNC_Result (*provide_bind_function)(TNC_IMCID imcID, - TNC_TNCC_BindFunctionPointer bindFunction); - - /** - * Sets the ID of an imc_t object. - * - * @param id IMC ID to be assigned - */ - void (*set_id)(imc_t *this, TNC_IMCID id); - - /** - * Returns the ID of an imc_t object. - * - * @return assigned IMC ID - */ - TNC_IMCID (*get_id)(imc_t *this); - - /** - * Returns the name of an imc_t object. - * - * @return name of IMC - */ - char* (*get_name)(imc_t *this); - - /** - * Sets the supported message types of an imc_t object. - * - * @param supported_types list of messages type supported by IMC - * @param type_count number of supported message types - */ - void (*set_message_types)(imc_t *this, TNC_MessageTypeList supported_types, - TNC_UInt32 type_count); - - /** - * Check if the IMC supports a given message type. - * - * @param message_type message type - * @return TRUE if supported - */ - bool (*type_supported)(imc_t *this, TNC_MessageType message_type); - - /** - * Destroys an imc_t object. - */ - void (*destroy)(imc_t *this); -}; - -#endif /** IMC_H_ @}*/ diff --git a/src/libcharon/tnc/imc/imc_manager.h b/src/libcharon/tnc/imc/imc_manager.h deleted file mode 100644 index ad83cf552..000000000 --- a/src/libcharon/tnc/imc/imc_manager.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Steffen - * HSR 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 imc_manager imc_manager - * @{ @ingroup imc - */ - -#ifndef IMC_MANAGER_H_ -#define IMC_MANAGER_H_ - -#include "imc.h" - -#include <library.h> - -typedef struct imc_manager_t imc_manager_t; - -/** - * The IMC manager controls all IMC instances. - */ -struct imc_manager_t { - - /** - * Add an IMC instance - * - * @param imc IMC instance - * @return TRUE if initialization successful - */ - bool (*add)(imc_manager_t *this, imc_t *imc); - - /** - * Remove an IMC instance from the list and return it - * - * @param id ID of IMC instance - * @return removed IMC instance - */ - imc_t* (*remove)(imc_manager_t *this, TNC_IMCID id); - - /** - * Check if an IMC with a given ID is registered with the IMC manager - * - * @param id ID of IMC instance - * @return TRUE if registered - */ - bool (*is_registered)(imc_manager_t *this, TNC_IMCID id); - - /** - * Return the preferred language for recommendations - * - * @return preferred language string - */ - char* (*get_preferred_language)(imc_manager_t *this); - - /** - * Notify all IMC instances - * - * @param state communicate the state a connection has reached - */ - void (*notify_connection_change)(imc_manager_t *this, - TNC_ConnectionID id, - TNC_ConnectionState state); - - /** - * Begin a handshake between the IMCs and a connection - * - * @param id connection ID - */ - void (*begin_handshake)(imc_manager_t *this, TNC_ConnectionID id); - - /** - * Sets the supported message types reported by a given IMC - * - * @param id ID of reporting IMC - * @param supported_types list of messages type supported by IMC - * @param type_count number of supported message types - * @return TNC result code - */ - TNC_Result (*set_message_types)(imc_manager_t *this, - TNC_IMCID id, - TNC_MessageTypeList supported_types, - TNC_UInt32 type_count); - - /** - * Delivers a message to interested IMCs. - * - * @param connection_id ID of connection over which message was received - * @param message message - * @param message_len message length - * @param message_type message type - */ - void (*receive_message)(imc_manager_t *this, - TNC_ConnectionID connection_id, - TNC_BufferReference message, - TNC_UInt32 message_len, - TNC_MessageType message_type); - - /** - * Notify all IMCs that all IMV messages received in a batch have been - * delivered and this is the IMCs last chance to send a message in the - * batch of IMC messages currently being collected. - * - * @param id connection ID - */ - void (*batch_ending)(imc_manager_t *this, TNC_ConnectionID id); - - /** - * Destroy an IMC manager and all its controlled instances. - */ - void (*destroy)(imc_manager_t *this); -}; - -#endif /** IMC_MANAGER_H_ @}*/ diff --git a/src/libcharon/tnc/imv/imv.h b/src/libcharon/tnc/imv/imv.h deleted file mode 100644 index 26874ab0b..000000000 --- a/src/libcharon/tnc/imv/imv.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Steffen - * HSR 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 imv imv - * @ingroup tnc - * - * @defgroup imvt imv - * @{ @ingroup imv - */ - -#ifndef IMV_H_ -#define IMV_H_ - -#include <tnc/tncifimv.h> -#include <library.h> - -typedef struct imv_t imv_t; - -/** - * Controls a single Integrity Measurement Verifier (IMV) - */ -struct imv_t { - - /** - * The TNC Server calls this function to initialize the IMV and agree on - * the API version number to be used. It also supplies the IMV ID, an IMV - * identifier that the IMV must use when calling TNC Server callback functions. - * - * @param imvID IMV ID assigned by TNCS - * @param minVersion minimum API version supported - * @param maxVersion maximum API version supported by TNCS - * @param OutActualVersion mutually supported API version number - * @return TNC result code - */ - TNC_Result (*initialize)(TNC_IMVID imvID, - TNC_Version minVersion, - TNC_Version maxVersion, - TNC_Version *OutActualVersion); - - /** - * The TNC Server calls this function to inform the IMV that the state of - * the network connection identified by connectionID has changed to newState. - * - * @param imvID IMV ID assigned by TNCS - * @param connectionID network connection ID assigned by TNCS - * @param newState new network connection state - * @return TNC result code - */ - TNC_Result (*notify_connection_change)(TNC_IMVID imvID, - TNC_ConnectionID connectionID, - TNC_ConnectionState newState); - - /** - * The TNC Server calls this function at the end of an Integrity Check - * Handshake (after all IMC-IMV messages have been delivered) to solicit - * recommendations from IMVs that have not yet provided a recommendation. - * - * @param imvID IMV ID assigned by TNCS - * @param connectionID network connection ID assigned by TNCS - * @return TNC result code - */ - TNC_Result (*solicit_recommendation)(TNC_IMVID imvID, - TNC_ConnectionID connectionID); - - /** - * The TNC Server calls this function to deliver a message to the IMV. - * The message is contained in the buffer referenced by message and contains - * the number of octets indicated by messageLength. The type of the message - * is indicated by messageType. - * - * @param imvID IMV ID assigned by TNCS - * @param connectionID network connection ID assigned by TNCS - * @param message reference to buffer containing message - * @param messageLength number of octets in message - * @param messageType message type of message - * @return TNC result code - */ - TNC_Result (*receive_message)(TNC_IMVID imvID, - TNC_ConnectionID connectionID, - TNC_BufferReference message, - TNC_UInt32 messageLength, - TNC_MessageType messageType); - - /** - * The TNC Server calls this function to notify IMVs that all IMC messages - * received in a batch have been delivered and this is the IMV’s last chance - * to send a message in the batch of IMV messages currently being collected. - * - * @param imvID IMV ID assigned by TNCS - * @param connectionID network connection ID assigned by TNCS - * @return TNC result code - */ - TNC_Result (*batch_ending)(TNC_IMVID imvID, - TNC_ConnectionID connectionID); - - /** - * The TNC Server calls this function to close down the IMV. - * - * @param imvID IMV ID assigned by TNCS - * @return TNC result code - */ - TNC_Result (*terminate)(TNC_IMVID imvID); - - /** - * IMVs implementing the UNIX/Linux Dynamic Linkage platform binding MUST - * define this additional function. The TNC Server MUST call the function - * immediately after calling TNC_IMV_Initialize to provide a pointer to the - * TNCS bind function. The IMV can then use the TNCS bind function to obtain - * pointers to any other TNCS functions. - * - * @param imvID IMV ID assigned by TNCS - * @param bindFunction pointer to TNC_TNCS_BindFunction - * @return TNC result code - */ - TNC_Result (*provide_bind_function)(TNC_IMVID imvID, - TNC_TNCS_BindFunctionPointer bindFunction); - - /** - * Sets the ID of an imv_t object. - * - * @param id IMV ID to be assigned - */ - void (*set_id)(imv_t *this, TNC_IMVID id); - - /** - * Returns the ID of an imv_t object. - * - * @return IMV ID assigned by TNCS - */ - TNC_IMVID (*get_id)(imv_t *this); - - /** - * Returns the name of an imv_t object. - * - * @return name of IMV - */ - char* (*get_name)(imv_t *this); - - /** - * Sets the supported message types of an imv_t object. - * - * @param supported_types list of messages type supported by IMV - * @param type_count number of supported message types - */ - void (*set_message_types)(imv_t *this, TNC_MessageTypeList supported_types, - TNC_UInt32 type_count); - - /** - * Check if the IMV supports a given message type. - * - * @param message_type message type - * @return TRUE if supported - */ - bool (*type_supported)(imv_t *this, TNC_MessageType message_type); - - /** - * Destroys an imv_t object. - */ - void (*destroy)(imv_t *this); -}; - -#endif /** IMV_H_ @}*/ diff --git a/src/libcharon/tnc/imv/imv_manager.h b/src/libcharon/tnc/imv/imv_manager.h deleted file mode 100644 index 0dd2d6253..000000000 --- a/src/libcharon/tnc/imv/imv_manager.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Steffen - * HSR 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 imv_manager imv_manager - * @{ @ingroup imv - */ - -#ifndef IMV_MANAGER_H_ -#define IMV_MANAGER_H_ - -#include "imv.h" -#include "imv_recommendations.h" - -#include <library.h> - -typedef struct imv_manager_t imv_manager_t; - -/** - * The IMV manager controls all IMV instances. - */ -struct imv_manager_t { - - /** - * Add an IMV instance - * - * @param imv IMV instance - * @return TRUE if initialization successful - */ - bool (*add)(imv_manager_t *this, imv_t *imv); - - /** - * Remove an IMV instance from the list and return it - * - * @param id ID of IMV instance - * @return removed IMC instance - */ - imv_t* (*remove)(imv_manager_t *this, TNC_IMVID id); - - /** - * Check if an IMV with a given ID is registered with the IMV manager - * - * @param id ID of IMV instance - * @return TRUE if registered - */ - bool (*is_registered)(imv_manager_t *this, TNC_IMVID id); - - - /** - * Get the configured recommendation policy - * - * @return configured recommendation policy - */ - recommendation_policy_t (*get_recommendation_policy)(imv_manager_t *this); - - /** - * Create an empty set of IMV recommendations and evaluations - * - * @return instance of a recommendations_t list - */ - recommendations_t* (*create_recommendations)(imv_manager_t *this); - - /** - * Enforce the TNC recommendation on the IKE_SA by either inserting an - * allow|isolate group membership rule (TRUE) or by blocking access (FALSE) - * - * @param rec TNC action recommendation - * @param eval TNC evaluation result - * @return TRUE for allow|isolate, FALSE for none - */ - bool (*enforce_recommendation)(imv_manager_t *this, - TNC_IMV_Action_Recommendation rec, - TNC_IMV_Evaluation_Result eval); - - /** - * Notify all IMV instances - * - * @param state communicate the state a connection has reached - */ - void (*notify_connection_change)(imv_manager_t *this, - TNC_ConnectionID id, - TNC_ConnectionState state); - - /** - * Sets the supported message types reported by a given IMV - * - * @param id ID of reporting IMV - * @param supported_types list of messages type supported by IMV - * @param type_count number of supported message types - * @return TNC result code - */ - TNC_Result (*set_message_types)(imv_manager_t *this, - TNC_IMVID id, - TNC_MessageTypeList supported_types, - TNC_UInt32 type_count); - - /** - * Solicit recommendations from IMVs that have not yet provided one - * - * @param id connection ID - */ - void (*solicit_recommendation)(imv_manager_t *this, TNC_ConnectionID id); - - /** - * Delivers a message to interested IMVs. - * - * @param connection_id ID of connection over which message was received - * @param message message - * @param message_len message length - * @param message_type message type - */ - void (*receive_message)(imv_manager_t *this, - TNC_ConnectionID connection_id, - TNC_BufferReference message, - TNC_UInt32 message_len, - TNC_MessageType message_type); - - /** - * Notify all IMVs that all IMC messages received in a batch have been - * delivered and this is the IMVs last chance to send a message in the - * batch of IMV messages currently being collected. - * - * @param id connection ID - */ - void (*batch_ending)(imv_manager_t *this, TNC_ConnectionID id); - - /** - * Destroy an IMV manager and all its controlled instances. - */ - void (*destroy)(imv_manager_t *this); -}; - -#endif /** IMV_MANAGER_H_ @}*/ diff --git a/src/libcharon/tnc/imv/imv_recommendations.h b/src/libcharon/tnc/imv/imv_recommendations.h deleted file mode 100644 index 3a6e25c9f..000000000 --- a/src/libcharon/tnc/imv/imv_recommendations.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Steffen - * HSR 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 imv_recommendations imv_recommendations - * @{ @ingroup imv - */ - -#ifndef IMV_RECOMMENDATIONS_H_ -#define IMV_RECOMMENDATIONS_H_ - -#include <tnc/tncifimv.h> -#include <library.h> - -typedef enum recommendation_policy_t recommendation_policy_t; - -enum recommendation_policy_t { - RECOMMENDATION_POLICY_DEFAULT, - RECOMMENDATION_POLICY_ANY, - RECOMMENDATION_POLICY_ALL -}; - -extern enum_name_t *recommendation_policy_names; - - -typedef struct recommendations_t recommendations_t; - -/** - * Collection of all IMV action recommendations and evaluation results - */ -struct recommendations_t { - - /** - * Deliver an IMV action recommendation and IMV evaluation result to the TNCS - * - * @param imv_id ID of the IMV providing the recommendation - * @param rec action recommendation - * @param eval evaluation result - * @return return code - */ - TNC_Result (*provide_recommendation)(recommendations_t *this, - TNC_IMVID imv_id, - TNC_IMV_Action_Recommendation rec, - TNC_IMV_Evaluation_Result eval); - - /** - * If all IMVs provided a recommendation, derive a consolidated action - * recommendation and evaluation result based on a configured policy - * - * @param rec action recommendation - * @param eval evaluation result - * @return TRUE if all IMVs provided a recommendation - */ - bool (*have_recommendation)(recommendations_t *this, - TNC_IMV_Action_Recommendation *rec, - TNC_IMV_Evaluation_Result *eval); - - /** - * Get the preferred language for remediation messages - * - * @return preferred language - */ - chunk_t (*get_preferred_language)(recommendations_t *this); - - /** - * Set the preferred language for remediation messages - * - * @param pref_lang preferred language - */ - void (*set_preferred_language)(recommendations_t *this, chunk_t pref_lang); - - /** - * Set the reason string - * - * @param id ID of IMV setting the reason string - * @param reason reason string - * @result return code - */ - TNC_Result (*set_reason_string)(recommendations_t *this, TNC_IMVID id, - chunk_t reason); - - /** - * Set the language for reason strings - * - * @param id ID of IMV setting the reason language - * @param reason_lang reason language - * @result return code - */ - TNC_Result (*set_reason_language)(recommendations_t *this, TNC_IMVID id, - chunk_t reason_lang); - - /** - * Enumerates over all IMVs sending a reason string. - * Format: TNC_IMVID *id, chunk_t *reason, chunk_t *reason_language - * - * @return enumerator - */ - enumerator_t* (*create_reason_enumerator)(recommendations_t *this); - /** - * Destroys an imv_t object. - */ - void (*destroy)(recommendations_t *this); -}; - -#endif /** IMV_RECOMMENDATIONS_H_ @}*/ diff --git a/src/libcharon/tnc/tnccs/tnccs.h b/src/libcharon/tnc/tnccs/tnccs.h deleted file mode 100644 index 32f065f67..000000000 --- a/src/libcharon/tnc/tnccs/tnccs.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Steffen - * HSR 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 tnccs tnccs - * @ingroup tnc - * - * @defgroup tnccst tnccs - * @{ @ingroup tnccs - */ - -#ifndef TNCCS_H_ -#define TNCCS_H_ - -#include <tnc/tncif.h> -#include <tnc/tncifimc.h> -#include <tnc/tncifimv.h> -#include <library.h> - -#define IETF_VENDOR_ID 0x000000 /* 0 */ -#define MICROSOFT_VENDOR_ID 0x000137 /* 311 */ -#define OSC_VENDOR_ID 0x002358 /* 9048 */ -#define FHH_VENDOR_ID 0x0080ab /* 32939 */ -#define ITA_VENDOR_ID 0x00902a /* 36906 */ -#define RESERVED_VENDOR_ID 0xffffff /* 16777215 */ - -typedef enum tnccs_type_t tnccs_type_t; - -/** - * Type of TNC Client/Server protocol - */ -enum tnccs_type_t { - TNCCS_UNKNOWN, - TNCCS_1_1, - TNCCS_SOH, - TNCCS_2_0, - TNCCS_DYNAMIC -}; - -/** - * enum names for tnccs_type_t. - */ -extern enum_name_t *tnccs_type_names; - -typedef struct tnccs_t tnccs_t; - -/** - * Constructor definition for a pluggable TNCCS protocol implementation. - * - * @param is_server TRUE if TNC Server, FALSE if TNC Client - * @return implementation of the tnccs_t interface - */ -typedef tnccs_t* (*tnccs_constructor_t)(bool is_server); - -/** - * Callback function adding a message to a TNCCS batch - * - * @param imc_id ID of IMC or TNC_IMCID_ANY - * @param imc_id ID of IMV or TNC_IMVID_ANY - * @param msg message to be added - * @param msg_len message length - * @param msg_type message type - * @return result code - */ -typedef TNC_Result (*tnccs_send_message_t)(tnccs_t* tncss, TNC_IMCID imc_id, - TNC_IMVID imv_id, - TNC_BufferReference msg, - TNC_UInt32 msg_len, - TNC_MessageType msg_type); - -#endif /** TNCCS_H_ @}*/ diff --git a/src/libcharon/tnc/tnccs/tnccs_manager.h b/src/libcharon/tnc/tnccs/tnccs_manager.h deleted file mode 100644 index 34f60029d..000000000 --- a/src/libcharon/tnc/tnccs/tnccs_manager.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2010 Andreas Steffen - * HSR 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 tnccs_manager tnccs_manager - * @{ @ingroup tnccs - */ - -#ifndef TNCCS_MANAGER_H_ -#define TNCCS_MANAGER_H_ - -#include "tnccs.h" - -#include <tnc/imv/imv_recommendations.h> - -typedef struct tnccs_manager_t tnccs_manager_t; - -/** - * The TNCCS manager manages all TNCCS implementations and creates instances. - * - * A plugin registers its implemented TNCCS protocol with the manager by - * providing type and a constructor function. The manager then creates - * TNCCS protocol instances via the provided constructor. - */ -struct tnccs_manager_t { - - /** - * Register a TNCCS protocol implementation. - * - * @param type TNCCS protocol type - * @param constructor constructor, returns a TNCCS protocol implementation - */ - void (*add_method)(tnccs_manager_t *this, tnccs_type_t type, - tnccs_constructor_t constructor); - - /** - * Unregister a TNCCS protocol implementation using it's constructor. - * - * @param constructor constructor function to remove, as added in add_method - */ - void (*remove_method)(tnccs_manager_t *this, tnccs_constructor_t constructor); - - /** - * Create a new TNCCS protocol instance. - * - * @param type type of the TNCCS protocol - * @param is_server TRUE if TNC Server, FALSE if TNC Client - * @return TNCCS protocol instance, NULL if no constructor found - */ - tnccs_t* (*create_instance)(tnccs_manager_t *this, tnccs_type_t type, - bool is_server); - - /** - * Create a TNCCS connection and assign a unique connection ID as well a - * callback function for adding a message to a TNCCS batch and create - * an empty set for collecting IMV recommendations - * - * @param tnccs TNCCS connection instance - * @param send_message TNCCS callback function - * @param request_handshake_retry pointer to boolean variable - * @param recs pointer to IMV recommendation set - * @return assigned connection ID - */ - TNC_ConnectionID (*create_connection)(tnccs_manager_t *this, tnccs_t *tnccs, - tnccs_send_message_t send_message, - bool *request_handshake_retry, - recommendations_t **recs); - - /** - * Remove a TNCCS connection using its connection ID. - * - * @param id ID of the connection to be removed - * @param is_server TNC Server if TRUE, TNC Client if FALSE - */ - void (*remove_connection)(tnccs_manager_t *this, TNC_ConnectionID id, - bool is_server); - - /** - * Request a handshake retry - * - * @param is_imc TRUE if IMC, FALSE if IMV - * @param imcv_id ID of IMC or IMV requesting the retry - * @param id ID of a specific connection or any connection - * @param reason reason for the handshake retry - * @return return code - */ - TNC_Result (*request_handshake_retry)(tnccs_manager_t *this, bool is_imc, - TNC_UInt32 imcv_id, - TNC_ConnectionID id, - TNC_RetryReason reason); - - /** - * Add an IMC/IMV message to the batch of a given connection ID. - * - * @param imc_id ID of IMC or TNC_IMCID_ANY - * @param imv_id ID of IMV or TNC_IMVID_ANY - * @param id ID of target connection - * @param msg message to be added - * @param msg_len message length - * @param msg_type message type - * @return return code - */ - TNC_Result (*send_message)(tnccs_manager_t *this, TNC_IMCID imc_id, - TNC_IMVID imv_id, - TNC_ConnectionID id, - TNC_BufferReference msg, - TNC_UInt32 msg_len, - TNC_MessageType msg_type); - - /** - * Deliver an IMV Action Recommendation and IMV Evaluation Result to the TNCS - * - * @param imv_id ID of the IMV providing the recommendation - * @param id ID of target connection - * @param rec action recommendation - * @param eval evaluation result - * @return return code - */ - TNC_Result (*provide_recommendation)(tnccs_manager_t *this, - TNC_IMVID imv_id, - TNC_ConnectionID id, - TNC_IMV_Action_Recommendation rec, - TNC_IMV_Evaluation_Result eval); - - /** - * Get the value of an attribute associated with a connection or with the - * TNCS as a whole. - * - * @param imv_id ID of the IMV requesting the attribute - * @param id ID of target connection - * @param attribute_id ID of the requested attribute - * @param buffer_len length of the buffer in bytes - * @param buffer pointer to the buffer - * @param out_value_len actual length of the returned attribute - * @return return code - */ - TNC_Result (*get_attribute)(tnccs_manager_t *this, - TNC_IMVID imv_id, - TNC_ConnectionID id, - TNC_AttributeID attribute_id, - TNC_UInt32 buffer_len, - TNC_BufferReference buffer, - TNC_UInt32 *out_value_len); - - /** - * Set the value of an attribute associated with a connection or with the - * TNCS as a whole. - * - * @param imv_id ID of the IMV setting the attribute - * @param id ID of target connection - * @param attribute_id ID of the attribute to be set - * @param buffer_len length of the buffer in bytes - * @param buffer pointer to the buffer - * @return return code - */ - TNC_Result (*set_attribute)(tnccs_manager_t *this, - TNC_IMVID imv_id, - TNC_ConnectionID id, - TNC_AttributeID attribute_id, - TNC_UInt32 buffer_len, - TNC_BufferReference buffer); - - /** - * Destroy a tnccs_manager instance. - */ - void (*destroy)(tnccs_manager_t *this); -}; - -/** - * Create a tnccs_manager instance. - */ -tnccs_manager_t *tnccs_manager_create(); - -#endif /** TNCCS_MANAGER_H_ @}*/ diff --git a/src/libcharon/tnc/tncif.h b/src/libcharon/tnc/tncif.h deleted file mode 100644 index 99441a9a9..000000000 --- a/src/libcharon/tnc/tncif.h +++ /dev/null @@ -1,106 +0,0 @@ -/* tncif.h - * - * Trusted Network Connect IF-IMV API version 1.20 - * Microsoft Windows DLL Platform Binding C Header - * February 5, 2007 - * - * Copyright(c) 2005-2007, Trusted Computing Group, Inc. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - Neither the name of the Trusted Computing Group nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Contact the Trusted Computing Group at - * admin@trustedcomputinggroup.org for information on specification - * licensing through membership agreements. - * - * Any marks and brands contained herein are the property of their - * respective owners. - * - * Trusted Network Connect IF-IMC/IF-IMV API version 1.00 Revision 3 - * Microsoft Windows DLL Platform Binding C Header - * Common definitions for IF-IMC and IF-IMV - * extracted from tncifimc.h and tncifimv.h - * Feb 12, 2007 - */ - -/** - * @defgroup tnc tnc - * @ingroup libcharon - * - * @defgroup tncif tncif - * @{ @ingroup tnc - */ - -#ifndef TNCIF_H_ -#define TNCIF_H_ - -/* Basic Types */ -typedef unsigned long TNC_UInt32; -typedef unsigned char *TNC_BufferReference; - -/* Derived Types */ -typedef TNC_UInt32 TNC_ConnectionID; -typedef TNC_UInt32 TNC_ConnectionState; -typedef TNC_UInt32 TNC_RetryReason; -typedef TNC_UInt32 TNC_MessageType; -typedef TNC_MessageType *TNC_MessageTypeList; -typedef TNC_UInt32 TNC_VendorID; -typedef TNC_UInt32 TNC_MessageSubtype; -typedef TNC_UInt32 TNC_Version; -typedef TNC_UInt32 TNC_Result; - -/* Result Codes */ -#define TNC_RESULT_SUCCESS 0 -#define TNC_RESULT_NOT_INITIALIZED 1 -#define TNC_RESULT_ALREADY_INITIALIZED 2 -#define TNC_RESULT_NO_COMMON_VERSION 3 -#define TNC_RESULT_CANT_RETRY 4 -#define TNC_RESULT_WONT_RETRY 5 -#define TNC_RESULT_INVALID_PARAMETER 6 -#define TNC_RESULT_CANT_RESPOND 7 -#define TNC_RESULT_ILLEGAL_OPERATION 8 -#define TNC_RESULT_OTHER 9 -#define TNC_RESULT_FATAL 10 - -/* Network Connection ID Values */ -#define TNC_CONNECTIONID_ANY 0xFFFFFFFF -/* Network Connection State Values */ -#define TNC_CONNECTION_STATE_CREATE 0 -#define TNC_CONNECTION_STATE_HANDSHAKE 1 -#define TNC_CONNECTION_STATE_ACCESS_ALLOWED 2 -#define TNC_CONNECTION_STATE_ACCESS_ISOLATED 3 -#define TNC_CONNECTION_STATE_ACCESS_NONE 4 -#define TNC_CONNECTION_STATE_DELETE 5 - -/* Vendor ID Values */ -#define TNC_VENDORID_TCG 0 -#define TNC_VENDORID_ANY ((TNC_VendorID) 0xffffff) -/* Message Subtype Values */ -#define TNC_SUBTYPE_ANY ((TNC_MessageSubtype) 0xff) - -#endif /** TNCIF_H_ @}*/ diff --git a/src/libcharon/tnc/tncifimc.h b/src/libcharon/tnc/tncifimc.h deleted file mode 100644 index c6ddabd45..000000000 --- a/src/libcharon/tnc/tncifimc.h +++ /dev/null @@ -1,180 +0,0 @@ -/* tncifimc.h - * - * Trusted Network Connect IF-IMC API version 1.20 Revision 8 - * Microsoft Windows DLL Platform Binding C Header - * February 5, 2007 - * - * Copyright(c) 2005-2007, Trusted Computing Group, Inc. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - Neither the name of the Trusted Computing Group nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Contact the Trusted Computing Group at - * admin@trustedcomputinggroup.org for information on specification - * licensing through membership agreements. - * - * Any marks and brands contained herein are the property of their - * respective owners. - * - */ - -/** - * @defgroup tncifimc tncifimc - * @{ @ingroup tnc - */ - -#ifndef TNCIFIMC_H_ -#define TNCIFIMC_H_ - -#include "tncif.h" - -/* Derived Types */ - -typedef TNC_UInt32 TNC_IMCID; - -/* Function pointers */ - -typedef TNC_Result (*TNC_IMC_InitializePointer)( - TNC_IMCID imcID, - TNC_Version minVersion, - TNC_Version maxVersion, - TNC_Version *pOutActualVersion); -typedef TNC_Result (*TNC_IMC_NotifyConnectionChangePointer)( - TNC_IMCID imcID, - TNC_ConnectionID connectionID, - TNC_ConnectionState newState); -typedef TNC_Result (*TNC_IMC_BeginHandshakePointer)( - TNC_IMCID imcID, - TNC_ConnectionID connectionID); -typedef TNC_Result (*TNC_IMC_ReceiveMessagePointer)( - TNC_IMCID imcID, - TNC_ConnectionID connectionID, - TNC_BufferReference message, - TNC_UInt32 messageLength, - TNC_MessageType messageType); -typedef TNC_Result (*TNC_IMC_BatchEndingPointer)( - TNC_IMCID imcID, - TNC_ConnectionID connectionID); -typedef TNC_Result (*TNC_IMC_TerminatePointer)( - TNC_IMCID imcID); -typedef TNC_Result (*TNC_TNCC_ReportMessageTypesPointer)( - TNC_IMCID imcID, - TNC_MessageTypeList supportedTypes, - TNC_UInt32 typeCount); -typedef TNC_Result (*TNC_TNCC_SendMessagePointer)( - TNC_IMCID imcID, - TNC_ConnectionID connectionID, - TNC_BufferReference message, - TNC_UInt32 messageLength, - TNC_MessageType messageType); -typedef TNC_Result (*TNC_TNCC_RequestHandshakeRetryPointer)( - TNC_IMCID imcID, - TNC_ConnectionID connectionID, - TNC_RetryReason reason); -typedef TNC_Result (*TNC_TNCC_BindFunctionPointer)( - TNC_IMCID imcID, - char *functionName, - void **pOutfunctionPointer); -typedef TNC_Result (*TNC_IMC_ProvideBindFunctionPointer)( - TNC_IMCID imcID, - TNC_TNCC_BindFunctionPointer bindFunction); - -#define TNC_IFIMC_VERSION_1 1 - -/* Handshake Retry Reason Values */ - -#define TNC_RETRY_REASON_IMC_REMEDIATION_COMPLETE 0 -#define TNC_RETRY_REASON_IMC_SERIOUS_EVENT 1 -#define TNC_RETRY_REASON_IMC_INFORMATIONAL_EVENT 2 -#define TNC_RETRY_REASON_IMC_PERIODIC 3 -/* reserved for TNC_RETRY_REASON_IMV_IMPORTANT_POLICY_CHANGE: 4 */ -/* reserved for TNC_RETRY_REASON_IMV_MINOR_POLICY_CHANGE: 5 */ -/* reserved for TNC_RETRY_REASON_IMV_SERIOUS_EVENT: 6 */ -/* reserved for TNC_RETRY_REASON_IMV_MINOR_EVENT: 7 */ -/* reserved for TNC_RETRY_REASON_IMV_PERIODIC: 8 */ - -/* IMC Functions */ - -TNC_Result TNC_IMC_Initialize( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_Version minVersion, -/*in*/ TNC_Version maxVersion, -/*out*/ TNC_Version *pOutActualVersion); - -TNC_Result TNC_IMC_NotifyConnectionChange( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_ConnectionState newState); - -TNC_Result TNC_IMC_BeginHandshake( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_ConnectionID connectionID); - -TNC_Result TNC_IMC_ReceiveMessage( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_BufferReference messageBuffer, -/*in*/ TNC_UInt32 messageLength, -/*in*/ TNC_MessageType messageType); - -TNC_Result TNC_IMC_BatchEnding( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_ConnectionID connectionID); - -TNC_Result TNC_IMC_Terminate( -/*in*/ TNC_IMCID imcID); - -TNC_Result TNC_IMC_ProvideBindFunction( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_TNCC_BindFunctionPointer bindFunction); - -/* TNC Client Functions */ - -TNC_Result TNC_TNCC_ReportMessageTypes( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_MessageTypeList supportedTypes, -/*in*/ TNC_UInt32 typeCount); - -TNC_Result TNC_TNCC_SendMessage( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_BufferReference message, -/*in*/ TNC_UInt32 messageLength, -/*in*/ TNC_MessageType messageType); - -TNC_Result TNC_TNCC_RequestHandshakeRetry( -/*in*/ TNC_IMCID imcID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_RetryReason reason); - -TNC_Result TNC_TNCC_BindFunction( -/*in*/ TNC_IMCID imcID, -/*in*/ char *functionName, -/*out*/ void **pOutfunctionPointer); - -#endif /** TNCIFIMC_H_ @}*/ diff --git a/src/libcharon/tnc/tncifimv.h b/src/libcharon/tnc/tncifimv.h deleted file mode 100644 index 4ec101337..000000000 --- a/src/libcharon/tnc/tncifimv.h +++ /dev/null @@ -1,248 +0,0 @@ -/* tncifimv.h - * - * Trusted Network Connect IF-IMV API version 1.20 - * Microsoft Windows DLL Platform Binding C Header - * February 5, 2007 - * - * Copyright(c) 2005-2007, Trusted Computing Group, Inc. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - Neither the name of the Trusted Computing Group nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Contact the Trusted Computing Group at - * admin@trustedcomputinggroup.org for information on specification - * licensing through membership agreements. - * - * Any marks and brands contained herein are the property of their - * respective owners. - */ - -/** - * @defgroup tncifimv tncifimv - * @{ @ingroup tnc - */ - -#ifndef TNCIFIMV_H_ -#define TNCIFIMV_H_ - -#include "tncif.h" - -#include <library.h> - -typedef TNC_UInt32 TNC_IMVID; -typedef TNC_UInt32 TNC_IMV_Action_Recommendation; -typedef TNC_UInt32 TNC_IMV_Evaluation_Result; -typedef TNC_UInt32 TNC_AttributeID; - -/* Function pointers */ - -typedef TNC_Result (*TNC_IMV_InitializePointer)( - TNC_IMVID imvID, - TNC_Version minVersion, - TNC_Version maxVersion, - TNC_Version *pOutActualVersion); -typedef TNC_Result (*TNC_IMV_NotifyConnectionChangePointer)( - TNC_IMVID imvID, - TNC_ConnectionID connectionID, - TNC_ConnectionState newState); -typedef TNC_Result (*TNC_IMV_ReceiveMessagePointer)( - TNC_IMVID imvID, - TNC_ConnectionID connectionID, - TNC_BufferReference message, - TNC_UInt32 messageLength, - TNC_MessageType messageType); -typedef TNC_Result (*TNC_IMV_SolicitRecommendationPointer)( - TNC_IMVID imvID, - TNC_ConnectionID connectionID); -typedef TNC_Result (*TNC_IMV_BatchEndingPointer)( - TNC_IMVID imvID, - TNC_ConnectionID connectionID); -typedef TNC_Result (*TNC_IMV_TerminatePointer)( - TNC_IMVID imvID); -typedef TNC_Result (*TNC_TNCS_ReportMessageTypesPointer)( - TNC_IMVID imvID, - TNC_MessageTypeList supportedTypes, - TNC_UInt32 typeCount); -typedef TNC_Result (*TNC_TNCS_SendMessagePointer)( - TNC_IMVID imvID, - TNC_ConnectionID connectionID, - TNC_BufferReference message, - TNC_UInt32 messageLength, - TNC_MessageType messageType); -typedef TNC_Result (*TNC_TNCS_RequestHandshakeRetryPointer)( - TNC_IMVID imvID, - TNC_ConnectionID connectionID, - TNC_RetryReason reason); -typedef TNC_Result (*TNC_TNCS_ProvideRecommendationPointer)( - TNC_IMVID imvID, - TNC_ConnectionID connectionID, - TNC_IMV_Action_Recommendation recommendation, - TNC_IMV_Evaluation_Result evaluation); -typedef TNC_Result (*TNC_TNCS_GetAttributePointer)( - TNC_IMVID imvID, -TNC_ConnectionID connectionID, -TNC_AttributeID attributeID, - TNC_UInt32 bufferLength, - TNC_BufferReference buffer, - TNC_UInt32 *pOutValueLength); -typedef TNC_Result (*TNC_TNCS_SetAttributePointer)( - TNC_IMVID imvID, - TNC_ConnectionID connectionID, -TNC_AttributeID attributeID, - TNC_UInt32 bufferLength, - TNC_BufferReference buffer); -typedef TNC_Result (*TNC_TNCS_BindFunctionPointer)( - TNC_IMVID imvID, - char *functionName, - void **pOutfunctionPointer); -typedef TNC_Result (*TNC_IMV_ProvideBindFunctionPointer)( - TNC_IMVID imvID, - TNC_TNCS_BindFunctionPointer bindFunction); - -/* Version Numbers */ - -#define TNC_IFIMV_VERSION_1 1 - -/* Handshake Retry Reason Values */ - -/* reserved for TNC_RETRY_REASON_IMC_REMEDIATION_COMPLETE: 0 */ -/* reserved for TNC_RETRY_REASON_IMC_SERIOUS_EVENT: 1 */ -/* reserved for TNC_RETRY_REASON_IMC_INFORMATIONAL_EVENT: 2 */ -/* reserved for TNC_RETRY_REASON_IMC_PERIODIC: 3 */ -#define TNC_RETRY_REASON_IMV_IMPORTANT_POLICY_CHANGE 4 -#define TNC_RETRY_REASON_IMV_MINOR_POLICY_CHANGE 5 -#define TNC_RETRY_REASON_IMV_SERIOUS_EVENT 6 -#define TNC_RETRY_REASON_IMV_MINOR_EVENT 7 -#define TNC_RETRY_REASON_IMV_PERIODIC 8 - -/* IMV Action Recommendation Values */ - -#define TNC_IMV_ACTION_RECOMMENDATION_ALLOW 0 -#define TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS 1 -#define TNC_IMV_ACTION_RECOMMENDATION_ISOLATE 2 -#define TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION 3 - -extern enum_name_t *TNC_IMV_Action_Recommendation_names; - -/* IMV Evaluation Result Values */ - -#define TNC_IMV_EVALUATION_RESULT_COMPLIANT 0 -#define TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR 1 -#define TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR 2 -#define TNC_IMV_EVALUATION_RESULT_ERROR 3 -#define TNC_IMV_EVALUATION_RESULT_DONT_KNOW 4 - -extern enum_name_t *TNC_IMV_Evaluation_Result_names; - -/* Message Attribute ID Values */ - -#define TNC_ATTRIBUTEID_PREFERRED_LANGUAGE ((TNC_AttributeID) 0x00000001) -#define TNC_ATTRIBUTEID_REASON_STRING ((TNC_AttributeID) 0x00000002) -#define TNC_ATTRIBUTEID_REASON_LANGUAGE ((TNC_AttributeID) 0x00000003) - -/* IMV Functions */ - -TNC_Result TNC_IMV_Initialize( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_Version minVersion, -/*in*/ TNC_Version maxVersion, -/*in*/ TNC_Version *pOutActualVersion); - -TNC_Result TNC_IMV_NotifyConnectionChange( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_ConnectionState newState); - -TNC_Result TNC_IMV_ReceiveMessage( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_BufferReference messageBuffer, -/*in*/ TNC_UInt32 messageLength, -/*in*/ TNC_MessageType messageType); - -TNC_Result TNC_IMV_SolicitRecommendation( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID); - -TNC_Result TNC_IMV_BatchEnding( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID); - -TNC_Result TNC_IMV_Terminate( -/*in*/ TNC_IMVID imvID); - -TNC_Result TNC_IMV_ProvideBindFunction( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_TNCS_BindFunctionPointer bindFunction); - -/* TNC Server Functions */ - -TNC_Result TNC_TNCS_ReportMessageTypes( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_MessageTypeList supportedTypes, -/*in*/ TNC_UInt32 typeCount); - -TNC_Result TNC_TNCS_SendMessage( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_BufferReference message, -/*in*/ TNC_UInt32 messageLength, -/*in*/ TNC_MessageType messageType); - -TNC_Result TNC_TNCS_RequestHandshakeRetry( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_RetryReason reason); - -TNC_Result TNC_TNCS_ProvideRecommendation( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_IMV_Action_Recommendation recommendation, -/*in*/ TNC_IMV_Evaluation_Result evaluation); - -TNC_Result TNC_TNCS_GetAttribute( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_AttributeID attributeID, -/*in*/ TNC_UInt32 bufferLength, -/*out*/ TNC_BufferReference buffer, -/*out*/ TNC_UInt32 *pOutValueLength); - -TNC_Result TNC_TNCS_SetAttribute( -/*in*/ TNC_IMVID imvID, -/*in*/ TNC_ConnectionID connectionID, -/*in*/ TNC_AttributeID attributeID, -/*in*/ TNC_UInt32 bufferLength, -/*in*/ TNC_BufferReference buffer); - -TNC_Result TNC_TNCS_BindFunction( -/*in*/ TNC_IMVID imvID, -/*in*/ char *functionName, -/*in*/ void **pOutfunctionPointer); - -#endif /** TNCIFIMV_H_ @}*/ |