diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-11-28 11:42:20 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-11-28 11:42:20 +0000 |
commit | f73fba54dc8b30c6482e1e8abf15bbf455592fcd (patch) | |
tree | a449515607c5e51a5c703d7a9b1149c9e4a11560 /src/libcharon | |
parent | b8064f4099997a9e2179f3ad4ace605f5ccac3a1 (diff) | |
download | vyos-strongswan-f73fba54dc8b30c6482e1e8abf15bbf455592fcd.tar.gz vyos-strongswan-f73fba54dc8b30c6482e1e8abf15bbf455592fcd.zip |
[svn-upgrade] new version strongswan (4.5.0)
Diffstat (limited to 'src/libcharon')
255 files changed, 12049 insertions, 17333 deletions
diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk index 3297654e9..21a2b8ee6 100644 --- a/src/libcharon/Android.mk +++ b/src/libcharon/Android.mk @@ -40,16 +40,12 @@ encoding/payloads/transform_substructure.c encoding/payloads/transform_substruct 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_interface.c kernel/kernel_interface.h \ -kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ -kernel/kernel_net.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 \ -processing/jobs/job.h \ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \ -processing/jobs/callback_job.c processing/jobs/callback_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 \ processing/jobs/migrate_job.c processing/jobs/migrate_job.h \ @@ -62,8 +58,6 @@ processing/jobs/send_keepalive_job.c processing/jobs/send_keepalive_job.h \ processing/jobs/roam_job.c processing/jobs/roam_job.h \ processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \ processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \ -processing/scheduler.c processing/scheduler.h \ -processing/processor.c processing/processor.h \ 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 \ @@ -94,7 +88,9 @@ 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 +sa/tasks/task.c sa/tasks/task.h \ +tnccs/tnccs.c tnccs/tnccs.h \ +tnccs/tnccs_manager.h tnccs/tnccs_manager.c # adding the plugin source files @@ -141,10 +137,6 @@ LOCAL_SRC_FILES += $(addprefix ../libsimaka/, \ ) endif -LOCAL_SRC_FILES += $(call add_plugin, kernel-netlink) - -LOCAL_SRC_FILES += $(call add_plugin, kernel-pfkey) - LOCAL_SRC_FILES += $(call add_plugin, load-tester) LOCAL_SRC_FILES += $(call add_plugin, socket-default) diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index 44501c0d0..2b7646327 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -38,16 +38,12 @@ encoding/payloads/transform_substructure.c encoding/payloads/transform_substruct 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_interface.c kernel/kernel_interface.h \ -kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ -kernel/kernel_net.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 \ -processing/jobs/job.h \ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \ -processing/jobs/callback_job.c processing/jobs/callback_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 \ processing/jobs/migrate_job.c processing/jobs/migrate_job.h \ @@ -60,8 +56,6 @@ processing/jobs/send_keepalive_job.c processing/jobs/send_keepalive_job.h \ processing/jobs/roam_job.c processing/jobs/roam_job.h \ processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \ processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \ -processing/scheduler.c processing/scheduler.h \ -processing/processor.c processing/processor.h \ 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 \ @@ -92,7 +86,9 @@ 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 +sa/tasks/task.c sa/tasks/task.h \ +tnccs/tnccs.c tnccs/tnccs.h \ +tnccs/tnccs_manager.h tnccs/tnccs_manager.c daemon.lo : $(top_builddir)/config.status @@ -104,7 +100,8 @@ INCLUDES = \ AM_CFLAGS = \ -DIPSEC_DIR=\"${ipsecdir}\" \ - -DIPSEC_PIDDIR=\"${piddir}\" + -DIPSEC_PIDDIR=\"${piddir}\" \ + -DPLUGINS=\""${libcharon_plugins}\"" libcharon_la_LIBADD = -lm $(PTHREADLIB) $(DLLIB) $(SOCKLIB) @@ -135,51 +132,15 @@ else SUBDIRS = . endif -PLUGINS = ${libstrongswan_plugins} ${libhydra_plugins} - if USE_LOAD_TESTER SUBDIRS += plugins/load_tester - PLUGINS += load-tester if MONOLITHIC libcharon_la_LIBADD += plugins/load_tester/libstrongswan-load-tester.la endif endif -if USE_KERNEL_PFKEY - SUBDIRS += plugins/kernel_pfkey - PLUGINS += kernel-pfkey -if MONOLITHIC - libcharon_la_LIBADD += plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la -endif -endif - -if USE_KERNEL_PFROUTE - SUBDIRS += plugins/kernel_pfroute - PLUGINS += kernel-pfroute -if MONOLITHIC - libcharon_la_LIBADD += plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la -endif -endif - -if USE_KERNEL_KLIPS - SUBDIRS += plugins/kernel_klips - PLUGINS += kernel-klips -if MONOLITHIC - libcharon_la_LIBADD += plugins/kernel_klips/libstrongswan-kernel-klips.la -endif -endif - -if USE_KERNEL_NETLINK - SUBDIRS += plugins/kernel_netlink - PLUGINS += kernel-netlink -if MONOLITHIC - libcharon_la_LIBADD += plugins/kernel_netlink/libstrongswan-kernel-netlink.la -endif -endif - if USE_SOCKET_DEFAULT SUBDIRS += plugins/socket_default - PLUGINS += socket-default if MONOLITHIC libcharon_la_LIBADD += plugins/socket_default/libstrongswan-socket-default.la endif @@ -187,7 +148,6 @@ endif if USE_SOCKET_RAW SUBDIRS += plugins/socket_raw - PLUGINS += socket-raw if MONOLITHIC libcharon_la_LIBADD += plugins/socket_raw/libstrongswan-socket-raw.la endif @@ -195,7 +155,6 @@ endif if USE_SOCKET_DYNAMIC SUBDIRS += plugins/socket_dynamic - PLUGINS += socket-dynamic if MONOLITHIC libcharon_la_LIBADD += plugins/socket_dynamic/libstrongswan-socket-dynamic.la endif @@ -203,7 +162,6 @@ endif if USE_FARP SUBDIRS += plugins/farp - PLUGINS += farp if MONOLITHIC libcharon_la_LIBADD += plugins/farp/libstrongswan-farp.la endif @@ -211,7 +169,6 @@ endif if USE_STROKE SUBDIRS += plugins/stroke - PLUGINS += stroke if MONOLITHIC libcharon_la_LIBADD += plugins/stroke/libstrongswan-stroke.la endif @@ -219,7 +176,6 @@ endif if USE_SMP SUBDIRS += plugins/smp - PLUGINS += smp if MONOLITHIC libcharon_la_LIBADD += plugins/smp/libstrongswan-smp.la endif @@ -227,7 +183,6 @@ endif if USE_SQL SUBDIRS += plugins/sql - PLUGINS += sql if MONOLITHIC libcharon_la_LIBADD += plugins/sql/libstrongswan-sql.la endif @@ -235,7 +190,6 @@ endif if USE_UPDOWN SUBDIRS += plugins/updown - PLUGINS += updown if MONOLITHIC libcharon_la_LIBADD += plugins/updown/libstrongswan-updown.la endif @@ -243,7 +197,6 @@ endif if USE_EAP_IDENTITY SUBDIRS += plugins/eap_identity - PLUGINS += eap-identity if MONOLITHIC libcharon_la_LIBADD += plugins/eap_identity/libstrongswan-eap-identity.la endif @@ -251,7 +204,6 @@ endif if USE_EAP_SIM SUBDIRS += plugins/eap_sim - PLUGINS += eap-sim if MONOLITHIC libcharon_la_LIBADD += plugins/eap_sim/libstrongswan-eap-sim.la endif @@ -259,7 +211,6 @@ endif if USE_EAP_SIM_FILE SUBDIRS += plugins/eap_sim_file - PLUGINS += eap-sim-file if MONOLITHIC libcharon_la_LIBADD += plugins/eap_sim_file/libstrongswan-eap-sim-file.la endif @@ -267,7 +218,6 @@ endif if USE_EAP_SIMAKA_SQL SUBDIRS += plugins/eap_simaka_sql - PLUGINS += eap-simaka-sql if MONOLITHIC libcharon_la_LIBADD += plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la endif @@ -275,7 +225,6 @@ endif if USE_EAP_SIMAKA_PSEUDONYM SUBDIRS += plugins/eap_simaka_pseudonym - PLUGINS += eap-simaka-pseudonym if MONOLITHIC libcharon_la_LIBADD += plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la endif @@ -283,7 +232,6 @@ endif if USE_EAP_SIMAKA_REAUTH SUBDIRS += plugins/eap_simaka_reauth - PLUGINS += eap-simaka-reauth if MONOLITHIC libcharon_la_LIBADD += plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la endif @@ -291,7 +239,6 @@ endif if USE_EAP_AKA SUBDIRS += plugins/eap_aka - PLUGINS += eap-aka if MONOLITHIC libcharon_la_LIBADD += plugins/eap_aka/libstrongswan-eap-aka.la endif @@ -299,7 +246,6 @@ endif if USE_EAP_AKA_3GPP2 SUBDIRS += plugins/eap_aka_3gpp2 - PLUGINS += eap-aka-3gpp2 if MONOLITHIC libcharon_la_LIBADD += plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la endif @@ -314,7 +260,6 @@ endif if USE_EAP_MD5 SUBDIRS += plugins/eap_md5 - PLUGINS += eap-md5 if MONOLITHIC libcharon_la_LIBADD += plugins/eap_md5/libstrongswan-eap-md5.la endif @@ -322,7 +267,6 @@ endif if USE_EAP_GTC SUBDIRS += plugins/eap_gtc - PLUGINS += eap-gtc if MONOLITHIC libcharon_la_LIBADD += plugins/eap_gtc/libstrongswan-eap-gtc.la endif @@ -330,7 +274,6 @@ endif if USE_EAP_MSCHAPV2 SUBDIRS += plugins/eap_mschapv2 - PLUGINS += eap-mschapv2 if MONOLITHIC libcharon_la_LIBADD += plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la endif @@ -338,15 +281,69 @@ endif if USE_EAP_RADIUS SUBDIRS += plugins/eap_radius - PLUGINS += eap-radius if MONOLITHIC libcharon_la_LIBADD += plugins/eap_radius/libstrongswan-eap-radius.la endif endif +if USE_EAP_TLS + SUBDIRS += plugins/eap_tls +if MONOLITHIC + libcharon_la_LIBADD += plugins/eap_tls/libstrongswan-eap-tls.la +endif +endif + +if USE_EAP_TTLS + SUBDIRS += plugins/eap_ttls +if MONOLITHIC + libcharon_la_LIBADD += plugins/eap_ttls/libstrongswan-eap-ttls.la +endif +endif + +if USE_EAP_TNC + SUBDIRS += plugins/eap_tnc +if MONOLITHIC + libcharon_la_LIBADD += plugins/eap_tnc/libstrongswan-eap-tnc.la +endif +endif + +if USE_TLS +if MONOLITHIC + # otherwise this library is linked to eap_tls + libcharon_la_LIBADD += $(top_builddir)/src/libtls/libtls.la +endif +endif + +if USE_TNC_IMC + SUBDIRS += plugins/tnc_imc +if MONOLITHIC + libcharon_la_LIBADD += plugins/tnc_imc/libstrongswan-tnc_imc.la +endif +endif + +if USE_TNC_IMV + SUBDIRS += plugins/tnc_imv +if MONOLITHIC + libcharon_la_LIBADD += plugins/tnc_imv/libstrongswan-tnc_imv.la +endif +endif + +if USE_TNCCS_11 + SUBDIRS += plugins/tnccs_11 +if MONOLITHIC + libcharon_la_LIBADD += plugins/tnccs_11/libstrongswan-tnccs-11.la +endif +endif + +if USE_TNCCS_20 + SUBDIRS += plugins/tnccs_20 +if MONOLITHIC + libcharon_la_LIBADD += plugins/tnccs_20/libstrongswan-tnccs-20.la +endif +endif + if USE_MEDSRV SUBDIRS += plugins/medsrv - PLUGINS += medsrv if MONOLITHIC libcharon_la_LIBADD += plugins/medsrv/libstrongswan-medsrv.la endif @@ -354,7 +351,6 @@ endif if USE_MEDCLI SUBDIRS += plugins/medcli - PLUGINS += medcli if MONOLITHIC libcharon_la_LIBADD += plugins/medcli/libstrongswan-medcli.la endif @@ -362,7 +358,6 @@ endif if USE_NM SUBDIRS += plugins/nm - PLUGINS += nm if MONOLITHIC libcharon_la_LIBADD += plugins/nm/libstrongswan-nm.la endif @@ -370,7 +365,6 @@ endif if USE_DHCP SUBDIRS += plugins/dhcp - PLUGINS += dhcp if MONOLITHIC libcharon_la_LIBADD += plugins/dhcp/libstrongswan-dhcp.la endif @@ -378,23 +372,34 @@ endif if USE_ANDROID SUBDIRS += plugins/android - PLUGINS += android if MONOLITHIC libcharon_la_LIBADD += plugins/android/libstrongswan-android.la endif endif +if USE_MAEMO + SUBDIRS += plugins/maemo +if MONOLITHIC + libcharon_la_LIBADD += plugins/maemo/libstrongswan-maemo.la +endif +endif + if USE_HA SUBDIRS += plugins/ha - PLUGINS += ha if MONOLITHIC libcharon_la_LIBADD += plugins/ha/libstrongswan-ha.la endif endif +if USE_LED + SUBDIRS += plugins/led +if MONOLITHIC + libcharon_la_LIBADD += plugins/led/libstrongswan-led.la +endif +endif + if USE_UCI SUBDIRS += plugins/uci - PLUGINS += uci if MONOLITHIC libcharon_la_LIBADD += plugins/uci/libstrongswan-uci.la endif @@ -402,7 +407,6 @@ endif if USE_ADDRBLOCK SUBDIRS += plugins/addrblock - PLUGINS += addrblock if MONOLITHIC libcharon_la_LIBADD += plugins/uci/libstrongswan-addrblock.la endif @@ -410,11 +414,8 @@ endif if USE_UNIT_TESTS SUBDIRS += plugins/unit_tester - PLUGINS += unit-tester if MONOLITHIC libcharon_la_LIBADD += plugins/unit_tester/libstrongswan-unit-tester.la endif endif -AM_CFLAGS += -DPLUGINS=\""${PLUGINS}\"" - diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in index 8e58b0e2e..8a7a99ddd 100644 --- a/src/libcharon/Makefile.in +++ b/src/libcharon/Makefile.in @@ -46,108 +46,85 @@ host_triplet = @host@ @USE_LIBCAP_TRUE@am__append_2 = -lcap @USE_LOAD_TESTER_TRUE@am__append_3 = plugins/load_tester -@USE_LOAD_TESTER_TRUE@am__append_4 = load-tester -@MONOLITHIC_TRUE@@USE_LOAD_TESTER_TRUE@am__append_5 = plugins/load_tester/libstrongswan-load-tester.la -@USE_KERNEL_PFKEY_TRUE@am__append_6 = plugins/kernel_pfkey -@USE_KERNEL_PFKEY_TRUE@am__append_7 = kernel-pfkey -@MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE@am__append_8 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la -@USE_KERNEL_PFROUTE_TRUE@am__append_9 = plugins/kernel_pfroute -@USE_KERNEL_PFROUTE_TRUE@am__append_10 = kernel-pfroute -@MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE@am__append_11 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la -@USE_KERNEL_KLIPS_TRUE@am__append_12 = plugins/kernel_klips -@USE_KERNEL_KLIPS_TRUE@am__append_13 = kernel-klips -@MONOLITHIC_TRUE@@USE_KERNEL_KLIPS_TRUE@am__append_14 = plugins/kernel_klips/libstrongswan-kernel-klips.la -@USE_KERNEL_NETLINK_TRUE@am__append_15 = plugins/kernel_netlink -@USE_KERNEL_NETLINK_TRUE@am__append_16 = kernel-netlink -@MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE@am__append_17 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la -@USE_SOCKET_DEFAULT_TRUE@am__append_18 = plugins/socket_default -@USE_SOCKET_DEFAULT_TRUE@am__append_19 = socket-default -@MONOLITHIC_TRUE@@USE_SOCKET_DEFAULT_TRUE@am__append_20 = plugins/socket_default/libstrongswan-socket-default.la -@USE_SOCKET_RAW_TRUE@am__append_21 = plugins/socket_raw -@USE_SOCKET_RAW_TRUE@am__append_22 = socket-raw -@MONOLITHIC_TRUE@@USE_SOCKET_RAW_TRUE@am__append_23 = plugins/socket_raw/libstrongswan-socket-raw.la -@USE_SOCKET_DYNAMIC_TRUE@am__append_24 = plugins/socket_dynamic -@USE_SOCKET_DYNAMIC_TRUE@am__append_25 = socket-dynamic -@MONOLITHIC_TRUE@@USE_SOCKET_DYNAMIC_TRUE@am__append_26 = plugins/socket_dynamic/libstrongswan-socket-dynamic.la -@USE_FARP_TRUE@am__append_27 = plugins/farp -@USE_FARP_TRUE@am__append_28 = farp -@MONOLITHIC_TRUE@@USE_FARP_TRUE@am__append_29 = plugins/farp/libstrongswan-farp.la -@USE_STROKE_TRUE@am__append_30 = plugins/stroke -@USE_STROKE_TRUE@am__append_31 = stroke -@MONOLITHIC_TRUE@@USE_STROKE_TRUE@am__append_32 = plugins/stroke/libstrongswan-stroke.la -@USE_SMP_TRUE@am__append_33 = plugins/smp -@USE_SMP_TRUE@am__append_34 = smp -@MONOLITHIC_TRUE@@USE_SMP_TRUE@am__append_35 = plugins/smp/libstrongswan-smp.la -@USE_SQL_TRUE@am__append_36 = plugins/sql -@USE_SQL_TRUE@am__append_37 = sql -@MONOLITHIC_TRUE@@USE_SQL_TRUE@am__append_38 = plugins/sql/libstrongswan-sql.la -@USE_UPDOWN_TRUE@am__append_39 = plugins/updown -@USE_UPDOWN_TRUE@am__append_40 = updown -@MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_41 = plugins/updown/libstrongswan-updown.la -@USE_EAP_IDENTITY_TRUE@am__append_42 = plugins/eap_identity -@USE_EAP_IDENTITY_TRUE@am__append_43 = eap-identity -@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_44 = plugins/eap_identity/libstrongswan-eap-identity.la -@USE_EAP_SIM_TRUE@am__append_45 = plugins/eap_sim -@USE_EAP_SIM_TRUE@am__append_46 = eap-sim -@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_47 = plugins/eap_sim/libstrongswan-eap-sim.la -@USE_EAP_SIM_FILE_TRUE@am__append_48 = plugins/eap_sim_file -@USE_EAP_SIM_FILE_TRUE@am__append_49 = eap-sim-file -@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_50 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la -@USE_EAP_SIMAKA_SQL_TRUE@am__append_51 = plugins/eap_simaka_sql -@USE_EAP_SIMAKA_SQL_TRUE@am__append_52 = eap-simaka-sql -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_53 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la -@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_54 = plugins/eap_simaka_pseudonym -@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_55 = eap-simaka-pseudonym -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_56 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la -@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_57 = plugins/eap_simaka_reauth -@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_58 = eap-simaka-reauth -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_59 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la -@USE_EAP_AKA_TRUE@am__append_60 = plugins/eap_aka -@USE_EAP_AKA_TRUE@am__append_61 = eap-aka -@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_62 = plugins/eap_aka/libstrongswan-eap-aka.la -@USE_EAP_AKA_3GPP2_TRUE@am__append_63 = plugins/eap_aka_3gpp2 -@USE_EAP_AKA_3GPP2_TRUE@am__append_64 = eap-aka-3gpp2 -@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_65 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la -@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_66 = $(top_builddir)/src/libsimaka/libsimaka.la -@USE_EAP_MD5_TRUE@am__append_67 = plugins/eap_md5 -@USE_EAP_MD5_TRUE@am__append_68 = eap-md5 -@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_69 = plugins/eap_md5/libstrongswan-eap-md5.la -@USE_EAP_GTC_TRUE@am__append_70 = plugins/eap_gtc -@USE_EAP_GTC_TRUE@am__append_71 = eap-gtc -@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_72 = plugins/eap_gtc/libstrongswan-eap-gtc.la -@USE_EAP_MSCHAPV2_TRUE@am__append_73 = plugins/eap_mschapv2 -@USE_EAP_MSCHAPV2_TRUE@am__append_74 = eap-mschapv2 -@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_75 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la -@USE_EAP_RADIUS_TRUE@am__append_76 = plugins/eap_radius -@USE_EAP_RADIUS_TRUE@am__append_77 = eap-radius -@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_78 = plugins/eap_radius/libstrongswan-eap-radius.la -@USE_MEDSRV_TRUE@am__append_79 = plugins/medsrv -@USE_MEDSRV_TRUE@am__append_80 = medsrv -@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_81 = plugins/medsrv/libstrongswan-medsrv.la -@USE_MEDCLI_TRUE@am__append_82 = plugins/medcli -@USE_MEDCLI_TRUE@am__append_83 = medcli -@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_84 = plugins/medcli/libstrongswan-medcli.la -@USE_NM_TRUE@am__append_85 = plugins/nm -@USE_NM_TRUE@am__append_86 = nm -@MONOLITHIC_TRUE@@USE_NM_TRUE@am__append_87 = plugins/nm/libstrongswan-nm.la -@USE_DHCP_TRUE@am__append_88 = plugins/dhcp -@USE_DHCP_TRUE@am__append_89 = dhcp -@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_90 = plugins/dhcp/libstrongswan-dhcp.la -@USE_ANDROID_TRUE@am__append_91 = plugins/android -@USE_ANDROID_TRUE@am__append_92 = android -@MONOLITHIC_TRUE@@USE_ANDROID_TRUE@am__append_93 = plugins/android/libstrongswan-android.la -@USE_HA_TRUE@am__append_94 = plugins/ha -@USE_HA_TRUE@am__append_95 = ha -@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_96 = plugins/ha/libstrongswan-ha.la -@USE_UCI_TRUE@am__append_97 = plugins/uci -@USE_UCI_TRUE@am__append_98 = uci -@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_99 = plugins/uci/libstrongswan-uci.la -@USE_ADDRBLOCK_TRUE@am__append_100 = plugins/addrblock -@USE_ADDRBLOCK_TRUE@am__append_101 = addrblock -@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_102 = plugins/uci/libstrongswan-addrblock.la -@USE_UNIT_TESTS_TRUE@am__append_103 = plugins/unit_tester -@USE_UNIT_TESTS_TRUE@am__append_104 = unit-tester -@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_105 = plugins/unit_tester/libstrongswan-unit-tester.la +@MONOLITHIC_TRUE@@USE_LOAD_TESTER_TRUE@am__append_4 = plugins/load_tester/libstrongswan-load-tester.la +@USE_SOCKET_DEFAULT_TRUE@am__append_5 = plugins/socket_default +@MONOLITHIC_TRUE@@USE_SOCKET_DEFAULT_TRUE@am__append_6 = plugins/socket_default/libstrongswan-socket-default.la +@USE_SOCKET_RAW_TRUE@am__append_7 = plugins/socket_raw +@MONOLITHIC_TRUE@@USE_SOCKET_RAW_TRUE@am__append_8 = plugins/socket_raw/libstrongswan-socket-raw.la +@USE_SOCKET_DYNAMIC_TRUE@am__append_9 = plugins/socket_dynamic +@MONOLITHIC_TRUE@@USE_SOCKET_DYNAMIC_TRUE@am__append_10 = plugins/socket_dynamic/libstrongswan-socket-dynamic.la +@USE_FARP_TRUE@am__append_11 = plugins/farp +@MONOLITHIC_TRUE@@USE_FARP_TRUE@am__append_12 = plugins/farp/libstrongswan-farp.la +@USE_STROKE_TRUE@am__append_13 = plugins/stroke +@MONOLITHIC_TRUE@@USE_STROKE_TRUE@am__append_14 = plugins/stroke/libstrongswan-stroke.la +@USE_SMP_TRUE@am__append_15 = plugins/smp +@MONOLITHIC_TRUE@@USE_SMP_TRUE@am__append_16 = plugins/smp/libstrongswan-smp.la +@USE_SQL_TRUE@am__append_17 = plugins/sql +@MONOLITHIC_TRUE@@USE_SQL_TRUE@am__append_18 = plugins/sql/libstrongswan-sql.la +@USE_UPDOWN_TRUE@am__append_19 = plugins/updown +@MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_20 = plugins/updown/libstrongswan-updown.la +@USE_EAP_IDENTITY_TRUE@am__append_21 = plugins/eap_identity +@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_22 = plugins/eap_identity/libstrongswan-eap-identity.la +@USE_EAP_SIM_TRUE@am__append_23 = plugins/eap_sim +@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_24 = plugins/eap_sim/libstrongswan-eap-sim.la +@USE_EAP_SIM_FILE_TRUE@am__append_25 = plugins/eap_sim_file +@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_26 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la +@USE_EAP_SIMAKA_SQL_TRUE@am__append_27 = plugins/eap_simaka_sql +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_28 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la +@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_29 = plugins/eap_simaka_pseudonym +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_30 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la +@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_31 = plugins/eap_simaka_reauth +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_32 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la +@USE_EAP_AKA_TRUE@am__append_33 = plugins/eap_aka +@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_34 = plugins/eap_aka/libstrongswan-eap-aka.la +@USE_EAP_AKA_3GPP2_TRUE@am__append_35 = plugins/eap_aka_3gpp2 +@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_36 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la +@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_37 = $(top_builddir)/src/libsimaka/libsimaka.la +@USE_EAP_MD5_TRUE@am__append_38 = plugins/eap_md5 +@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_39 = plugins/eap_md5/libstrongswan-eap-md5.la +@USE_EAP_GTC_TRUE@am__append_40 = plugins/eap_gtc +@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_41 = plugins/eap_gtc/libstrongswan-eap-gtc.la +@USE_EAP_MSCHAPV2_TRUE@am__append_42 = plugins/eap_mschapv2 +@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_43 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la +@USE_EAP_RADIUS_TRUE@am__append_44 = plugins/eap_radius +@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_45 = plugins/eap_radius/libstrongswan-eap-radius.la +@USE_EAP_TLS_TRUE@am__append_46 = plugins/eap_tls +@MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE@am__append_47 = plugins/eap_tls/libstrongswan-eap-tls.la +@USE_EAP_TTLS_TRUE@am__append_48 = plugins/eap_ttls +@MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE@am__append_49 = plugins/eap_ttls/libstrongswan-eap-ttls.la +@USE_EAP_TNC_TRUE@am__append_50 = plugins/eap_tnc +@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_51 = plugins/eap_tnc/libstrongswan-eap-tnc.la +@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_52 = $(top_builddir)/src/libtls/libtls.la +@USE_TNC_IMC_TRUE@am__append_53 = plugins/tnc_imc +@MONOLITHIC_TRUE@@USE_TNC_IMC_TRUE@am__append_54 = plugins/tnc_imc/libstrongswan-tnc_imc.la +@USE_TNC_IMV_TRUE@am__append_55 = plugins/tnc_imv +@MONOLITHIC_TRUE@@USE_TNC_IMV_TRUE@am__append_56 = plugins/tnc_imv/libstrongswan-tnc_imv.la +@USE_TNCCS_11_TRUE@am__append_57 = plugins/tnccs_11 +@MONOLITHIC_TRUE@@USE_TNCCS_11_TRUE@am__append_58 = plugins/tnccs_11/libstrongswan-tnccs-11.la +@USE_TNCCS_20_TRUE@am__append_59 = plugins/tnccs_20 +@MONOLITHIC_TRUE@@USE_TNCCS_20_TRUE@am__append_60 = plugins/tnccs_20/libstrongswan-tnccs-20.la +@USE_MEDSRV_TRUE@am__append_61 = plugins/medsrv +@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_62 = plugins/medsrv/libstrongswan-medsrv.la +@USE_MEDCLI_TRUE@am__append_63 = plugins/medcli +@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_64 = plugins/medcli/libstrongswan-medcli.la +@USE_NM_TRUE@am__append_65 = plugins/nm +@MONOLITHIC_TRUE@@USE_NM_TRUE@am__append_66 = plugins/nm/libstrongswan-nm.la +@USE_DHCP_TRUE@am__append_67 = plugins/dhcp +@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_68 = plugins/dhcp/libstrongswan-dhcp.la +@USE_ANDROID_TRUE@am__append_69 = plugins/android +@MONOLITHIC_TRUE@@USE_ANDROID_TRUE@am__append_70 = plugins/android/libstrongswan-android.la +@USE_MAEMO_TRUE@am__append_71 = plugins/maemo +@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_72 = plugins/maemo/libstrongswan-maemo.la +@USE_HA_TRUE@am__append_73 = plugins/ha +@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_74 = plugins/ha/libstrongswan-ha.la +@USE_LED_TRUE@am__append_75 = plugins/led +@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_76 = plugins/led/libstrongswan-led.la +@USE_UCI_TRUE@am__append_77 = plugins/uci +@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_78 = plugins/uci/libstrongswan-uci.la +@USE_ADDRBLOCK_TRUE@am__append_79 = plugins/addrblock +@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_80 = plugins/uci/libstrongswan-addrblock.la +@USE_UNIT_TESTS_TRUE@am__append_81 = plugins/unit_tester +@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_82 = plugins/unit_tester/libstrongswan-unit-tester.la subdir = src/libcharon DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -158,6 +135,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -190,18 +168,20 @@ LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = libcharon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__append_5) $(am__append_8) \ - $(am__append_11) $(am__append_14) $(am__append_17) \ - $(am__append_20) $(am__append_23) $(am__append_26) \ - $(am__append_29) $(am__append_32) $(am__append_35) \ - $(am__append_38) $(am__append_41) $(am__append_44) \ - $(am__append_47) $(am__append_50) $(am__append_53) \ - $(am__append_56) $(am__append_59) $(am__append_62) \ - $(am__append_65) $(am__append_66) $(am__append_69) \ - $(am__append_72) $(am__append_75) $(am__append_78) \ - $(am__append_81) $(am__append_84) $(am__append_87) \ - $(am__append_90) $(am__append_93) $(am__append_96) \ - $(am__append_99) $(am__append_102) $(am__append_105) + $(am__DEPENDENCIES_1) $(am__append_4) $(am__append_6) \ + $(am__append_8) $(am__append_10) $(am__append_12) \ + $(am__append_14) $(am__append_16) $(am__append_18) \ + $(am__append_20) $(am__append_22) $(am__append_24) \ + $(am__append_26) $(am__append_28) $(am__append_30) \ + $(am__append_32) $(am__append_34) $(am__append_36) \ + $(am__append_37) $(am__append_39) $(am__append_41) \ + $(am__append_43) $(am__append_45) $(am__append_47) \ + $(am__append_49) $(am__append_51) $(am__append_52) \ + $(am__append_54) $(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__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 \ @@ -249,16 +229,12 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.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_interface.c kernel/kernel_interface.h \ - kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ - kernel/kernel_net.h network/packet.c network/packet.h \ + 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 \ - processing/jobs/job.h processing/jobs/acquire_job.c \ - processing/jobs/acquire_job.h processing/jobs/callback_job.c \ - processing/jobs/callback_job.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 \ @@ -279,9 +255,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ processing/jobs/update_sa_job.c \ processing/jobs/update_sa_job.h \ processing/jobs/inactivity_job.c \ - processing/jobs/inactivity_job.h processing/scheduler.c \ - processing/scheduler.h processing/processor.c \ - processing/processor.h sa/authenticators/authenticator.c \ + processing/jobs/inactivity_job.h \ + sa/authenticators/authenticator.c \ sa/authenticators/authenticator.h \ sa/authenticators/eap_authenticator.c \ sa/authenticators/eap_authenticator.h \ @@ -313,7 +288,8 @@ 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 \ - encoding/payloads/endpoint_notify.c \ + tnccs/tnccs.c tnccs/tnccs.h tnccs/tnccs_manager.h \ + tnccs/tnccs_manager.c encoding/payloads/endpoint_notify.c \ encoding/payloads/endpoint_notify.h \ processing/jobs/initiate_mediation_job.c \ processing/jobs/initiate_mediation_job.h \ @@ -334,22 +310,21 @@ am_libcharon_la_OBJECTS = bus.lo file_logger.lo sys_logger.lo \ notify_payload.lo payload.lo proposal_substructure.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_interface.lo \ - kernel_ipsec.lo packet.lo receiver.lo sender.lo \ - socket_manager.lo acquire_job.lo callback_job.lo \ - delete_child_sa_job.lo delete_ike_sa_job.lo migrate_job.lo \ - process_message_job.lo rekey_child_sa_job.lo \ + unknown_payload.lo vendor_id_payload.lo kernel_handler.lo \ + packet.lo receiver.lo sender.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 roam_job.lo update_sa_job.lo \ - inactivity_job.lo scheduler.lo processor.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 \ - 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 \ + 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 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 tnccs.lo tnccs_manager.lo \ $(am__objects_1) libcharon_la_OBJECTS = $(am_libcharon_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ @@ -381,18 +356,19 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ distdir ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = . plugins/load_tester plugins/kernel_pfkey \ - plugins/kernel_pfroute plugins/kernel_klips \ - plugins/kernel_netlink plugins/socket_default \ +DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \ plugins/socket_raw plugins/socket_dynamic plugins/farp \ plugins/stroke plugins/smp plugins/sql plugins/updown \ plugins/eap_identity plugins/eap_sim plugins/eap_sim_file \ plugins/eap_simaka_sql plugins/eap_simaka_pseudonym \ plugins/eap_simaka_reauth plugins/eap_aka \ plugins/eap_aka_3gpp2 plugins/eap_md5 plugins/eap_gtc \ - plugins/eap_mschapv2 plugins/eap_radius plugins/medsrv \ - plugins/medcli plugins/nm plugins/dhcp plugins/android \ - plugins/ha plugins/uci plugins/addrblock plugins/unit_tester + plugins/eap_mschapv2 plugins/eap_radius plugins/eap_tls \ + plugins/eap_ttls plugins/eap_tnc plugins/tnc_imc \ + plugins/tnc_imv plugins/tnccs_11 plugins/tnccs_20 \ + plugins/medsrv plugins/medcli plugins/nm plugins/dhcp \ + plugins/android plugins/maemo plugins/ha plugins/led \ + plugins/uci plugins/addrblock plugins/unit_tester DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -484,6 +460,8 @@ 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@ @@ -515,14 +493,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -537,24 +518,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -562,7 +550,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ @@ -622,16 +613,12 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.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_interface.c kernel/kernel_interface.h \ - kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ - kernel/kernel_net.h network/packet.c network/packet.h \ + 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 \ - processing/jobs/job.h processing/jobs/acquire_job.c \ - processing/jobs/acquire_job.h processing/jobs/callback_job.c \ - processing/jobs/callback_job.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 \ @@ -652,9 +639,8 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ processing/jobs/update_sa_job.c \ processing/jobs/update_sa_job.h \ processing/jobs/inactivity_job.c \ - processing/jobs/inactivity_job.h processing/scheduler.c \ - processing/scheduler.h processing/processor.c \ - processing/processor.h sa/authenticators/authenticator.c \ + processing/jobs/inactivity_job.h \ + sa/authenticators/authenticator.c \ sa/authenticators/authenticator.h \ sa/authenticators/eap_authenticator.c \ sa/authenticators/eap_authenticator.h \ @@ -686,78 +672,78 @@ 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 \ - $(am__append_1) + tnccs/tnccs.c tnccs/tnccs.h tnccs/tnccs_manager.h \ + tnccs/tnccs_manager.c $(am__append_1) INCLUDES = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon -AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \ - -DPLUGINS=\""${PLUGINS}\"" +AM_CFLAGS = \ + -DIPSEC_DIR=\"${ipsecdir}\" \ + -DIPSEC_PIDDIR=\"${piddir}\" \ + -DPLUGINS=\""${libcharon_plugins}\"" + libcharon_la_LIBADD = -lm $(PTHREADLIB) $(DLLIB) $(SOCKLIB) \ - $(am__append_2) $(am__append_5) $(am__append_8) \ - $(am__append_11) $(am__append_14) $(am__append_17) \ - $(am__append_20) $(am__append_23) $(am__append_26) \ - $(am__append_29) $(am__append_32) $(am__append_35) \ - $(am__append_38) $(am__append_41) $(am__append_44) \ - $(am__append_47) $(am__append_50) $(am__append_53) \ - $(am__append_56) $(am__append_59) $(am__append_62) \ - $(am__append_65) $(am__append_66) $(am__append_69) \ - $(am__append_72) $(am__append_75) $(am__append_78) \ - $(am__append_81) $(am__append_84) $(am__append_87) \ - $(am__append_90) $(am__append_93) $(am__append_96) \ - $(am__append_99) $(am__append_102) $(am__append_105) + $(am__append_2) $(am__append_4) $(am__append_6) \ + $(am__append_8) $(am__append_10) $(am__append_12) \ + $(am__append_14) $(am__append_16) $(am__append_18) \ + $(am__append_20) $(am__append_22) $(am__append_24) \ + $(am__append_26) $(am__append_28) $(am__append_30) \ + $(am__append_32) $(am__append_34) $(am__append_36) \ + $(am__append_37) $(am__append_39) $(am__append_41) \ + $(am__append_43) $(am__append_45) $(am__append_47) \ + $(am__append_49) $(am__append_51) $(am__append_52) \ + $(am__append_54) $(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) EXTRA_DIST = Android.mk -@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_3) $(am__append_6) \ -@MONOLITHIC_FALSE@ $(am__append_9) $(am__append_12) \ -@MONOLITHIC_FALSE@ $(am__append_15) $(am__append_18) \ -@MONOLITHIC_FALSE@ $(am__append_21) $(am__append_24) \ -@MONOLITHIC_FALSE@ $(am__append_27) $(am__append_30) \ -@MONOLITHIC_FALSE@ $(am__append_33) $(am__append_36) \ -@MONOLITHIC_FALSE@ $(am__append_39) $(am__append_42) \ -@MONOLITHIC_FALSE@ $(am__append_45) $(am__append_48) \ -@MONOLITHIC_FALSE@ $(am__append_51) $(am__append_54) \ -@MONOLITHIC_FALSE@ $(am__append_57) $(am__append_60) \ -@MONOLITHIC_FALSE@ $(am__append_63) $(am__append_67) \ -@MONOLITHIC_FALSE@ $(am__append_70) $(am__append_73) \ -@MONOLITHIC_FALSE@ $(am__append_76) $(am__append_79) \ -@MONOLITHIC_FALSE@ $(am__append_82) $(am__append_85) \ -@MONOLITHIC_FALSE@ $(am__append_88) $(am__append_91) \ -@MONOLITHIC_FALSE@ $(am__append_94) $(am__append_97) \ -@MONOLITHIC_FALSE@ $(am__append_100) $(am__append_103) +@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_3) $(am__append_5) \ +@MONOLITHIC_FALSE@ $(am__append_7) $(am__append_9) \ +@MONOLITHIC_FALSE@ $(am__append_11) $(am__append_13) \ +@MONOLITHIC_FALSE@ $(am__append_15) $(am__append_17) \ +@MONOLITHIC_FALSE@ $(am__append_19) $(am__append_21) \ +@MONOLITHIC_FALSE@ $(am__append_23) $(am__append_25) \ +@MONOLITHIC_FALSE@ $(am__append_27) $(am__append_29) \ +@MONOLITHIC_FALSE@ $(am__append_31) $(am__append_33) \ +@MONOLITHIC_FALSE@ $(am__append_35) $(am__append_38) \ +@MONOLITHIC_FALSE@ $(am__append_40) $(am__append_42) \ +@MONOLITHIC_FALSE@ $(am__append_44) $(am__append_46) \ +@MONOLITHIC_FALSE@ $(am__append_48) $(am__append_50) \ +@MONOLITHIC_FALSE@ $(am__append_53) $(am__append_55) \ +@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) # build optional plugins ######################## -@MONOLITHIC_TRUE@SUBDIRS = $(am__append_3) $(am__append_6) \ -@MONOLITHIC_TRUE@ $(am__append_9) $(am__append_12) \ -@MONOLITHIC_TRUE@ $(am__append_15) $(am__append_18) \ -@MONOLITHIC_TRUE@ $(am__append_21) $(am__append_24) \ -@MONOLITHIC_TRUE@ $(am__append_27) $(am__append_30) \ -@MONOLITHIC_TRUE@ $(am__append_33) $(am__append_36) \ -@MONOLITHIC_TRUE@ $(am__append_39) $(am__append_42) \ -@MONOLITHIC_TRUE@ $(am__append_45) $(am__append_48) \ -@MONOLITHIC_TRUE@ $(am__append_51) $(am__append_54) \ -@MONOLITHIC_TRUE@ $(am__append_57) $(am__append_60) \ -@MONOLITHIC_TRUE@ $(am__append_63) $(am__append_67) \ -@MONOLITHIC_TRUE@ $(am__append_70) $(am__append_73) \ -@MONOLITHIC_TRUE@ $(am__append_76) $(am__append_79) \ -@MONOLITHIC_TRUE@ $(am__append_82) $(am__append_85) \ -@MONOLITHIC_TRUE@ $(am__append_88) $(am__append_91) \ -@MONOLITHIC_TRUE@ $(am__append_94) $(am__append_97) \ -@MONOLITHIC_TRUE@ $(am__append_100) $(am__append_103) -PLUGINS = ${libstrongswan_plugins} ${libhydra_plugins} $(am__append_4) \ - $(am__append_7) $(am__append_10) $(am__append_13) \ - $(am__append_16) $(am__append_19) $(am__append_22) \ - $(am__append_25) $(am__append_28) $(am__append_31) \ - $(am__append_34) $(am__append_37) $(am__append_40) \ - $(am__append_43) $(am__append_46) $(am__append_49) \ - $(am__append_52) $(am__append_55) $(am__append_58) \ - $(am__append_61) $(am__append_64) $(am__append_68) \ - $(am__append_71) $(am__append_74) $(am__append_77) \ - $(am__append_80) $(am__append_83) $(am__append_86) \ - $(am__append_89) $(am__append_92) $(am__append_95) \ - $(am__append_98) $(am__append_101) $(am__append_104) +@MONOLITHIC_TRUE@SUBDIRS = $(am__append_3) $(am__append_5) \ +@MONOLITHIC_TRUE@ $(am__append_7) $(am__append_9) \ +@MONOLITHIC_TRUE@ $(am__append_11) $(am__append_13) \ +@MONOLITHIC_TRUE@ $(am__append_15) $(am__append_17) \ +@MONOLITHIC_TRUE@ $(am__append_19) $(am__append_21) \ +@MONOLITHIC_TRUE@ $(am__append_23) $(am__append_25) \ +@MONOLITHIC_TRUE@ $(am__append_27) $(am__append_29) \ +@MONOLITHIC_TRUE@ $(am__append_31) $(am__append_33) \ +@MONOLITHIC_TRUE@ $(am__append_35) $(am__append_38) \ +@MONOLITHIC_TRUE@ $(am__append_40) $(am__append_42) \ +@MONOLITHIC_TRUE@ $(am__append_44) $(am__append_46) \ +@MONOLITHIC_TRUE@ $(am__append_48) $(am__append_50) \ +@MONOLITHIC_TRUE@ $(am__append_53) $(am__append_55) \ +@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) all: all-recursive .SUFFIXES: @@ -837,7 +823,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/authenticator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bus.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cert_payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certreq_payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/child_cfg.Plo@am__quote@ @@ -885,8 +870,7 @@ distclean-compile: @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@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_interface.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_ipsec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_handler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keymat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mediation_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mediation_manager.Plo@am__quote@ @@ -899,7 +883,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peer_cfg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_message_job.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal_substructure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psk_authenticator.Plo@am__quote@ @@ -910,7 +893,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/retransmit_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/roam_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sa_payload.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scheduler.Plo@am__quote@ @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@ @@ -919,6 +901,8 @@ distclean-compile: @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)/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@ @@ -1194,19 +1178,12 @@ vendor_id_payload.lo: encoding/payloads/vendor_id_payload.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 vendor_id_payload.lo `test -f 'encoding/payloads/vendor_id_payload.c' || echo '$(srcdir)/'`encoding/payloads/vendor_id_payload.c -kernel_interface.lo: kernel/kernel_interface.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kernel_interface.lo -MD -MP -MF $(DEPDIR)/kernel_interface.Tpo -c -o kernel_interface.lo `test -f 'kernel/kernel_interface.c' || echo '$(srcdir)/'`kernel/kernel_interface.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kernel_interface.Tpo $(DEPDIR)/kernel_interface.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel/kernel_interface.c' object='kernel_interface.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 kernel_interface.lo `test -f 'kernel/kernel_interface.c' || echo '$(srcdir)/'`kernel/kernel_interface.c - -kernel_ipsec.lo: kernel/kernel_ipsec.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kernel_ipsec.lo -MD -MP -MF $(DEPDIR)/kernel_ipsec.Tpo -c -o kernel_ipsec.lo `test -f 'kernel/kernel_ipsec.c' || echo '$(srcdir)/'`kernel/kernel_ipsec.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kernel_ipsec.Tpo $(DEPDIR)/kernel_ipsec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel/kernel_ipsec.c' object='kernel_ipsec.lo' libtool=yes @AMDEPBACKSLASH@ +kernel_handler.lo: kernel/kernel_handler.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kernel_handler.lo -MD -MP -MF $(DEPDIR)/kernel_handler.Tpo -c -o kernel_handler.lo `test -f 'kernel/kernel_handler.c' || echo '$(srcdir)/'`kernel/kernel_handler.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kernel_handler.Tpo $(DEPDIR)/kernel_handler.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel/kernel_handler.c' object='kernel_handler.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 kernel_ipsec.lo `test -f 'kernel/kernel_ipsec.c' || echo '$(srcdir)/'`kernel/kernel_ipsec.c +@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 @@ -1243,13 +1220,6 @@ acquire_job.lo: processing/jobs/acquire_job.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 acquire_job.lo `test -f 'processing/jobs/acquire_job.c' || echo '$(srcdir)/'`processing/jobs/acquire_job.c -callback_job.lo: processing/jobs/callback_job.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT callback_job.lo -MD -MP -MF $(DEPDIR)/callback_job.Tpo -c -o callback_job.lo `test -f 'processing/jobs/callback_job.c' || echo '$(srcdir)/'`processing/jobs/callback_job.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/callback_job.Tpo $(DEPDIR)/callback_job.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='processing/jobs/callback_job.c' object='callback_job.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 callback_job.lo `test -f 'processing/jobs/callback_job.c' || echo '$(srcdir)/'`processing/jobs/callback_job.c - delete_child_sa_job.lo: processing/jobs/delete_child_sa_job.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT delete_child_sa_job.lo -MD -MP -MF $(DEPDIR)/delete_child_sa_job.Tpo -c -o delete_child_sa_job.lo `test -f 'processing/jobs/delete_child_sa_job.c' || echo '$(srcdir)/'`processing/jobs/delete_child_sa_job.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/delete_child_sa_job.Tpo $(DEPDIR)/delete_child_sa_job.Plo @@ -1334,20 +1304,6 @@ inactivity_job.lo: processing/jobs/inactivity_job.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 inactivity_job.lo `test -f 'processing/jobs/inactivity_job.c' || echo '$(srcdir)/'`processing/jobs/inactivity_job.c -scheduler.lo: processing/scheduler.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT scheduler.lo -MD -MP -MF $(DEPDIR)/scheduler.Tpo -c -o scheduler.lo `test -f 'processing/scheduler.c' || echo '$(srcdir)/'`processing/scheduler.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/scheduler.Tpo $(DEPDIR)/scheduler.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='processing/scheduler.c' object='scheduler.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 scheduler.lo `test -f 'processing/scheduler.c' || echo '$(srcdir)/'`processing/scheduler.c - -processor.lo: processing/processor.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT processor.lo -MD -MP -MF $(DEPDIR)/processor.Tpo -c -o processor.lo `test -f 'processing/processor.c' || echo '$(srcdir)/'`processing/processor.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/processor.Tpo $(DEPDIR)/processor.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='processing/processor.c' object='processor.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 processor.lo `test -f 'processing/processor.c' || echo '$(srcdir)/'`processing/processor.c - authenticator.lo: sa/authenticators/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 authenticator.lo -MD -MP -MF $(DEPDIR)/authenticator.Tpo -c -o authenticator.lo `test -f 'sa/authenticators/authenticator.c' || echo '$(srcdir)/'`sa/authenticators/authenticator.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/authenticator.Tpo $(DEPDIR)/authenticator.Plo @@ -1565,6 +1521,20 @@ 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 +tnccs.lo: 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 'tnccs/tnccs.c' || echo '$(srcdir)/'`tnccs/tnccs.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs.Tpo $(DEPDIR)/tnccs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='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 'tnccs/tnccs.c' || echo '$(srcdir)/'`tnccs/tnccs.c + +tnccs_manager.lo: 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 'tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnccs/tnccs_manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_manager.Tpo $(DEPDIR)/tnccs_manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='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 'tnccs/tnccs_manager.c' || echo '$(srcdir)/'`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 @@ -1934,6 +1904,8 @@ daemon.lo : $(top_builddir)/config.status @MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@ # otherwise this library is linked to both the eap_aka and the eap_sim plugin +@MONOLITHIC_TRUE@@USE_TLS_TRUE@ # otherwise this library is linked to eap_tls + # 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 441009e5e..ab8d0fc48 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -17,7 +17,6 @@ #include <stdint.h> -#include <daemon.h> #include <threading/thread.h> #include <threading/thread_value.h> #include <threading/condvar.h> @@ -163,7 +162,7 @@ METHOD(bus_t, listen_, void, this->mutex->lock(this->mutex); this->listeners->insert_last(this->listeners, data.entry); - charon->processor->queue_job(charon->processor, job); + lib->processor->queue_job(lib->processor, job); thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex); thread_cleanup_push((thread_cleanup_t)listener_cleanup, &data); old = thread_cancelability(TRUE); diff --git a/src/libcharon/bus/listeners/file_logger.c b/src/libcharon/bus/listeners/file_logger.c index 87db532f5..157436a7d 100644 --- a/src/libcharon/bus/listeners/file_logger.c +++ b/src/libcharon/bus/listeners/file_logger.c @@ -46,6 +46,11 @@ struct private_file_logger_t { * strftime() format of time prefix, if any */ char *time_format; + + /** + * Print the name/# of the IKE_SA? + */ + bool ike_name; }; /** @@ -56,7 +61,7 @@ static bool log_(private_file_logger_t *this, debug_t group, level_t level, { if (level <= this->levels[group]) { - char buffer[8192], timestr[128]; + char buffer[8192], timestr[128], namestr[128] = ""; char *current = buffer, *next; struct tm tm; time_t t; @@ -67,6 +72,23 @@ static bool log_(private_file_logger_t *this, debug_t group, level_t level, localtime_r(&t, &tm); strftime(timestr, sizeof(timestr), this->time_format, &tm); } + if (this->ike_name && ike_sa) + { + if (ike_sa->get_peer_cfg(ike_sa)) + { + snprintf(namestr, sizeof(namestr), " <%s|%d>", + ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa)); + } + else + { + snprintf(namestr, sizeof(namestr), " <%d>", + ike_sa->get_unique_id(ike_sa)); + } + } + else + { + namestr[0] = '\0'; + } /* write in memory buffer first */ vsnprintf(buffer, sizeof(buffer), format, args); @@ -81,13 +103,13 @@ static bool log_(private_file_logger_t *this, debug_t group, level_t level, } if (this->time_format) { - fprintf(this->out, "%s %.2d[%N] %s\n", - timestr, thread, debug_names, group, current); + fprintf(this->out, "%s %.2d[%N]%s %s\n", + timestr, thread, debug_names, group, namestr, current); } else { - fprintf(this->out, "%.2d[%N] %s\n", - thread, debug_names, group, current); + fprintf(this->out, "%.2d[%N]%s %s\n", + thread, debug_names, group, namestr, current); } current = next; } @@ -129,7 +151,7 @@ static void destroy(private_file_logger_t *this) /* * Described in header. */ -file_logger_t *file_logger_create(FILE *out, char *time_format) +file_logger_t *file_logger_create(FILE *out, char *time_format, bool ike_name) { private_file_logger_t *this = malloc_thing(private_file_logger_t); @@ -142,6 +164,7 @@ file_logger_t *file_logger_create(FILE *out, char *time_format) /* private variables */ this->out = out; this->time_format = time_format; + this->ike_name = ike_name; set_level(this, DBG_ANY, LEVEL_SILENT); return &this->public; diff --git a/src/libcharon/bus/listeners/file_logger.h b/src/libcharon/bus/listeners/file_logger.h index e02a12c0c..d02f1701d 100644 --- a/src/libcharon/bus/listeners/file_logger.h +++ b/src/libcharon/bus/listeners/file_logger.h @@ -54,8 +54,9 @@ struct file_logger_t { * * @param out FILE to write to * @param time_format format of timestamp prefix, as in strftime() + * @param ike_name TRUE to prefix the name of the IKE_SA * @return file_logger_t object */ -file_logger_t *file_logger_create(FILE *out, char *time_format); +file_logger_t *file_logger_create(FILE *out, char *time_format, bool ike_name); #endif /** FILE_LOGGER_H_ @}*/ diff --git a/src/libcharon/bus/listeners/sys_logger.c b/src/libcharon/bus/listeners/sys_logger.c index 5bc1d581a..fa394ba88 100644 --- a/src/libcharon/bus/listeners/sys_logger.c +++ b/src/libcharon/bus/listeners/sys_logger.c @@ -41,6 +41,11 @@ struct private_sys_logger_t { * Maximum level to log, for each group */ level_t levels[DBG_MAX]; + + /** + * Print the name/# of the IKE_SA? + */ + bool ike_name; }; /** @@ -51,12 +56,26 @@ static bool log_(private_sys_logger_t *this, debug_t group, level_t level, { if (level <= this->levels[group]) { - char buffer[8192]; + char buffer[8192], namestr[128] = ""; char *current = buffer, *next; /* write in memory buffer first */ vsnprintf(buffer, sizeof(buffer), format, args); + if (this->ike_name && ike_sa) + { + if (ike_sa->get_peer_cfg(ike_sa)) + { + snprintf(namestr, sizeof(namestr), " <%s|%d>", + ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa)); + } + else + { + snprintf(namestr, sizeof(namestr), " <%d>", + ike_sa->get_unique_id(ike_sa)); + } + } + /* do a syslog with every line */ while (current) { @@ -65,8 +84,8 @@ static bool log_(private_sys_logger_t *this, debug_t group, level_t level, { *(next++) = '\0'; } - syslog(this->facility|LOG_INFO, "%.2d[%N] %s\n", - thread, debug_names, group, current); + syslog(this->facility|LOG_INFO, "%.2d[%N]%s %s\n", + thread, debug_names, group, namestr, current); current = next; } } @@ -104,7 +123,7 @@ static void destroy(private_sys_logger_t *this) /* * Described in header. */ -sys_logger_t *sys_logger_create(int facility) +sys_logger_t *sys_logger_create(int facility, bool ike_name) { private_sys_logger_t *this = malloc_thing(private_sys_logger_t); @@ -116,6 +135,7 @@ sys_logger_t *sys_logger_create(int facility) /* private variables */ this->facility = facility; + this->ike_name = ike_name; set_level(this, DBG_ANY, LEVEL_SILENT); return &this->public; diff --git a/src/libcharon/bus/listeners/sys_logger.h b/src/libcharon/bus/listeners/sys_logger.h index 58d4de529..d83715a6a 100644 --- a/src/libcharon/bus/listeners/sys_logger.h +++ b/src/libcharon/bus/listeners/sys_logger.h @@ -53,8 +53,9 @@ struct sys_logger_t { * Constructor to create a sys_logger_t object. * * @param facility syslog facility to use + * @param ike_name TRUE to prefix the name of the IKE_SA * @return sys_logger_t object */ -sys_logger_t *sys_logger_create(int facility); +sys_logger_t *sys_logger_create(int facility, bool ike_name); #endif /** SYS_LOGGER_H_ @}*/ diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c index 70f38b285..1cdfd5949 100644 --- a/src/libcharon/config/child_cfg.c +++ b/src/libcharon/config/child_cfg.c @@ -27,15 +27,6 @@ ENUM(action_names, ACTION_NONE, ACTION_RESTART, "restart", ); -ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE, - "IPCOMP_NONE"); -ENUM_NEXT(ipcomp_transform_names, IPCOMP_OUI, IPCOMP_LZJH, IPCOMP_NONE, - "IPCOMP_OUI", - "IPCOMP_DEFLATE", - "IPCOMP_LZS", - "IPCOMP_LZJH"); -ENUM_END(ipcomp_transform_names, IPCOMP_LZJH); - typedef struct private_child_cfg_t private_child_cfg_t; /** diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h index d34835ead..1e6fe3fe9 100644 --- a/src/libcharon/config/child_cfg.h +++ b/src/libcharon/config/child_cfg.h @@ -24,9 +24,6 @@ #define CHILD_CFG_H_ typedef enum action_t action_t; -typedef enum ipcomp_transform_t ipcomp_transform_t; -typedef struct lifetime_cfg_t lifetime_cfg_t; -typedef struct mark_t mark_t; typedef struct child_cfg_t child_cfg_t; #include <library.h> @@ -52,48 +49,6 @@ enum action_t { extern enum_name_t *action_names; /** - * IPComp transform IDs, as in RFC 4306 - */ -enum ipcomp_transform_t { - IPCOMP_NONE = 241, - IPCOMP_OUI = 1, - IPCOMP_DEFLATE = 2, - IPCOMP_LZS = 3, - IPCOMP_LZJH = 4, -}; - -/** - * enum strings for ipcomp_transform_t. - */ -extern enum_name_t *ipcomp_transform_names; - -/** - * A lifetime_cfg_t defines the lifetime limits of a CHILD_SA. - * - * Set any of these values to 0 to ignore. - */ -struct lifetime_cfg_t { - struct { - /** Limit before the CHILD_SA gets invalid. */ - u_int64_t life; - /** Limit before the CHILD_SA gets rekeyed. */ - u_int64_t rekey; - /** The range of a random value subtracted from rekey. */ - u_int64_t jitter; - } time, bytes, packets; -}; - -/** - * A mark_t defines an optional mark in a CHILD_SA. - */ -struct mark_t { - /** Mark value */ - u_int32_t value; - /** Mark mask */ - u_int32_t mask; -}; - -/** * A child_cfg_t defines the config template for a CHILD_SA. * * After creation, proposals and traffic selectors may be added to the config. @@ -238,7 +193,7 @@ struct child_cfg_t { * Check whether IPComp should be used, if the other peer supports it. * * @return TRUE, if IPComp should be used - * FALSE, otherwise + * FALSE, otherwise */ bool (*use_ipcomp)(child_cfg_t *this); @@ -259,7 +214,7 @@ struct child_cfg_t { /** * Optional mark for CHILD_SA * - * @param inbound TRUE for inbound, FALSE for outbound + * @param inbound TRUE for inbound, FALSE for outbound * @return mark */ mark_t (*get_mark)(child_cfg_t *this, bool inbound); @@ -277,7 +232,7 @@ struct child_cfg_t { * Check whether IPsec transport SA should be set up in proxy mode * * @return TRUE, if proxy mode should be used - * FALSE, otherwise + * FALSE, otherwise */ bool (*use_proxy_mode)(child_cfg_t *this); @@ -285,7 +240,7 @@ struct child_cfg_t { * Check whether IPsec policies should be installed in the kernel * * @return TRUE, if IPsec kernel policies should be installed - * FALSE, otherwise + * FALSE, otherwise */ bool (*install_policy)(child_cfg_t *this); diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index e86393028..5b8294599 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2008-2009 Tobias Brunner - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2010 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -87,6 +87,11 @@ struct private_proposal_t { * senders SPI */ u_int64_t spi; + + /** + * Proposal number + */ + u_int number; }; /** @@ -117,11 +122,9 @@ static void add_algo(linked_list_t *list, u_int16_t algo, u_int16_t key_size) list->insert_last(list, (void*)algo_key); } -/** - * Implements proposal_t.add_algorithm - */ -static void add_algorithm(private_proposal_t *this, transform_type_t type, - u_int16_t algo, u_int16_t key_size) +METHOD(proposal_t, add_algorithm, void, + private_proposal_t *this, transform_type_t type, + u_int16_t algo, u_int16_t key_size) { switch (type) { @@ -160,11 +163,8 @@ static bool alg_filter(void *null, algorithm_t **in, u_int16_t *alg, return TRUE; } -/** - * Implements proposal_t.create_enumerator. - */ -static enumerator_t *create_enumerator(private_proposal_t *this, - transform_type_t type) +METHOD(proposal_t, create_enumerator, enumerator_t*, + private_proposal_t *this, transform_type_t type) { linked_list_t *list; @@ -192,11 +192,9 @@ static enumerator_t *create_enumerator(private_proposal_t *this, (void*)alg_filter, NULL, NULL); } -/** - * Implements proposal_t.get_algorithm. - */ -static bool get_algorithm(private_proposal_t *this, transform_type_t type, - u_int16_t *alg, u_int16_t *key_size) +METHOD(proposal_t, get_algorithm, bool, + private_proposal_t *this, transform_type_t type, + u_int16_t *alg, u_int16_t *key_size) { enumerator_t *enumerator; bool found = FALSE; @@ -210,10 +208,8 @@ static bool get_algorithm(private_proposal_t *this, transform_type_t type, return found; } -/** - * Implements proposal_t.has_dh_group - */ -static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group) +METHOD(proposal_t, has_dh_group, bool, + private_proposal_t *this, diffie_hellman_group_t group) { bool result = FALSE; @@ -240,10 +236,8 @@ static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group) return result; } -/** - * Implementation of proposal_t.strip_dh. - */ -static void strip_dh(private_proposal_t *this) +METHOD(proposal_t, strip_dh, void, + private_proposal_t *this) { algorithm_t *alg; @@ -254,28 +248,6 @@ static void strip_dh(private_proposal_t *this) } /** - * Returns true if the given alg is an authenticated encryption algorithm - */ -static bool is_authenticated_encryption(u_int16_t alg) -{ - switch(alg) - { - case ENCR_AES_CCM_ICV8: - case ENCR_AES_CCM_ICV12: - case ENCR_AES_CCM_ICV16: - case ENCR_AES_GCM_ICV8: - case ENCR_AES_GCM_ICV12: - case ENCR_AES_GCM_ICV16: - case ENCR_CAMELLIA_CCM_ICV8: - case ENCR_CAMELLIA_CCM_ICV12: - case ENCR_CAMELLIA_CCM_ICV16: - case ENCR_NULL_AUTH_AES_GMAC: - return TRUE; - } - return FALSE; -} - -/** * Find a matching alg/keysize in two linked lists */ static bool select_algo(linked_list_t *first, linked_list_t *second, bool priv, @@ -326,12 +298,10 @@ static bool select_algo(linked_list_t *first, linked_list_t *second, bool priv, return FALSE; } -/** - * Implements proposal_t.select. - */ -static proposal_t *select_proposal(private_proposal_t *this, - private_proposal_t *other, bool private) +METHOD(proposal_t, select_proposal, proposal_t*, + private_proposal_t *this, proposal_t *other_pub, bool private) { + private_proposal_t *other = (private_proposal_t*)other_pub; proposal_t *selected; u_int16_t algo; size_t key_size; @@ -346,7 +316,7 @@ static proposal_t *select_proposal(private_proposal_t *this, return NULL; } - selected = proposal_create(this->protocol); + selected = proposal_create(this->protocol, other->number); /* select encryption algorithm */ if (select_algo(this->encryption_algos, other->encryption_algos, private, @@ -366,7 +336,7 @@ static proposal_t *select_proposal(private_proposal_t *this, return NULL; } /* select integrity algorithm */ - if (!is_authenticated_encryption(algo)) + if (!encryption_algorithm_is_aead(algo)) { if (select_algo(this->integrity_algos, other->integrity_algos, private, &add, &algo, &key_size)) @@ -442,26 +412,20 @@ static proposal_t *select_proposal(private_proposal_t *this, return selected; } -/** - * Implements proposal_t.get_protocols. - */ -static protocol_id_t get_protocol(private_proposal_t *this) +METHOD(proposal_t, get_protocol, protocol_id_t, + private_proposal_t *this) { return this->protocol; } -/** - * Implements proposal_t.set_spi. - */ -static void set_spi(private_proposal_t *this, u_int64_t spi) +METHOD(proposal_t, set_spi, void, + private_proposal_t *this, u_int64_t spi) { this->spi = spi; } -/** - * Implements proposal_t.get_spi. - */ -static u_int64_t get_spi(private_proposal_t *this) +METHOD(proposal_t, get_spi, u_int64_t, + private_proposal_t *this) { return this->spi; } @@ -514,19 +478,21 @@ static bool algo_list_equals(linked_list_t *l1, linked_list_t *l2) return equals; } -/** - * Implementation of proposal_t.equals. - */ -static bool equals(private_proposal_t *this, private_proposal_t *other) +METHOD(proposal_t, get_number, u_int, + private_proposal_t *this) +{ + return this->number; +} + +METHOD(proposal_t, equals, bool, + private_proposal_t *this, proposal_t *other_pub) { + private_proposal_t *other = (private_proposal_t*)other_pub; + if (this == other) { return TRUE; } - if (this->public.equals != other->public.equals) - { - return FALSE; - } return ( algo_list_equals(this->encryption_algos, other->encryption_algos) && algo_list_equals(this->integrity_algos, other->integrity_algos) && @@ -535,13 +501,12 @@ static bool equals(private_proposal_t *this, private_proposal_t *other) algo_list_equals(this->esns, other->esns)); } -/** - * Implements proposal_t.clone - */ -static proposal_t *clone_(private_proposal_t *this) +METHOD(proposal_t, clone_, proposal_t*, + private_proposal_t *this) { - private_proposal_t *clone = (private_proposal_t*)proposal_create(this->protocol); + private_proposal_t *clone; + clone = (private_proposal_t*)proposal_create(this->protocol, 0); clone_algo_list(this->encryption_algos, clone->encryption_algos); clone_algo_list(this->integrity_algos, clone->integrity_algos); clone_algo_list(this->prf_algos, clone->prf_algos); @@ -549,6 +514,7 @@ static proposal_t *clone_(private_proposal_t *this) clone_algo_list(this->esns, clone->esns); clone->spi = this->spi; + clone->number = this->number; return &clone->public; } @@ -565,7 +531,7 @@ static void check_proposal(private_proposal_t *this) e = this->encryption_algos->create_enumerator(this->encryption_algos); while (e->enumerate(e, &alg)) { - if (!is_authenticated_encryption(alg->algorithm)) + if (!encryption_algorithm_is_aead(alg->algorithm)) { all_aead = FALSE; break; @@ -623,6 +589,9 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg) case AUTH_AES_XCBC_96: prf = PRF_AES128_XCBC; break; + case AUTH_CAMELLIA_XCBC_96: + prf = PRF_CAMELLIA128_XCBC; + break; default: prf = PRF_UNDEFINED; } @@ -715,10 +684,8 @@ int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, return written; } -/** - * Implements proposal_t.destroy. - */ -static void destroy(private_proposal_t *this) +METHOD(proposal_t, destroy, void, + private_proposal_t *this) { this->encryption_algos->destroy_function(this->encryption_algos, free); this->integrity_algos->destroy_function(this->integrity_algos, free); @@ -731,31 +698,34 @@ static void destroy(private_proposal_t *this) /* * Describtion in header-file */ -proposal_t *proposal_create(protocol_id_t protocol) +proposal_t *proposal_create(protocol_id_t protocol, u_int number) { - private_proposal_t *this = malloc_thing(private_proposal_t); - - this->public.add_algorithm = (void (*)(proposal_t*,transform_type_t,u_int16_t,u_int16_t))add_algorithm; - this->public.create_enumerator = (enumerator_t* (*)(proposal_t*,transform_type_t))create_enumerator; - this->public.get_algorithm = (bool (*)(proposal_t*,transform_type_t,u_int16_t*,u_int16_t*))get_algorithm; - this->public.has_dh_group = (bool (*)(proposal_t*,diffie_hellman_group_t))has_dh_group; - this->public.strip_dh = (void(*)(proposal_t*))strip_dh; - this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*,bool))select_proposal; - this->public.get_protocol = (protocol_id_t(*)(proposal_t*))get_protocol; - this->public.set_spi = (void(*)(proposal_t*,u_int64_t))set_spi; - this->public.get_spi = (u_int64_t(*)(proposal_t*))get_spi; - this->public.equals = (bool(*)(proposal_t*, proposal_t *other))equals; - this->public.clone = (proposal_t*(*)(proposal_t*))clone_; - this->public.destroy = (void(*)(proposal_t*))destroy; - - this->spi = 0; - this->protocol = protocol; - - this->encryption_algos = linked_list_create(); - this->integrity_algos = linked_list_create(); - this->prf_algos = linked_list_create(); - this->dh_groups = linked_list_create(); - this->esns = linked_list_create(); + private_proposal_t *this; + + INIT(this, + .public = { + .add_algorithm = _add_algorithm, + .create_enumerator = _create_enumerator, + .get_algorithm = _get_algorithm, + .has_dh_group = _has_dh_group, + .strip_dh = _strip_dh, + .select = _select_proposal, + .get_protocol = _get_protocol, + .set_spi = _set_spi, + .get_spi = _get_spi, + .get_number = _get_number, + .equals = _equals, + .clone = _clone_, + .destroy = _destroy, + }, + .protocol = protocol, + .number = number, + .encryption_algos = linked_list_create(), + .integrity_algos = linked_list_create(), + .prf_algos = linked_list_create(), + .dh_groups = linked_list_create(), + .esns = linked_list_create(), + ); return &this->public; } @@ -777,19 +747,24 @@ static void proposal_add_supported_ike(private_proposal_t *this) switch (encryption) { case ENCR_AES_CBC: - /* we assume that we support all AES sizes */ - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128); - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192); - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256); - break; - case ENCR_3DES: case ENCR_AES_CTR: + case ENCR_CAMELLIA_CBC: + case ENCR_CAMELLIA_CTR: case ENCR_AES_CCM_ICV8: case ENCR_AES_CCM_ICV12: case ENCR_AES_CCM_ICV16: case ENCR_AES_GCM_ICV8: case ENCR_AES_GCM_ICV12: case ENCR_AES_GCM_ICV16: + case ENCR_CAMELLIA_CCM_ICV8: + case ENCR_CAMELLIA_CCM_ICV12: + case ENCR_CAMELLIA_CCM_ICV16: + /* we assume that we support all AES/Camellia sizes */ + add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128); + add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192); + add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256); + break; + case ENCR_3DES: add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0); break; case ENCR_DES: @@ -877,7 +852,7 @@ static void proposal_add_supported_ike(private_proposal_t *this) */ proposal_t *proposal_create_default(protocol_id_t protocol) { - private_proposal_t *this = (private_proposal_t*)proposal_create(protocol); + private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0); switch (protocol) { @@ -912,7 +887,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol) */ proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs) { - private_proposal_t *this = (private_proposal_t*)proposal_create(protocol); + private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0); chunk_t string = {(void*)algs, strlen(algs)}; chunk_t alg; status_t status = SUCCESS; diff --git a/src/libcharon/config/proposal.h b/src/libcharon/config/proposal.h index 30f63b80d..97af5b60b 100644 --- a/src/libcharon/config/proposal.h +++ b/src/libcharon/config/proposal.h @@ -161,6 +161,13 @@ struct proposal_t { void (*set_spi) (proposal_t *this, u_int64_t spi); /** + * Get the proposal number, as encoded in SA payload + * + * @return proposal number + */ + u_int (*get_number)(proposal_t *this); + + /** * Check for the eqality of two proposals. * * @param other other proposal to check for equality @@ -185,9 +192,10 @@ struct proposal_t { * Create a child proposal for AH, ESP or IKE. * * @param protocol protocol, such as PROTO_ESP + * @param number proposal number, as encoded in SA payload * @return proposal_t object */ -proposal_t *proposal_create(protocol_id_t protocol); +proposal_t *proposal_create(protocol_id_t protocol, u_int number); /** * Create a default proposal if nothing further specified. diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index c0227027c..4b8e1fadd 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -33,6 +33,7 @@ #include <library.h> #include <config/proposal.h> +#include <kernel/kernel_handler.h> #ifndef LOG_AUTHPRIV /* not defined on OpenSolaris */ #define LOG_AUTHPRIV LOG_AUTH @@ -50,6 +51,11 @@ struct private_daemon_t { daemon_t public; /** + * Handler for kernel events + */ + kernel_handler_t *kernel_handler; + + /** * capabilities to keep */ #ifdef CAPABILITIES_LIBCAP @@ -94,10 +100,8 @@ static void dbg_bus(debug_t group, level_t level, char *fmt, ...) static void destroy(private_daemon_t *this) { /* terminate all idle threads */ - if (this->public.processor) - { - this->public.processor->set_threads(this->public.processor, 0); - } + lib->processor->set_threads(lib->processor, 0); + /* close all IKE_SAs */ if (this->public.ike_sa_manager) { @@ -110,21 +114,19 @@ static void destroy(private_daemon_t *this) #ifdef CAPABILITIES_LIBCAP cap_free(this->caps); #endif /* CAPABILITIES_LIBCAP */ + DESTROY_IF(this->kernel_handler); DESTROY_IF(this->public.traps); DESTROY_IF(this->public.ike_sa_manager); - DESTROY_IF(this->public.kernel_interface); - DESTROY_IF(this->public.scheduler); 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); - /* wait until all threads are gone */ - DESTROY_IF(this->public.processor); /* rehook library logging, shutdown logging */ dbg = dbg_old; @@ -176,7 +178,7 @@ METHOD(daemon_t, start, void, private_daemon_t *this) { /* start the engine, go multithreaded */ - charon->processor->set_threads(charon->processor, + lib->processor->set_threads(lib->processor, lib->settings->get_int(lib->settings, "charon.threads", DEFAULT_THREADS)); } @@ -213,7 +215,7 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr, int loggers_defined = 0; debug_t group; level_t def; - bool append; + bool append, ike_name; FILE *file; /* setup sysloggers */ @@ -222,13 +224,16 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr, while (enumerator->enumerate(enumerator, &facility)) { loggers_defined++; + + ike_name = lib->settings->get_bool(lib->settings, + "charon.syslog.%s.ike_name", FALSE, facility); if (streq(facility, "daemon")) { - sys_logger = sys_logger_create(LOG_DAEMON); + sys_logger = sys_logger_create(LOG_DAEMON, ike_name); } else if (streq(facility, "auth")) { - sys_logger = sys_logger_create(LOG_AUTHPRIV); + sys_logger = sys_logger_create(LOG_AUTHPRIV, ike_name); } else { @@ -282,7 +287,9 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr, } file_logger = file_logger_create(file, lib->settings->get_str(lib->settings, - "charon.filelog.%s.time_format", NULL, filename)); + "charon.filelog.%s.time_format", NULL, filename), + lib->settings->get_bool(lib->settings, + "charon.filelog.%s.ike_name", FALSE, filename)); def = lib->settings->get_int(lib->settings, "charon.filelog.%s.default", 1, filename); for (group = 0; group < DBG_MAX; group++) @@ -303,12 +310,12 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr, if (!loggers_defined) { /* set up default stdout file_logger */ - file_logger = file_logger_create(stdout, NULL); + file_logger = file_logger_create(stdout, NULL, FALSE); this->public.bus->add_listener(this->public.bus, &file_logger->listener); this->public.file_loggers->insert_last(this->public.file_loggers, file_logger); /* set up default daemon sys_logger */ - sys_logger = sys_logger_create(LOG_DAEMON); + sys_logger = sys_logger_create(LOG_DAEMON, FALSE); this->public.bus->add_listener(this->public.bus, &sys_logger->listener); this->public.sys_loggers->insert_last(this->public.sys_loggers, sys_logger); @@ -322,7 +329,7 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr, } /* set up default auth sys_logger */ - sys_logger = sys_logger_create(LOG_AUTHPRIV); + sys_logger = sys_logger_create(LOG_AUTHPRIV, FALSE); this->public.bus->add_listener(this->public.bus, &sys_logger->listener); this->public.sys_loggers->insert_last(this->public.sys_loggers, sys_logger); @@ -356,15 +363,14 @@ METHOD(daemon_t, initialize, bool, } /* load secrets, ca certificates and crls */ - this->public.processor = processor_create(); - this->public.scheduler = scheduler_create(); 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.kernel_interface = kernel_interface_create(); this->public.socket = socket_manager_create(); this->public.traps = trap_manager_create(); + this->kernel_handler = kernel_handler_create(); /* load plugins, further infrastructure may need it */ if (!lib->plugins->load(lib->plugins, NULL, diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h index 38f0256e7..c0c834b43 100644 --- a/src/libcharon/daemon.h +++ b/src/libcharon/daemon.h @@ -37,7 +37,7 @@ * @defgroup payloads payloads * @ingroup encoding * - * @defgroup kernel kernel + * @defgroup ckernel kernel * @ingroup libcharon * * @defgroup network network @@ -46,11 +46,11 @@ * @defgroup cplugins plugins * @ingroup libcharon * - * @defgroup processing processing + * @defgroup cprocessing processing * @ingroup libcharon * - * @defgroup jobs jobs - * @ingroup processing + * @defgroup cjobs jobs + * @ingroup cprocessing * * @defgroup sa sa * @ingroup libcharon @@ -140,9 +140,6 @@ typedef struct daemon_t daemon_t; #include <network/sender.h> #include <network/receiver.h> #include <network/socket_manager.h> -#include <processing/scheduler.h> -#include <processing/processor.h> -#include <kernel/kernel_interface.h> #include <control/controller.h> #include <bus/bus.h> #include <bus/listeners/file_logger.h> @@ -152,6 +149,7 @@ typedef struct daemon_t daemon_t; #include <config/backend_manager.h> #include <sa/authenticators/eap/eap_manager.h> #include <sa/authenticators/eap/sim_manager.h> +#include <tnccs/tnccs_manager.h> #ifdef ME #include <sa/connect_manager.h> @@ -209,16 +207,6 @@ struct daemon_t { receiver_t *receiver; /** - * The Scheduler-Thread. - */ - scheduler_t *scheduler; - - /** - * Job processing using a thread pool. - */ - processor_t *processor; - - /** * The signaling bus. */ bus_t *bus; @@ -234,11 +222,6 @@ struct daemon_t { linked_list_t *sys_loggers; /** - * Kernel Interface to communicate with kernel - */ - kernel_interface_t *kernel_interface; - - /** * Controller to control the daemon */ controller_t *controller; @@ -253,6 +236,11 @@ struct daemon_t { */ sim_manager_t *sim; + /** + * 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 6485da492..224f76fce 100644 --- a/src/libcharon/encoding/generator.c +++ b/src/libcharon/encoding/generator.c @@ -42,6 +42,16 @@ #include <encoding/payloads/configuration_attribute.h> #include <encoding/payloads/eap_payload.h> +/** + * Generating is done in a data buffer. + * This is the start size of this buffer in bytes. + */ +#define GENERATOR_DATA_BUFFER_SIZE 500 + +/** + * Number of bytes to increase the buffer, if it is too small. + */ +#define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500 typedef struct private_generator_t private_generator_t; @@ -453,36 +463,19 @@ static void generate_from_chunk(private_generator_t *this, u_int32_t offset) write_bytes_to_buffer(this, value->ptr, value->len); } -/** - * Implementation of private_generator_t.write_to_chunk. - */ -static void write_to_chunk(private_generator_t *this,chunk_t *data) +METHOD(generator_t, get_chunk, chunk_t, + private_generator_t *this, u_int32_t **lenpos) { - int data_length = get_length(this); - u_int32_t header_length_field = data_length; - - /* write length into header length field */ - if (this->header_length_position_offset > 0) - { - u_int32_t val = htonl(header_length_field); - write_bytes_to_buffer_at_offset(this, &val, sizeof(u_int32_t), - this->header_length_position_offset); - } + chunk_t data; - if (this->current_bit > 0) - { - data_length++; - } - *data = chunk_alloc(data_length); - memcpy(data->ptr, this->buffer, data_length); - - DBG3(DBG_ENC, "generated data of this generator %B", data); + *lenpos = (u_int32_t*)(this->buffer + this->header_length_position_offset); + data = chunk_create(this->buffer, get_length(this)); + DBG3(DBG_ENC, "generated data of this generator %B", &data); + return data; } -/** - * Implementation of private_generator_t.generate_payload. - */ -static void generate_payload (private_generator_t *this,payload_t *payload) +METHOD(generator_t, generate_payload, void, + private_generator_t *this,payload_t *payload) { int i, offset_start; size_t rule_count; @@ -846,14 +839,11 @@ static void generate_payload (private_generator_t *this,payload_t *payload) this->out_position - this->buffer - offset_start); } -/** - * Implementation of generator_t.destroy. - */ -static status_t destroy(private_generator_t *this) +METHOD(generator_t, destroy, void, + private_generator_t *this) { free(this->buffer); free(this); - return SUCCESS; } /* @@ -863,26 +853,18 @@ generator_t *generator_create() { private_generator_t *this; - this = malloc_thing(private_generator_t); - - /* initiate public functions */ - this->public.generate_payload = (void(*)(generator_t*, payload_t *))generate_payload; - this->public.destroy = (void(*)(generator_t*)) destroy; - this->public.write_to_chunk = (void (*) (generator_t *,chunk_t *))write_to_chunk; + INIT(this, + .public = { + .get_chunk = _get_chunk, + .generate_payload = _generate_payload, + .destroy = _destroy, + }, + .buffer = malloc(GENERATOR_DATA_BUFFER_SIZE), + ); - /* allocate memory for buffer */ - this->buffer = malloc(GENERATOR_DATA_BUFFER_SIZE); - - /* initiate private variables */ this->out_position = this->buffer; this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE; - this->data_struct = NULL; - this->current_bit = 0; - this->last_payload_length_position_offset = 0; - this->header_length_position_offset = 0; - this->attribute_format = FALSE; - this->attribute_length = 0; - - return &(this->public); + + return &this->public; } diff --git a/src/libcharon/encoding/generator.h b/src/libcharon/encoding/generator.h index 2221c84af..fe561fdfd 100644 --- a/src/libcharon/encoding/generator.h +++ b/src/libcharon/encoding/generator.h @@ -29,24 +29,12 @@ typedef struct generator_t generator_t; #include <encoding/payloads/payload.h> /** - * Generating is done in a data buffer. - * This is the start size of this buffer in bytes. - */ -#define GENERATOR_DATA_BUFFER_SIZE 500 - -/** - * Number of bytes to increase the buffer, if it is too small. - */ -#define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500 - - -/** * A generator_t class used to generate IKEv2 payloads. * * After creation, multiple payloads can be generated with the generate_payload * method. The generated bytes are appended. After all payloads are added, * the write_to_chunk method writes out all generated data since - * the creation of the generator. After that, the generator must be destroyed. + * the creation of the generator. * The generater uses a set of encoding rules, which it can get from * the supplied payload. With this rules, the generater can generate * the payload and all substructures automatically. @@ -56,18 +44,20 @@ struct generator_t { /** * Generates a specific payload from given payload object. * - * Remember: Header and substructures are also handled as payloads. - * * @param payload interface payload_t implementing object */ void (*generate_payload) (generator_t *this,payload_t *payload); /** - * Writes all generated data of the generator to a chunk. + * Return a chunk for the currently generated data. + * + * The returned length pointer must be filled in with the length of + * the generated chunk (in network order). * - * @param data chunk to write the data to + * @param lenpos receives a pointer to fill in length value + * @param return chunk to internal buffer. */ - void (*write_to_chunk) (generator_t *this,chunk_t *data); + chunk_t (*get_chunk) (generator_t *this, u_int32_t **lenpos); /** * Destroys a generator_t object. diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index ee49a6686..d41ad4697 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2006-2007 Tobias Brunner - * Copyright (C) 2005-2009 Martin Willi + * Copyright (C) 2005-2010 Martin Willi + * Copyright (C) 2010 revosec AG * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -43,111 +44,61 @@ */ #define MAX_DELETE_PAYLOADS 20 - -typedef struct payload_rule_t payload_rule_t; - /** * A payload rule defines the rules for a payload * in a specific message rule. It defines if and how * many times a payload must/can occur in a message * and if it must be encrypted. */ -struct payload_rule_t { - /** - * Payload type. - */ - payload_type_t payload_type; - - /** - * Minimal occurence of this payload. - */ - size_t min_occurence; - - /** - * Max occurence of this payload. - */ - size_t max_occurence; - - /** - * TRUE if payload must be encrypted - */ - bool encrypted; - - /** - * If this payload occurs, the message rule is - * fullfilled in any case. This applies e.g. to - * notify_payloads. - */ - bool sufficient; -}; - -typedef struct payload_order_t payload_order_t; +typedef struct { + /* Payload type */ + payload_type_t type; + /* Minimal occurence of this payload. */ + size_t min_occurence; + /* Max occurence of this payload. */ + size_t max_occurence; + /* TRUE if payload must be encrypted */ + bool encrypted; + /* If payload occurs, the message rule is fullfilled */ + bool sufficient; +} payload_rule_t; /** * payload ordering structure allows us to reorder payloads according to RFC. */ -struct payload_order_t { - - /** - * payload type - */ +typedef struct { + /** payload type */ payload_type_t type; - - /** - * notify type, if payload == NOTIFY - */ + /** notify type, if payload == NOTIFY */ notify_type_t notify; -}; - - -typedef struct message_rule_t message_rule_t; +} payload_order_t; /** * A message rule defines the kind of a message, * if it has encrypted contents and a list * of payload ordering rules and payload parsing rules. */ -struct message_rule_t { - /** - * Type of message. - */ +typedef struct { + /** Type of message. */ exchange_type_t exchange_type; - - /** - * Is message a request or response. - */ + /** Is message a request or response. */ bool is_request; - - /** - * Message contains encrypted content. - */ - bool encrypted_content; - - /** - * Number of payload rules which will follow - */ - int payload_rule_count; - - /** - * Pointer to first payload rule - */ - payload_rule_t *payload_rules; - - /** - * Number of payload order rules - */ - int payload_order_count; - - /** - * payload ordering rules - */ - payload_order_t *payload_order; -}; + /** Message contains encrypted payloads. */ + bool encrypted; + /** Number of payload rules which will follow */ + int rule_count; + /** Pointer to first payload rule */ + payload_rule_t *rules; + /** Number of payload order rules */ + int order_count; + /** payload ordering rules */ + payload_order_t *order; +} message_rule_t; /** * Message rule for IKE_SA_INIT from initiator. */ -static payload_rule_t ike_sa_init_i_payload_rules[] = { +static payload_rule_t ike_sa_init_i_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, FALSE, FALSE}, {SECURITY_ASSOCIATION, 1, 1, FALSE, FALSE}, @@ -159,7 +110,7 @@ static payload_rule_t ike_sa_init_i_payload_rules[] = { /** * payload order for IKE_SA_INIT initiator */ -static payload_order_t ike_sa_init_i_payload_order[] = { +static payload_order_t ike_sa_init_i_order[] = { /* payload type notify type */ {NOTIFY, COOKIE}, {SECURITY_ASSOCIATION, 0}, @@ -174,7 +125,7 @@ static payload_order_t ike_sa_init_i_payload_order[] = { /** * Message rule for IKE_SA_INIT from responder. */ -static payload_rule_t ike_sa_init_r_payload_rules[] = { +static payload_rule_t ike_sa_init_r_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, FALSE, TRUE}, {SECURITY_ASSOCIATION, 1, 1, FALSE, FALSE}, @@ -186,7 +137,7 @@ static payload_rule_t ike_sa_init_r_payload_rules[] = { /** * payload order for IKE_SA_INIT responder */ -static payload_order_t ike_sa_init_r_payload_order[] = { +static payload_order_t ike_sa_init_r_order[] = { /* payload type notify type */ {SECURITY_ASSOCIATION, 0}, {KEY_EXCHANGE, 0}, @@ -202,7 +153,7 @@ static payload_order_t ike_sa_init_r_payload_order[] = { /** * Message rule for IKE_AUTH from initiator. */ -static payload_rule_t ike_auth_i_payload_rules[] = { +static payload_rule_t ike_auth_i_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, {EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE}, @@ -227,7 +178,7 @@ static payload_rule_t ike_auth_i_payload_rules[] = { /** * payload order for IKE_AUTH initiator */ -static payload_order_t ike_auth_i_payload_order[] = { +static payload_order_t ike_auth_i_order[] = { /* payload type notify type */ {ID_INITIATOR, 0}, {CERTIFICATE, 0}, @@ -256,7 +207,7 @@ static payload_order_t ike_auth_i_payload_order[] = { /** * Message rule for IKE_AUTH from responder. */ -static payload_rule_t ike_auth_r_payload_rules[] = { +static payload_rule_t ike_auth_r_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, {EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE}, @@ -273,7 +224,7 @@ static payload_rule_t ike_auth_r_payload_rules[] = { /** * payload order for IKE_AUTH responder */ -static payload_order_t ike_auth_r_payload_order[] = { +static payload_order_t ike_auth_r_order[] = { /* payload type notify type */ {ID_RESPONDER, 0}, {CERTIFICATE, 0}, @@ -299,7 +250,7 @@ static payload_order_t ike_auth_r_payload_order[] = { /** * Message rule for INFORMATIONAL from initiator. */ -static payload_rule_t informational_i_payload_rules[] = { +static payload_rule_t informational_i_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, {CONFIGURATION, 0, 1, TRUE, FALSE}, @@ -310,7 +261,7 @@ static payload_rule_t informational_i_payload_rules[] = { /** * payload order for INFORMATIONAL initiator */ -static payload_order_t informational_i_payload_order[] = { +static payload_order_t informational_i_order[] = { /* payload type notify type */ {NOTIFY, UPDATE_SA_ADDRESSES}, {NOTIFY, NAT_DETECTION_SOURCE_IP}, @@ -324,7 +275,7 @@ static payload_order_t informational_i_payload_order[] = { /** * Message rule for INFORMATIONAL from responder. */ -static payload_rule_t informational_r_payload_rules[] = { +static payload_rule_t informational_r_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, {CONFIGURATION, 0, 1, TRUE, FALSE}, @@ -335,7 +286,7 @@ static payload_rule_t informational_r_payload_rules[] = { /** * payload order for INFORMATIONAL responder */ -static payload_order_t informational_r_payload_order[] = { +static payload_order_t informational_r_order[] = { /* payload type notify type */ {NOTIFY, UPDATE_SA_ADDRESSES}, {NOTIFY, NAT_DETECTION_SOURCE_IP}, @@ -349,7 +300,7 @@ static payload_order_t informational_r_payload_order[] = { /** * Message rule for CREATE_CHILD_SA from initiator. */ -static payload_rule_t create_child_sa_i_payload_rules[] = { +static payload_rule_t create_child_sa_i_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE}, @@ -364,7 +315,7 @@ static payload_rule_t create_child_sa_i_payload_rules[] = { /** * payload order for CREATE_CHILD_SA from initiator. */ -static payload_order_t create_child_sa_i_payload_order[] = { +static payload_order_t create_child_sa_i_order[] = { /* payload type notify type */ {NOTIFY, REKEY_SA}, {NOTIFY, IPCOMP_SUPPORTED}, @@ -382,7 +333,7 @@ static payload_order_t create_child_sa_i_payload_order[] = { /** * Message rule for CREATE_CHILD_SA from responder. */ -static payload_rule_t create_child_sa_r_payload_rules[] = { +static payload_rule_t create_child_sa_r_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE}, @@ -397,7 +348,7 @@ static payload_rule_t create_child_sa_r_payload_rules[] = { /** * payload order for CREATE_CHILD_SA from responder. */ -static payload_order_t create_child_sa_r_payload_order[] = { +static payload_order_t create_child_sa_r_order[] = { /* payload type notify type */ {NOTIFY, IPCOMP_SUPPORTED}, {NOTIFY, USE_TRANSPORT_MODE}, @@ -416,7 +367,7 @@ static payload_order_t create_child_sa_r_payload_order[] = { /** * Message rule for ME_CONNECT from initiator. */ -static payload_rule_t me_connect_i_payload_rules[] = { +static payload_rule_t me_connect_i_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, {ID_PEER, 1, 1, TRUE, FALSE}, @@ -426,7 +377,7 @@ static payload_rule_t me_connect_i_payload_rules[] = { /** * payload order for ME_CONNECT from initiator. */ -static payload_order_t me_connect_i_payload_order[] = { +static payload_order_t me_connect_i_order[] = { /* payload type notify type */ {NOTIFY, 0}, {ID_PEER, 0}, @@ -436,7 +387,7 @@ static payload_order_t me_connect_i_payload_order[] = { /** * Message rule for ME_CONNECT from responder. */ -static payload_rule_t me_connect_r_payload_rules[] = { +static payload_rule_t me_connect_r_rules[] = { /* payload type min max encr suff */ {NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, {VENDOR_ID, 0, 10, TRUE, FALSE} @@ -445,7 +396,7 @@ static payload_rule_t me_connect_r_payload_rules[] = { /** * payload order for ME_CONNECT from responder. */ -static payload_order_t me_connect_r_payload_order[] = { +static payload_order_t me_connect_r_order[] = { /* payload type notify type */ {NOTIFY, 0}, {VENDOR_ID, 0}, @@ -457,65 +408,45 @@ static payload_order_t me_connect_r_payload_order[] = { */ static message_rule_t message_rules[] = { {IKE_SA_INIT, TRUE, FALSE, - (sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)), - ike_sa_init_i_payload_rules, - (sizeof(ike_sa_init_i_payload_order)/sizeof(payload_order_t)), - ike_sa_init_i_payload_order, + countof(ike_sa_init_i_rules), ike_sa_init_i_rules, + countof(ike_sa_init_i_order), ike_sa_init_i_order, }, {IKE_SA_INIT, FALSE, FALSE, - (sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)), - ike_sa_init_r_payload_rules, - (sizeof(ike_sa_init_r_payload_order)/sizeof(payload_order_t)), - ike_sa_init_r_payload_order, + countof(ike_sa_init_r_rules), ike_sa_init_r_rules, + countof(ike_sa_init_r_order), ike_sa_init_r_order, }, {IKE_AUTH, TRUE, TRUE, - (sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)), - ike_auth_i_payload_rules, - (sizeof(ike_auth_i_payload_order)/sizeof(payload_order_t)), - ike_auth_i_payload_order, + countof(ike_auth_i_rules), ike_auth_i_rules, + countof(ike_auth_i_order), ike_auth_i_order, }, {IKE_AUTH, FALSE, TRUE, - (sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)), - ike_auth_r_payload_rules, - (sizeof(ike_auth_r_payload_order)/sizeof(payload_order_t)), - ike_auth_r_payload_order, + countof(ike_auth_r_rules), ike_auth_r_rules, + countof(ike_auth_r_order), ike_auth_r_order, }, {INFORMATIONAL, TRUE, TRUE, - (sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)), - informational_i_payload_rules, - (sizeof(informational_i_payload_order)/sizeof(payload_order_t)), - informational_i_payload_order, + countof(informational_i_rules), informational_i_rules, + countof(informational_i_order), informational_i_order, }, {INFORMATIONAL, FALSE, TRUE, - (sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)), - informational_r_payload_rules, - (sizeof(informational_r_payload_order)/sizeof(payload_order_t)), - informational_r_payload_order, + countof(informational_r_rules), informational_r_rules, + countof(informational_r_order), informational_r_order, }, {CREATE_CHILD_SA, TRUE, TRUE, - (sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)), - create_child_sa_i_payload_rules, - (sizeof(create_child_sa_i_payload_order)/sizeof(payload_order_t)), - create_child_sa_i_payload_order, + countof(create_child_sa_i_rules), create_child_sa_i_rules, + countof(create_child_sa_i_order), create_child_sa_i_order, }, {CREATE_CHILD_SA, FALSE, TRUE, - (sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)), - create_child_sa_r_payload_rules, - (sizeof(create_child_sa_r_payload_order)/sizeof(payload_order_t)), - create_child_sa_r_payload_order, + countof(create_child_sa_r_rules), create_child_sa_r_rules, + countof(create_child_sa_r_order), create_child_sa_r_order, }, #ifdef ME {ME_CONNECT, TRUE, TRUE, - (sizeof(me_connect_i_payload_rules)/sizeof(payload_rule_t)), - me_connect_i_payload_rules, - (sizeof(me_connect_i_payload_order)/sizeof(payload_order_t)), - me_connect_i_payload_order, + countof(me_connect_i_rules), me_connect_i_rules, + countof(me_connect_i_order), me_connect_i_order, }, {ME_CONNECT, FALSE, TRUE, - (sizeof(me_connect_r_payload_rules)/sizeof(payload_rule_t)), - me_connect_r_payload_rules, - (sizeof(me_connect_r_payload_order)/sizeof(payload_order_t)), - me_connect_r_payload_order, + countof(me_connect_r_rules), me_connect_r_rules, + countof(me_connect_r_order), me_connect_r_order, }, #endif /* ME */ }; @@ -586,169 +517,132 @@ struct private_message_t { /** * The message rule for this message instance */ - message_rule_t *message_rule; + message_rule_t *rule; }; /** - * Implementation of private_message_t.set_message_rule. + * Get the message rule that applies to this message */ -static status_t set_message_rule(private_message_t *this) +static message_rule_t* get_message_rule(private_message_t *this) { int i; - for (i = 0; i < (sizeof(message_rules) / sizeof(message_rule_t)); i++) + for (i = 0; i < countof(message_rules); i++) { if ((this->exchange_type == message_rules[i].exchange_type) && (this->is_request == message_rules[i].is_request)) { - /* found rule for given exchange_type*/ - this->message_rule = &(message_rules[i]); - return SUCCESS; + return &message_rules[i]; } } - this->message_rule = NULL; - return NOT_FOUND; + return NULL; } /** - * Implementation of private_message_t.get_payload_rule. + * Look up a payload rule */ -static status_t get_payload_rule(private_message_t *this, - payload_type_t payload_type, payload_rule_t **payload_rule) +static payload_rule_t* get_payload_rule(private_message_t *this, + payload_type_t type) { int i; - for (i = 0; i < this->message_rule->payload_rule_count;i++) + for (i = 0; i < this->rule->rule_count;i++) { - if (this->message_rule->payload_rules[i].payload_type == payload_type) + if (this->rule->rules[i].type == type) { - *payload_rule = &(this->message_rule->payload_rules[i]); - return SUCCESS; + return &this->rule->rules[i]; } } - - *payload_rule = NULL; - return NOT_FOUND; + return NULL; } -/** - * Implementation of message_t.set_ike_sa_id. - */ -static void set_ike_sa_id(private_message_t *this,ike_sa_id_t *ike_sa_id) +METHOD(message_t, set_ike_sa_id, void, + private_message_t *this,ike_sa_id_t *ike_sa_id) { DESTROY_IF(this->ike_sa_id); this->ike_sa_id = ike_sa_id->clone(ike_sa_id); } -/** - * Implementation of message_t.get_ike_sa_id. - */ -static ike_sa_id_t* get_ike_sa_id(private_message_t *this) +METHOD(message_t, get_ike_sa_id, ike_sa_id_t*, + private_message_t *this) { return this->ike_sa_id; } -/** - * Implementation of message_t.set_message_id. - */ -static void set_message_id(private_message_t *this,u_int32_t message_id) +METHOD(message_t, set_message_id, void, + private_message_t *this,u_int32_t message_id) { this->message_id = message_id; } -/** - * Implementation of message_t.get_message_id. - */ -static u_int32_t get_message_id(private_message_t *this) +METHOD(message_t, get_message_id, u_int32_t, + private_message_t *this) { return this->message_id; } -/** - * Implementation of message_t.get_initiator_spi. - */ -static u_int64_t get_initiator_spi(private_message_t *this) +METHOD(message_t, get_initiator_spi, u_int64_t, + private_message_t *this) { return (this->ike_sa_id->get_initiator_spi(this->ike_sa_id)); } -/** - * Implementation of message_t.get_responder_spi. - */ -static u_int64_t get_responder_spi(private_message_t *this) +METHOD(message_t, get_responder_spi, u_int64_t, + private_message_t *this) { return (this->ike_sa_id->get_responder_spi(this->ike_sa_id)); } -/** - * Implementation of message_t.set_major_version. - */ -static void set_major_version(private_message_t *this,u_int8_t major_version) +METHOD(message_t, set_major_version, void, + private_message_t *this, u_int8_t major_version) { this->major_version = major_version; } -/** - * Implementation of message_t.set_major_version. - */ -static u_int8_t get_major_version(private_message_t *this) +METHOD(message_t, get_major_version, u_int8_t, + private_message_t *this) { return this->major_version; } -/** - * Implementation of message_t.set_minor_version. - */ -static void set_minor_version(private_message_t *this,u_int8_t minor_version) +METHOD(message_t, set_minor_version, void, + private_message_t *this,u_int8_t minor_version) { this->minor_version = minor_version; } -/** - * Implementation of message_t.get_minor_version. - */ -static u_int8_t get_minor_version(private_message_t *this) +METHOD(message_t, get_minor_version, u_int8_t, + private_message_t *this) { return this->minor_version; } -/** - * Implementation of message_t.set_exchange_type. - */ -static void set_exchange_type(private_message_t *this, - exchange_type_t exchange_type) +METHOD(message_t, set_exchange_type, void, + private_message_t *this, exchange_type_t exchange_type) { this->exchange_type = exchange_type; } -/** - * Implementation of message_t.get_exchange_type. - */ -static exchange_type_t get_exchange_type(private_message_t *this) +METHOD(message_t, get_exchange_type, exchange_type_t, + private_message_t *this) { return this->exchange_type; } -/** - * Implementation of message_t.get_first_payload_type. - */ -static payload_type_t get_first_payload_type(private_message_t *this) +METHOD(message_t, get_first_payload_type, payload_type_t, + private_message_t *this) { return this->first_payload; } -/** - * Implementation of message_t.set_request. - */ -static void set_request(private_message_t *this, bool request) +METHOD(message_t, set_request, void, + private_message_t *this, bool request) { this->is_request = request; } -/** - * Implementation of message_t.get_request. - */ -static exchange_type_t get_request(private_message_t *this) +METHOD(message_t, get_request, bool, + private_message_t *this) { return this->is_request; } @@ -767,10 +661,8 @@ static bool is_encoded(private_message_t *this) return TRUE; } -/** - * Implementation of message_t.add_payload. - */ -static void add_payload(private_message_t *this, payload_t *payload) +METHOD(message_t, add_payload, void, + private_message_t *this, payload_t *payload) { payload_t *last_payload; @@ -790,11 +682,8 @@ static void add_payload(private_message_t *this, payload_t *payload) payload_type_names, payload->get_type(payload)); } -/** - * Implementation of message_t.add_notify. - */ -static void add_notify(private_message_t *this, bool flush, notify_type_t type, - chunk_t data) +METHOD(message_t, add_notify, void, + private_message_t *this, bool flush, notify_type_t type, chunk_t data) { notify_payload_t *notify; payload_t *payload; @@ -813,50 +702,38 @@ static void add_notify(private_message_t *this, bool flush, notify_type_t type, add_payload(this, (payload_t*)notify); } -/** - * Implementation of message_t.set_source. - */ -static void set_source(private_message_t *this, host_t *host) +METHOD(message_t, set_source, void, + private_message_t *this, host_t *host) { this->packet->set_source(this->packet, host); } -/** - * Implementation of message_t.set_destination. - */ -static void set_destination(private_message_t *this, host_t *host) +METHOD(message_t, set_destination, void, + private_message_t *this, host_t *host) { this->packet->set_destination(this->packet, host); } -/** - * Implementation of message_t.get_source. - */ -static host_t* get_source(private_message_t *this) +METHOD(message_t, get_source, host_t*, + private_message_t *this) { return this->packet->get_source(this->packet); } -/** - * Implementation of message_t.get_destination. - */ -static host_t * get_destination(private_message_t *this) +METHOD(message_t, get_destination, host_t*, + private_message_t *this) { return this->packet->get_destination(this->packet); } -/** - * Implementation of message_t.create_payload_enumerator. - */ -static enumerator_t *create_payload_enumerator(private_message_t *this) +METHOD(message_t, create_payload_enumerator, enumerator_t*, + private_message_t *this) { return this->payloads->create_enumerator(this->payloads); } -/** - * Implementation of message_t.get_payload. - */ -static payload_t *get_payload(private_message_t *this, payload_type_t type) +METHOD(message_t, get_payload, payload_t*, + private_message_t *this, payload_type_t type) { payload_t *current, *found = NULL; enumerator_t *enumerator; @@ -874,10 +751,8 @@ static payload_t *get_payload(private_message_t *this, payload_type_t type) return found; } -/** - * Implementation of message_t.get_notify - */ -static notify_payload_t* get_notify(private_message_t *this, notify_type_t type) +METHOD(message_t, get_notify, notify_payload_t*, + private_message_t *this, notify_type_t type) { enumerator_t *enumerator; notify_payload_t *notify = NULL; @@ -1034,11 +909,13 @@ static void order_payloads(private_message_t *this) list->insert_first(list, payload); } /* for each rule, ... */ - for (i = 0; i < this->message_rule->payload_order_count; i++) + for (i = 0; i < this->rule->order_count; i++) { enumerator_t *enumerator; notify_payload_t *notify; - payload_order_t order = this->message_rule->payload_order[i]; + payload_order_t order; + + order = this->rule->order[i]; /* ... find all payload ... */ enumerator = list->create_enumerator(list); @@ -1068,8 +945,8 @@ static void order_payloads(private_message_t *this) { DBG1(DBG_ENC, "payload %N has no ordering rule in %N %s", payload_type_names, payload->get_type(payload), - exchange_type_names, this->message_rule->exchange_type, - this->message_rule->is_request ? "request" : "response"); + exchange_type_names, this->rule->exchange_type, + this->rule->is_request ? "request" : "response"); } add_payload(this, payload); } @@ -1077,98 +954,67 @@ static void order_payloads(private_message_t *this) } /** - * Implementation of private_message_t.encrypt_payloads. + * Wrap payloads in a encryption payload */ -static status_t encrypt_payloads(private_message_t *this, - crypter_t *crypter, signer_t* signer) +static encryption_payload_t* wrap_payloads(private_message_t *this) { encryption_payload_t *encryption; linked_list_t *payloads; payload_t *current; - status_t status; - if (!this->message_rule->encrypted_content) - { - DBG2(DBG_ENC, "message doesn't have to be encrypted"); - /* message contains no content to encrypt */ - return SUCCESS; - } - - if (!crypter || !signer) - { - DBG2(DBG_ENC, "no crypter or signer specified, do not encrypt message"); - /* message contains no content to encrypt */ - return SUCCESS; - } - - DBG2(DBG_ENC, "copy all payloads to a temporary list"); + /* copy all payloads in a temporary list */ payloads = linked_list_create(); - - /* first copy all payloads in a temporary list */ - while (this->payloads->get_count(this->payloads) > 0) + while (this->payloads->remove_first(this->payloads, + (void**)¤t) == SUCCESS) { - this->payloads->remove_first(this->payloads, (void**)¤t); payloads->insert_last(payloads, current); } encryption = encryption_payload_create(); - - DBG2(DBG_ENC, "check each payloads if they have to get encrypted"); - while (payloads->get_count(payloads) > 0) + while (payloads->remove_first(payloads, (void**)¤t) == SUCCESS) { payload_rule_t *rule; payload_type_t type; - bool to_encrypt = TRUE; - - payloads->remove_first(payloads, (void**)¤t); + bool encrypt = TRUE; type = current->get_type(current); - if (get_payload_rule(this, type, &rule) == SUCCESS) + rule = get_payload_rule(this, type); + if (rule) { - to_encrypt = rule->encrypted; + encrypt = rule->encrypted; } - if (to_encrypt) + if (encrypt) { DBG2(DBG_ENC, "insert payload %N to encryption payload", - payload_type_names, current->get_type(current)); + payload_type_names, type); encryption->add_payload(encryption, current); } else { DBG2(DBG_ENC, "insert payload %N unencrypted", - payload_type_names, current->get_type(current)); - add_payload(this, (payload_t*)current); + payload_type_names, type); + add_payload(this, current); } } - - DBG2(DBG_ENC, "encrypting encryption payload"); - encryption->set_transforms(encryption, crypter, signer); - status = encryption->encrypt(encryption); - DBG2(DBG_ENC, "add encrypted payload to payload list"); - add_payload(this, (payload_t*)encryption); - payloads->destroy(payloads); - return status; + return encryption; } -/** - * Implementation of message_t.generate. - */ -static status_t generate(private_message_t *this, crypter_t *crypter, - signer_t* signer, packet_t **packet) +METHOD(message_t, generate, status_t, + private_message_t *this, aead_t *aead, packet_t **packet) { generator_t *generator; ike_header_t *ike_header; - payload_t *payload, *next_payload; + payload_t *payload, *next; + encryption_payload_t *encryption = NULL; enumerator_t *enumerator; - status_t status; - chunk_t packet_data; + chunk_t chunk; char str[256]; + u_int32_t *lenpos; if (is_encoded(this)) - { - /* already generated, return a new packet clone */ + { /* already generated, return a new packet clone */ *packet = this->packet->clone(this->packet); return SUCCESS; } @@ -1182,14 +1028,12 @@ static status_t generate(private_message_t *this, crypter_t *crypter, if (this->packet->get_source(this->packet) == NULL || this->packet->get_destination(this->packet) == NULL) { - DBG1(DBG_ENC, "%s not defined", - !this->packet->get_source(this->packet) ? "source" : "destination"); + DBG1(DBG_ENC, "source/destination not defined"); return INVALID_STATE; } - /* set the rules for this messge */ - status = set_message_rule(this); - if (status != SUCCESS) + this->rule = get_message_rule(this); + if (!this->rule) { DBG1(DBG_ENC, "no message rules specified for this message type"); return NOT_SUPPORTED; @@ -1199,17 +1043,16 @@ static status_t generate(private_message_t *this, crypter_t *crypter, DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str))); - /* going to encrypt all content which have to be encrypted */ - status = encrypt_payloads(this, crypter, signer); - if (status != SUCCESS) + if (aead && this->rule->encrypted) { - DBG1(DBG_ENC, "payload encryption failed"); - return status; + encryption = wrap_payloads(this); + } + else + { + DBG2(DBG_ENC, "not encrypting payloads"); } - /* build ike header */ ike_header = ike_header_create(); - ike_header->set_exchange_type(ike_header, this->exchange_type); ike_header->set_message_id(ike_header, this->message_id); ike_header->set_response_flag(ike_header, !this->is_request); @@ -1222,54 +1065,49 @@ static status_t generate(private_message_t *this, crypter_t *crypter, generator = generator_create(); + /* generate all payloads with proper next type */ payload = (payload_t*)ike_header; - - /* generate every payload expect last one, this is done later*/ enumerator = create_payload_enumerator(this); - while (enumerator->enumerate(enumerator, &next_payload)) + while (enumerator->enumerate(enumerator, &next)) { - payload->set_next_type(payload, next_payload->get_type(next_payload)); + payload->set_next_type(payload, next->get_type(next)); generator->generate_payload(generator, payload); - payload = next_payload; + payload = next; } enumerator->destroy(enumerator); - - /* last payload has no next payload*/ - payload->set_next_type(payload, NO_PAYLOAD); - + payload->set_next_type(payload, encryption ? ENCRYPTED : NO_PAYLOAD); generator->generate_payload(generator, payload); - ike_header->destroy(ike_header); - /* build packet */ - generator->write_to_chunk(generator, &packet_data); - generator->destroy(generator); - - /* if last payload is of type encrypted, integrity checksum if necessary */ - if (payload->get_type(payload) == ENCRYPTED) + if (encryption) { - DBG2(DBG_ENC, "build signature on whole message"); - encryption_payload_t *encryption_payload = (encryption_payload_t*)payload; - status = encryption_payload->build_signature(encryption_payload, packet_data); - if (status != SUCCESS) + u_int32_t *lenpos; + + /* build associated data (without header of encryption payload) */ + chunk = generator->get_chunk(generator, &lenpos); + encryption->set_transform(encryption, aead); + /* fill in length, including encryption payload */ + htoun32(lenpos, chunk.len + encryption->get_length(encryption)); + + this->payloads->insert_last(this->payloads, encryption); + if (!encryption->encrypt(encryption, chunk)) { - return status; + generator->destroy(generator); + return INVALID_STATE; } + generator->generate_payload(generator, &encryption->payload_interface); } + chunk = generator->get_chunk(generator, &lenpos); + htoun32(lenpos, chunk.len); + this->packet->set_data(this->packet, chunk_clone(chunk)); + generator->destroy(generator); - this->packet->set_data(this->packet, packet_data); - - /* clone packet for caller */ *packet = this->packet->clone(this->packet); - - DBG2(DBG_ENC, "message generated successfully"); return SUCCESS; } -/** - * Implementation of message_t.get_packet. - */ -static packet_t *get_packet(private_message_t *this) +METHOD(message_t, get_packet, packet_t*, + private_message_t *this) { if (this->packet == NULL) { @@ -1278,10 +1116,8 @@ static packet_t *get_packet(private_message_t *this) return this->packet->clone(this->packet); } -/** - * Implementation of message_t.get_packet_data. - */ -static chunk_t get_packet_data(private_message_t *this) +METHOD(message_t, get_packet_data, chunk_t, + private_message_t *this) { if (this->packet == NULL) { @@ -1290,10 +1126,8 @@ static chunk_t get_packet_data(private_message_t *this) return chunk_clone(this->packet->get_data(this->packet)); } -/** - * Implementation of message_t.parse_header. - */ -static status_t parse_header(private_message_t *this) +METHOD(message_t, parse_header, status_t, + private_message_t *this) { ike_header_t *ike_header; status_t status; @@ -1310,7 +1144,6 @@ static status_t parse_header(private_message_t *this) } - /* verify payload */ status = ike_header->payload_interface.verify( &ike_header->payload_interface); if (status != SUCCESS) @@ -1320,18 +1153,14 @@ static status_t parse_header(private_message_t *this) return status; } - if (this->ike_sa_id != NULL) - { - this->ike_sa_id->destroy(this->ike_sa_id); - } - + DESTROY_IF(this->ike_sa_id); this->ike_sa_id = ike_sa_id_create(ike_header->get_initiator_spi(ike_header), ike_header->get_responder_spi(ike_header), ike_header->get_initiator_flag(ike_header)); this->exchange_type = ike_header->get_exchange_type(ike_header); this->message_id = ike_header->get_message_id(ike_header); - this->is_request = (!(ike_header->get_response_flag(ike_header))); + this->is_request = !ike_header->get_response_flag(ike_header); this->major_version = ike_header->get_maj_version(ike_header); this->minor_version = ike_header->get_min_version(ike_header); this->first_payload = ike_header->payload_interface.get_next_type( @@ -1342,232 +1171,151 @@ static status_t parse_header(private_message_t *this) ike_header->destroy(ike_header); - /* get the rules for this messge */ - status = set_message_rule(this); - if (status != SUCCESS) + this->rule = get_message_rule(this); + if (!this->rule) { DBG1(DBG_ENC, "no message rules specified for a %N %s", exchange_type_names, this->exchange_type, this->is_request ? "request" : "response"); } - return status; } /** - * Implementation of private_message_t.decrypt_and_verify_payloads. + * Decrypt payload from the encryption payload */ -static status_t decrypt_payloads(private_message_t *this, crypter_t *crypter, - signer_t* signer) +static status_t decrypt_payloads(private_message_t *this, aead_t *aead) { - bool current_payload_was_encrypted = FALSE; - payload_t *previous_payload = NULL; - int payload_number = 1; - iterator_t *iterator; - payload_t *current_payload; - status_t status; - - iterator = this->payloads->create_iterator(this->payloads,TRUE); + bool was_encrypted = FALSE; + payload_t *payload, *previous = NULL; + enumerator_t *enumerator; + payload_rule_t *rule; + payload_type_t type; + status_t status = SUCCESS; - /* process each payload and decrypt a encryption payload */ - while(iterator->iterate(iterator, (void**)¤t_payload)) + enumerator = this->payloads->create_enumerator(this->payloads); + while (enumerator->enumerate(enumerator, &payload)) { - payload_rule_t *payload_rule; - payload_type_t current_payload_type; + type = payload->get_type(payload); - /* needed to check */ - current_payload_type = current_payload->get_type(current_payload); + DBG2(DBG_ENC, "process payload of type %N", payload_type_names, type); - DBG2(DBG_ENC, "process payload of type %N", - payload_type_names, current_payload_type); - - if (current_payload_type == ENCRYPTED) + if (type == ENCRYPTED) { - encryption_payload_t *encryption_payload; - payload_t *current_encrypted_payload; + encryption_payload_t *encryption; + payload_t *encrypted; + chunk_t chunk; - encryption_payload = (encryption_payload_t*)current_payload; + encryption = (encryption_payload_t*)payload; DBG2(DBG_ENC, "found an encryption payload"); - if (payload_number != this->payloads->get_count(this->payloads)) + if (enumerator->enumerate(enumerator, &payload)) { - /* encrypted payload is not last one */ DBG1(DBG_ENC, "encrypted payload is not last payload"); - iterator->destroy(iterator); - return VERIFY_ERROR; + status = VERIFY_ERROR; + break; } - /* decrypt */ - encryption_payload->set_transforms(encryption_payload, - crypter, signer); - DBG2(DBG_ENC, "verify signature of encryption payload"); - status = encryption_payload->verify_signature(encryption_payload, - this->packet->get_data(this->packet)); - if (status != SUCCESS) + encryption->set_transform(encryption, aead); + chunk = this->packet->get_data(this->packet); + if (chunk.len < encryption->get_length(encryption)) { - DBG1(DBG_ENC, "encryption payload signature invalid"); - iterator->destroy(iterator); - return FAILED; + DBG1(DBG_ENC, "invalid payload length"); + status = VERIFY_ERROR; + break; } - DBG2(DBG_ENC, "decrypting content of encryption payload"); - status = encryption_payload->decrypt(encryption_payload); + chunk.len -= encryption->get_length(encryption); + status = encryption->decrypt(encryption, chunk); if (status != SUCCESS) { - DBG1(DBG_ENC, "encrypted payload could not be decrypted and parsed"); - iterator->destroy(iterator); - return PARSE_ERROR; - } - - /* needed later to find out if a payload was encrypted */ - current_payload_was_encrypted = TRUE; - - /* check if there are payloads contained in the encryption payload */ - if (encryption_payload->get_payload_count(encryption_payload) == 0) - { - DBG2(DBG_ENC, "encrypted payload is empty"); - /* remove the encryption payload, is not needed anymore */ - iterator->remove(iterator); - /* encrypted payload contains no other payload */ - current_payload_type = NO_PAYLOAD; - } - else - { - /* encryption_payload is replaced with first payload contained - * in encryption_payload */ - encryption_payload->remove_first_payload(encryption_payload, - ¤t_encrypted_payload); - iterator->replace(iterator, NULL, - (void *)current_encrypted_payload); - current_payload_type = current_encrypted_payload->get_type( - current_encrypted_payload); + break; } - /* is the current paylad the first in the message? */ - if (previous_payload == NULL) - { - /* yes, set the first payload type of the message to the - * current type */ - this->first_payload = current_payload_type; - } - else - { - /* no, set the next_type of the previous payload to the - * current type */ - previous_payload->set_next_type(previous_payload, - current_payload_type); - } + was_encrypted = TRUE; + this->payloads->remove_at(this->payloads, enumerator); - /* all encrypted payloads are added to the payload list */ - while (encryption_payload->get_payload_count(encryption_payload) > 0) + while ((encrypted = encryption->remove_payload(encryption))) { - encryption_payload->remove_first_payload(encryption_payload, - ¤t_encrypted_payload); - DBG2(DBG_ENC, "insert unencrypted payload of type " - "%N at end of list", payload_type_names, - current_encrypted_payload->get_type( - current_encrypted_payload)); - this->payloads->insert_last(this->payloads, - current_encrypted_payload); + type = encrypted->get_type(encrypted); + if (previous) + { + previous->set_next_type(previous, type); + } + else + { + this->first_payload = type; + } + DBG2(DBG_ENC, "insert decrypted payload of type " + "%N at end of list", payload_type_names, type); + this->payloads->insert_last(this->payloads, encrypted); + previous = encrypted; } - - /* encryption payload is processed, payloads are moved. Destroy it. */ - encryption_payload->destroy(encryption_payload); + encryption->destroy(encryption); } - - /* we allow unknown payloads of any type and don't bother if it was - * encrypted. Not our problem. */ - if (current_payload_type != UNKNOWN_PAYLOAD && - current_payload_type != NO_PAYLOAD) + if (type != UNKNOWN_PAYLOAD && !was_encrypted) { - /* get the ruleset for found payload */ - status = get_payload_rule(this, current_payload_type, &payload_rule); - if (status != SUCCESS) - { - /* payload is not allowed */ - DBG1(DBG_ENC, "payload type %N not allowed", - payload_type_names, current_payload_type); - iterator->destroy(iterator); - return VERIFY_ERROR; - } - - /* check if the payload was encrypted, and if it should been have - * encrypted */ - if (payload_rule->encrypted != current_payload_was_encrypted) + rule = get_payload_rule(this, type); + if (!rule || rule->encrypted) { - /* payload was not encrypted, but should have been. - * or vice-versa */ - DBG1(DBG_ENC, "payload type %N should be %s!", - payload_type_names, current_payload_type, - (payload_rule->encrypted) ? "encrypted" : "not encrypted"); - iterator->destroy(iterator); - return VERIFY_ERROR; + DBG1(DBG_ENC, "payload type %N was not encrypted", + payload_type_names, type); + status = VERIFY_ERROR; + break; } } - /* advance to the next payload */ - payload_number++; - /* is stored to set next payload in case of found encryption payload */ - previous_payload = current_payload; + previous = payload; } - iterator->destroy(iterator); - return SUCCESS; + enumerator->destroy(enumerator); + return status; } /** - * Implementation of private_message_t.verify. + * Verify a message and all payload according to message/payload rules */ static status_t verify(private_message_t *this) { int i; - enumerator_t *enumerator; - payload_t *current_payload; - size_t total_found_payloads = 0; DBG2(DBG_ENC, "verifying message structure"); /* check for payloads with wrong count*/ - for (i = 0; i < this->message_rule->payload_rule_count; i++) + for (i = 0; i < this->rule->rule_count; i++) { - size_t found_payloads = 0; + enumerator_t *enumerator; + payload_t *payload; payload_rule_t *rule; + int found = 0; - rule = &this->message_rule->payload_rules[i]; + rule = &this->rule->rules[i]; enumerator = create_payload_enumerator(this); - - /* check all payloads for specific rule */ - while (enumerator->enumerate(enumerator, ¤t_payload)) + while (enumerator->enumerate(enumerator, &payload)) { - payload_type_t current_payload_type; - unknown_payload_t *unknown_payload; + payload_type_t type; + unknown_payload_t *unknown; - current_payload_type = current_payload->get_type(current_payload); - if (current_payload_type == UNKNOWN_PAYLOAD) + type = payload->get_type(payload); + if (type == UNKNOWN_PAYLOAD) { - /* unknown payloads are ignored, IF they are not critical */ - unknown_payload = (unknown_payload_t*)current_payload; - if (unknown_payload->is_critical(unknown_payload)) + /* unknown payloads are ignored if they are not critical */ + unknown = (unknown_payload_t*)payload; + if (unknown->is_critical(unknown)) { DBG1(DBG_ENC, "%N is not supported, but its critical!", - payload_type_names, current_payload_type); + payload_type_names, type); enumerator->destroy(enumerator); return NOT_SUPPORTED; } } - else if (current_payload_type == rule->payload_type) + else if (type == rule->type) { - found_payloads++; - total_found_payloads++; - DBG2(DBG_ENC, "found payload of type %N", payload_type_names, - rule->payload_type); - - /* as soon as ohe payload occures more then specified, - * the verification fails */ - if (found_payloads > - rule->max_occurence) + found++; + DBG2(DBG_ENC, "found payload of type %N", + payload_type_names, type); + if (found > rule->max_occurence) { DBG1(DBG_ENC, "payload of type %N more than %d times (%d) " "occured in current message", payload_type_names, - current_payload_type, rule->max_occurence, - found_payloads); + type, rule->max_occurence, found); enumerator->destroy(enumerator); return VERIFY_ERROR; } @@ -1575,11 +1323,10 @@ static status_t verify(private_message_t *this) } enumerator->destroy(enumerator); - if (found_payloads < rule->min_occurence) + if (found < rule->min_occurence) { DBG1(DBG_ENC, "payload of type %N not occured %d times (%d)", - payload_type_names, rule->payload_type, rule->min_occurence, - found_payloads); + payload_type_names, rule->type, rule->min_occurence, found); return VERIFY_ERROR; } if (rule->sufficient) @@ -1590,72 +1337,60 @@ static status_t verify(private_message_t *this) return SUCCESS; } -/** - * Implementation of message_t.parse_body. - */ -static status_t parse_body(private_message_t *this, crypter_t *crypter, - signer_t *signer) +METHOD(message_t, parse_body, status_t, + private_message_t *this, aead_t *aead) { status_t status = SUCCESS; - payload_type_t current_payload_type; + payload_t *payload; + payload_type_t type; char str[256]; - current_payload_type = this->first_payload; + type = this->first_payload; DBG2(DBG_ENC, "parsing body of message, first payload is %N", - payload_type_names, current_payload_type); + payload_type_names, type); - /* parse payload for payload, while there are more available */ - while ((current_payload_type != NO_PAYLOAD)) + while (type != NO_PAYLOAD) { - payload_t *current_payload; - DBG2(DBG_ENC, "starting parsing a %N payload", - payload_type_names, current_payload_type); + payload_type_names, type); - /* parse current payload */ - status = this->parser->parse_payload(this->parser, current_payload_type, - (payload_t**)¤t_payload); + status = this->parser->parse_payload(this->parser, type, &payload); if (status != SUCCESS) { DBG1(DBG_ENC, "payload type %N could not be parsed", - payload_type_names, current_payload_type); + payload_type_names, type); return PARSE_ERROR; } - DBG2(DBG_ENC, "verifying payload of type %N", - payload_type_names, current_payload_type); - - /* verify it, stop parsig if its invalid */ - status = current_payload->verify(current_payload); + DBG2(DBG_ENC, "verifying payload of type %N", payload_type_names, type); + status = payload->verify(payload); if (status != SUCCESS) { DBG1(DBG_ENC, "%N payload verification failed", - payload_type_names, current_payload_type); - current_payload->destroy(current_payload); + payload_type_names, type); + payload->destroy(payload); return VERIFY_ERROR; } DBG2(DBG_ENC, "%N payload verified. Adding to payload list", - payload_type_names, current_payload_type); - this->payloads->insert_last(this->payloads,current_payload); + payload_type_names, type); + this->payloads->insert_last(this->payloads, payload); /* an encryption payload is the last one, so STOP here. decryption is * done later */ - if (current_payload_type == ENCRYPTED) + if (type == ENCRYPTED) { DBG2(DBG_ENC, "%N payload found. Stop parsing", - payload_type_names, current_payload_type); + payload_type_names, type); break; } - - /* get next payload type */ - current_payload_type = current_payload->get_next_type(current_payload); + type = payload->get_next_type(payload); } - if (current_payload_type == ENCRYPTED) + if (type == ENCRYPTED) { - status = decrypt_payloads(this,crypter,signer); + status = decrypt_payloads(this, aead); if (status != SUCCESS) { DBG1(DBG_ENC, "could not decrypt payloads"); @@ -1674,10 +1409,8 @@ static status_t parse_body(private_message_t *this, crypter_t *crypter, return SUCCESS; } -/** - * Implementation of message_t.destroy. - */ -static void destroy (private_message_t *this) +METHOD(message_t, destroy, void, + private_message_t *this) { DESTROY_IF(this->ike_sa_id); this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy)); @@ -1691,58 +1424,48 @@ static void destroy (private_message_t *this) */ message_t *message_create_from_packet(packet_t *packet) { - private_message_t *this = malloc_thing(private_message_t); - - /* public functions */ - this->public.set_major_version = (void(*)(message_t*, u_int8_t))set_major_version; - this->public.get_major_version = (u_int8_t(*)(message_t*))get_major_version; - this->public.set_minor_version = (void(*)(message_t*, u_int8_t))set_minor_version; - this->public.get_minor_version = (u_int8_t(*)(message_t*))get_minor_version; - this->public.set_message_id = (void(*)(message_t*, u_int32_t))set_message_id; - this->public.get_message_id = (u_int32_t(*)(message_t*))get_message_id; - this->public.get_initiator_spi = (u_int64_t(*)(message_t*))get_initiator_spi; - this->public.get_responder_spi = (u_int64_t(*)(message_t*))get_responder_spi; - this->public.set_ike_sa_id = (void(*)(message_t*, ike_sa_id_t *))set_ike_sa_id; - this->public.get_ike_sa_id = (ike_sa_id_t*(*)(message_t*))get_ike_sa_id; - this->public.set_exchange_type = (void(*)(message_t*, exchange_type_t))set_exchange_type; - this->public.get_exchange_type = (exchange_type_t(*)(message_t*))get_exchange_type; - this->public.get_first_payload_type = (payload_type_t(*)(message_t*))get_first_payload_type; - this->public.set_request = (void(*)(message_t*, bool))set_request; - this->public.get_request = (bool(*)(message_t*))get_request; - this->public.add_payload = (void(*)(message_t*,payload_t*))add_payload; - this->public.add_notify = (void(*)(message_t*,bool,notify_type_t,chunk_t))add_notify; - this->public.generate = (status_t (*) (message_t *,crypter_t*,signer_t*,packet_t**)) generate; - this->public.set_source = (void (*) (message_t*,host_t*)) set_source; - this->public.get_source = (host_t * (*) (message_t*)) get_source; - this->public.set_destination = (void (*) (message_t*,host_t*)) set_destination; - this->public.get_destination = (host_t * (*) (message_t*)) get_destination; - this->public.create_payload_enumerator = (enumerator_t * (*) (message_t *)) create_payload_enumerator; - this->public.get_payload = (payload_t * (*) (message_t *, payload_type_t)) get_payload; - this->public.get_notify = (notify_payload_t*(*)(message_t*, notify_type_t type))get_notify; - this->public.parse_header = (status_t (*) (message_t *)) parse_header; - this->public.parse_body = (status_t (*) (message_t *,crypter_t*,signer_t*)) parse_body; - this->public.get_packet = (packet_t * (*) (message_t*)) get_packet; - this->public.get_packet_data = (chunk_t (*) (message_t *this)) get_packet_data; - this->public.destroy = (void(*)(message_t*))destroy; - - /* private values */ - this->exchange_type = EXCHANGE_TYPE_UNDEFINED; - this->is_request = TRUE; - this->ike_sa_id = NULL; - this->first_payload = NO_PAYLOAD; - this->message_id = 0; - - /* private values */ - if (packet == NULL) - { - packet = packet_create(); - } - this->message_rule = NULL; - this->packet = packet; - this->payloads = linked_list_create(); - - /* parser is created from data of packet */ - this->parser = parser_create(this->packet->get_data(this->packet)); + private_message_t *this; + + INIT(this, + .public = { + .set_major_version = _set_major_version, + .get_major_version = _get_major_version, + .set_minor_version = _set_minor_version, + .get_minor_version = _get_minor_version, + .set_message_id = _set_message_id, + .get_message_id = _get_message_id, + .get_initiator_spi = _get_initiator_spi, + .get_responder_spi = _get_responder_spi, + .set_ike_sa_id = _set_ike_sa_id, + .get_ike_sa_id = _get_ike_sa_id, + .set_exchange_type = _set_exchange_type, + .get_exchange_type = _get_exchange_type, + .get_first_payload_type = _get_first_payload_type, + .set_request = _set_request, + .get_request = _get_request, + .add_payload = _add_payload, + .add_notify = _add_notify, + .generate = _generate, + .set_source = _set_source, + .get_source = _get_source, + .set_destination = _set_destination, + .get_destination = _get_destination, + .create_payload_enumerator = _create_payload_enumerator, + .get_payload = _get_payload, + .get_notify = _get_notify, + .parse_header = _parse_header, + .parse_body = _parse_body, + .get_packet = _get_packet, + .get_packet_data = _get_packet_data, + .destroy = _destroy, + }, + .exchange_type = EXCHANGE_TYPE_UNDEFINED, + .is_request = TRUE, + .first_payload = NO_PAYLOAD, + .packet = packet, + .payloads = linked_list_create(), + .parser = parser_create(packet->get_data(packet)), + ); return (&this->public); } @@ -1752,6 +1475,6 @@ message_t *message_create_from_packet(packet_t *packet) */ message_t *message_create() { - return message_create_from_packet(NULL); + return message_create_from_packet(packet_create()); } diff --git a/src/libcharon/encoding/message.h b/src/libcharon/encoding/message.h index 2c7718f49..8c1cbcd09 100644 --- a/src/libcharon/encoding/message.h +++ b/src/libcharon/encoding/message.h @@ -32,8 +32,7 @@ typedef struct message_t message_t; #include <encoding/payloads/ike_header.h> #include <encoding/payloads/notify_payload.h> #include <utils/linked_list.h> -#include <crypto/crypters/crypter.h> -#include <crypto/signers/signer.h> +#include <crypto/aead.h> /** * This class is used to represent an IKEv2-Message. @@ -201,14 +200,10 @@ struct message_t { * The body gets not only parsed, but rather it gets verified. * All payloads are verified if they are allowed to exist in the message * of this type and if their own structure is ok. - * If there are encrypted payloads, they get decrypted via the supplied - * crypter. Also the message integrity gets verified with the supplied - * signer. - * Crypter/signer can be omitted (by passing NULL) when no encryption - * payload is expected. - * - * @param crypter crypter to decrypt encryption payloads - * @param signer signer to verifiy a message with an encryption payload + * If there are encrypted payloads, they get decrypted and verified using + * the given aead transform (if given). + * + * @param aead aead transform to verify/decrypt message * @return * - SUCCESS if parsing successful * - NOT_SUPPORTED if ciritcal unknown payloads found @@ -216,32 +211,28 @@ struct message_t { * - PARSE_ERROR if message parsing failed * - VERIFY_ERROR if message verification failed (bad syntax) * - FAILED if integrity check failed - * - INVALID_STATE if crypter/signer not supplied, but needed + * - INVALID_STATE if aead not supplied, but needed */ - status_t (*parse_body) (message_t *this, crypter_t *crypter, signer_t *signer); + status_t (*parse_body) (message_t *this, aead_t *aead); /** * Generates the UDP packet of specific message. * * Payloads which must be encrypted are generated first and added to - * an encryption payload. This encryption payload will get encrypted via - * the supplied crypter. Then all other payloads and the header get generated. - * After that, the checksum is added to the encryption payload over the full - * message. - * Crypter/signer can be omitted (by passing NULL) when no encryption - * payload is expected. - * Generation is only done once, multiple calls will just return a packet copy. - * - * @param crypter crypter to use when a payload must be encrypted - * @param signer signer to build a mac + * an encryption payload. This encryption payload will get encrypted and + * signed via the supplied aead transform (if given). + * Generation is only done once, multiple calls will just return a copy + * of the packet. + * + * @param aead aead transform to encrypt/sign message * @param packet copy of generated packet * @return * - SUCCESS if packet could be generated * - INVALID_STATE if exchange type is currently not set * - NOT_FOUND if no rules found for message generation - * - INVALID_STATE if crypter/signer not supplied but needed. + * - INVALID_STATE if aead not supplied but needed. */ - status_t (*generate) (message_t *this, crypter_t *crypter, signer_t *signer, packet_t **packet); + status_t (*generate) (message_t *this, aead_t *aead, packet_t **packet); /** * Gets the source host informations. @@ -331,13 +322,8 @@ struct message_t { /** * Creates an message_t object from a incoming UDP Packet. * - * @warning the given packet_t object is not copied and gets - * destroyed in message_t's destroy call. - * - * - exchange_type is set to NOT_SET - * - original_initiator is set to TRUE - * - is_request is set to TRUE - * Call message_t.parse_header afterwards. + * The given packet gets owned by the message. The message is uninitialized, + * call parse_header() to populate header fields. * * @param packet packet_t object which is assigned to message * @return message_t object diff --git a/src/libcharon/encoding/payloads/delete_payload.c b/src/libcharon/encoding/payloads/delete_payload.c index 97b4743b2..5fc3b7c88 100644 --- a/src/libcharon/encoding/payloads/delete_payload.c +++ b/src/libcharon/encoding/payloads/delete_payload.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2010 Martin Willi + * Copyright (C) 2010 revosec AG * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -65,11 +66,6 @@ struct private_delete_payload_t { * The contained SPI's. */ chunk_t spis; - - /** - * List containing u_int32_t spis - */ - linked_list_t *spi_list; }; /** @@ -77,7 +73,6 @@ struct private_delete_payload_t { * * The defined offsets are the positions in a object of type * private_delete_payload_t. - * */ encoding_rule_t delete_payload_encodings[] = { /* 1 Byte next payload type, stored in the field next_payload */ @@ -85,20 +80,20 @@ encoding_rule_t delete_payload_encodings[] = { /* the critical bit */ { FLAG, offsetof(private_delete_payload_t, critical) }, /* 7 Bit reserved bits, nowhere stored */ - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, /* Length of the whole payload*/ - { PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length)}, + { PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length) }, { U_INT_8, offsetof(private_delete_payload_t, protocol_id) }, { U_INT_8, offsetof(private_delete_payload_t, spi_size) }, { U_INT_16, offsetof(private_delete_payload_t, spi_count) }, /* some delete data bytes, length is defined in PAYLOAD_LENGTH */ - { SPIS, offsetof(private_delete_payload_t, spis) } + { SPIS, offsetof(private_delete_payload_t, spis) } }; /* @@ -115,10 +110,8 @@ encoding_rule_t delete_payload_encodings[] = { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -/** - * Implementation of payload_t.verify. - */ -static status_t verify(private_delete_payload_t *this) +METHOD(payload_t, verify, status_t, + private_delete_payload_t *this) { switch (this->protocol_id) { @@ -147,112 +140,104 @@ static status_t verify(private_delete_payload_t *this) return SUCCESS; } -/** - * Implementation of delete_payload_t.get_encoding_rules. - */ -static void get_encoding_rules(private_delete_payload_t *this, encoding_rule_t **rules, size_t *rule_count) +METHOD(payload_t, get_encoding_rules, void, + private_delete_payload_t *this, encoding_rule_t **rules, size_t *rule_count) { *rules = delete_payload_encodings; - *rule_count = sizeof(delete_payload_encodings) / sizeof(encoding_rule_t); + *rule_count = countof(delete_payload_encodings); } -/** - * Implementation of payload_t.get_type. - */ -static payload_type_t get_payload_type(private_delete_payload_t *this) +METHOD(payload_t, get_payload_type, payload_type_t, + private_delete_payload_t *this) { return DELETE; } -/** - * Implementation of payload_t.get_next_type. - */ -static payload_type_t get_next_type(private_delete_payload_t *this) +METHOD(payload_t, get_next_type, payload_type_t, + private_delete_payload_t *this) { - return (this->next_payload); + return this->next_payload; } -/** - * Implementation of payload_t.set_next_type. - */ -static void set_next_type(private_delete_payload_t *this,payload_type_t type) +METHOD(payload_t, set_next_type, void, + private_delete_payload_t *this,payload_type_t type) { this->next_payload = type; } -/** - * Implementation of payload_t.get_length. - */ -static size_t get_length(private_delete_payload_t *this) +METHOD(payload_t, get_length, size_t, + private_delete_payload_t *this) { return this->payload_length; } -/** - * Implementation of delete_payload_t.get_protocol_id. - */ -static protocol_id_t get_protocol_id (private_delete_payload_t *this) +METHOD(delete_payload_t, get_protocol_id, protocol_id_t, + private_delete_payload_t *this) { - return (this->protocol_id); + return this->protocol_id; } -/** - * Implementation of delete_payload_t.add_spi. - */ -static void add_spi(private_delete_payload_t *this, u_int32_t spi) +METHOD(delete_payload_t, add_spi, void, + private_delete_payload_t *this, u_int32_t spi) { - /* only add SPIs if AH|ESP, ignore others */ - if (this->protocol_id == PROTO_AH || this->protocol_id == PROTO_ESP) + switch (this->protocol_id) { - this->spi_count += 1; - this->spis.len += this->spi_size; - this->spis.ptr = realloc(this->spis.ptr, this->spis.len); - *(u_int32_t*)(this->spis.ptr + (this->spis.len / this->spi_size - 1)) = spi; - if (this->spi_list) - { - /* reset SPI iterator list */ - this->spi_list->destroy(this->spi_list); - this->spi_list = NULL; - } + case PROTO_AH: + case PROTO_ESP: + this->spi_count++; + this->payload_length += sizeof(spi); + this->spis = chunk_cat("mc", this->spis, chunk_from_thing(spi)); + break; + default: + break; } } /** - * Implementation of delete_payload_t.create_spi_iterator. + * SPI enumerator implementation */ -static iterator_t* create_spi_iterator(private_delete_payload_t *this) -{ - int i; +typedef struct { + /** implements enumerator_t */ + enumerator_t public; + /** remaining SPIs */ + chunk_t spis; +} spi_enumerator_t; - if (this->spi_list == NULL) +METHOD(enumerator_t, spis_enumerate, bool, + spi_enumerator_t *this, u_int32_t *spi) +{ + if (this->spis.len >= sizeof(*spi)) { - this->spi_list = linked_list_create(); - /* only parse SPIs if AH|ESP */ - if (this->protocol_id == PROTO_AH || this->protocol_id == PROTO_ESP) - { - for (i = 0; i < this->spi_count; i++) - { - this->spi_list->insert_last(this->spi_list, this->spis.ptr + i * - this->spi_size); - } - } + memcpy(spi, this->spis.ptr, sizeof(*spi)); + this->spis = chunk_skip(this->spis, sizeof(*spi)); + return TRUE; } - return this->spi_list->create_iterator(this->spi_list, TRUE); + return FALSE; } -/** - * Implementation of payload_t.destroy and delete_payload_t.destroy. - */ -static void destroy(private_delete_payload_t *this) +METHOD(delete_payload_t, create_spi_enumerator, enumerator_t*, + private_delete_payload_t *this) { - if (this->spis.ptr != NULL) - { - chunk_free(&this->spis); - } - if (this->spi_list) + spi_enumerator_t *e; + + if (this->spi_size != sizeof(u_int32_t)) { - this->spi_list->destroy(this->spi_list); + return enumerator_create_empty(); } + INIT(e, + .public = { + .enumerate = (void*)_spis_enumerate, + .destroy = (void*)free, + }, + .spis = this->spis, + ); + return &e->public; +} + +METHOD2(payload_t, delete_payload_t, destroy, void, + private_delete_payload_t *this) +{ + free(this->spis.ptr); free(this); } @@ -261,32 +246,28 @@ static void destroy(private_delete_payload_t *this) */ delete_payload_t *delete_payload_create(protocol_id_t protocol_id) { - private_delete_payload_t *this = malloc_thing(private_delete_payload_t); - - /* interface functions */ - this->public.payload_interface.verify = (status_t (*) (payload_t *))verify; - this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules; - this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length; - this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type; - this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type; - this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type; - this->public.payload_interface.destroy = (void (*) (payload_t *))destroy; - - /* public functions */ - this->public.destroy = (void (*) (delete_payload_t *)) destroy; - this->public.get_protocol_id = (protocol_id_t (*) (delete_payload_t *)) get_protocol_id; - this->public.add_spi = (void (*) (delete_payload_t *,u_int32_t))add_spi; - this->public.create_spi_iterator = (iterator_t* (*) (delete_payload_t *)) create_spi_iterator; - - /* private variables */ - this->critical = FALSE; - this->next_payload = NO_PAYLOAD; - this->payload_length = DELETE_PAYLOAD_HEADER_LENGTH; - this->protocol_id = protocol_id; - this->spi_size = protocol_id == PROTO_AH || protocol_id == PROTO_ESP ? 4 : 0; - this->spi_count = 0; - this->spis = chunk_empty; - this->spi_list = NULL; + private_delete_payload_t *this; - return (&this->public); + INIT(this, + .public = { + .payload_interface = { + .verify = _verify, + .get_encoding_rules = _get_encoding_rules, + .get_length = _get_length, + .get_next_type = _get_next_type, + .set_next_type = _set_next_type, + .get_type = _get_payload_type, + .destroy = _destroy, + }, + .get_protocol_id = _get_protocol_id, + .add_spi = _add_spi, + .create_spi_enumerator = _create_spi_enumerator, + .destroy = _destroy, + }, + .next_payload = NO_PAYLOAD, + .payload_length = DELETE_PAYLOAD_HEADER_LENGTH, + .protocol_id = protocol_id, + .spi_size = protocol_id == PROTO_AH || protocol_id == PROTO_ESP ? 4 : 0, + ); + return &this->public; } diff --git a/src/libcharon/encoding/payloads/delete_payload.h b/src/libcharon/encoding/payloads/delete_payload.h index 3b62c1af1..026829f97 100644 --- a/src/libcharon/encoding/payloads/delete_payload.h +++ b/src/libcharon/encoding/payloads/delete_payload.h @@ -39,6 +39,7 @@ typedef struct delete_payload_t delete_payload_t; * The DELETE payload format is described in RFC section 3.11. */ struct delete_payload_t { + /** * The payload_t interface. */ @@ -59,13 +60,11 @@ struct delete_payload_t { void (*add_spi) (delete_payload_t *this, u_int32_t spi); /** - * Get an iterator over the SPIs. - * - * The iterate() function returns a pointer to a u_int32_t SPI. + * Get an enumerator over the SPIs in network order. * - * @return iterator over SPIs + * @return enumerator over SPIs, u_int32_t */ - iterator_t *(*create_spi_iterator) (delete_payload_t *this); + enumerator_t *(*create_spi_enumerator) (delete_payload_t *this); /** * Destroys an delete_payload_t object. diff --git a/src/libcharon/encoding/payloads/encryption_payload.c b/src/libcharon/encoding/payloads/encryption_payload.c index 2adbb88b9..3b23ea9fb 100644 --- a/src/libcharon/encoding/payloads/encryption_payload.c +++ b/src/libcharon/encoding/payloads/encryption_payload.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2010 Martin Willi + * Copyright (C) 2010 revosec AG * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -24,9 +25,6 @@ #include <utils/linked_list.h> #include <encoding/generator.h> #include <encoding/parser.h> -#include <utils/iterator.h> -#include <crypto/signers/signer.h> - typedef struct private_encryption_payload_t private_encryption_payload_t; @@ -50,9 +48,9 @@ struct private_encryption_payload_t { u_int8_t next_payload; /** - * Critical flag. + * Flags, including reserved bits */ - bool critical; + u_int8_t flags; /** * Length of this payload @@ -60,28 +58,17 @@ struct private_encryption_payload_t { u_int16_t payload_length; /** - * Chunk containing the iv, data, padding, - * and (an eventually not calculated) signature. + * Chunk containing the IV, plain, padding and ICV. */ chunk_t encrypted; /** - * Chunk containing the data in decrypted (unpadded) form. - */ - chunk_t decrypted; - - /** - * Signer set by set_signer. + * AEAD transform to use */ - signer_t *signer; + aead_t *aead; /** - * Crypter, supplied by encrypt/decrypt - */ - crypter_t *crypter; - - /** - * Contained payloads of this encrpytion_payload. + * Contained payloads */ linked_list_t *payloads; }; @@ -91,25 +78,16 @@ struct private_encryption_payload_t { * * The defined offsets are the positions in a object of type * private_encryption_payload_t. - * */ encoding_rule_t encryption_payload_encodings[] = { /* 1 Byte next payload type, stored in the field next_payload */ { U_INT_8, offsetof(private_encryption_payload_t, next_payload) }, - /* the critical bit */ - { FLAG, offsetof(private_encryption_payload_t, critical) }, - /* 7 Bit reserved bits, nowhere stored */ - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, + /* Critical and 7 reserved bits, all stored for reconstruction */ + { U_INT_8, offsetof(private_encryption_payload_t, flags) }, /* Length of the whole encryption payload*/ { PAYLOAD_LENGTH, offsetof(private_encryption_payload_t, payload_length) }, /* encrypted data, stored in a chunk. contains iv, data, padding */ - { ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) }, + { ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) }, }; /* @@ -131,108 +109,90 @@ encoding_rule_t encryption_payload_encodings[] = { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -/** - * Implementation of payload_t.verify. - */ -static status_t verify(private_encryption_payload_t *this) +METHOD(payload_t, verify, status_t, + private_encryption_payload_t *this) { return SUCCESS; } -/** - * Implementation of payload_t.get_encoding_rules. - */ -static void get_encoding_rules(private_encryption_payload_t *this, encoding_rule_t **rules, size_t *rule_count) +METHOD(payload_t, get_encoding_rules, void, + private_encryption_payload_t *this, encoding_rule_t **rules, + size_t *count) { *rules = encryption_payload_encodings; - *rule_count = sizeof(encryption_payload_encodings) / sizeof(encoding_rule_t); + *count = countof(encryption_payload_encodings); } -/** - * Implementation of payload_t.get_type. - */ -static payload_type_t get_type(private_encryption_payload_t *this) +METHOD(payload_t, get_type, payload_type_t, + private_encryption_payload_t *this) { return ENCRYPTED; } -/** - * Implementation of payload_t.get_next_type. - */ -static payload_type_t get_next_type(private_encryption_payload_t *this) +METHOD(payload_t, get_next_type, payload_type_t, + private_encryption_payload_t *this) { - /* returns first contained payload here */ - return (this->next_payload); + return this->next_payload; } -/** - * Implementation of payload_t.set_next_type. - */ -static void set_next_type(private_encryption_payload_t *this, payload_type_t type) +METHOD(payload_t, set_next_type, void, + private_encryption_payload_t *this, payload_type_t type) { - /* set next type is not allowed, since this payload MUST be the last one - * and so nothing is done in here*/ + /* the next payload is set during add */ } /** - * (re-)compute the lenght of the whole payload + * Compute the lenght of the whole payload */ static void compute_length(private_encryption_payload_t *this) { - iterator_t *iterator; - payload_t *current_payload; - size_t block_size, length = 0; - iterator = this->payloads->create_iterator(this->payloads, TRUE); + enumerator_t *enumerator; + payload_t *payload; + size_t bs, length = 0; - /* count payload length */ - while (iterator->iterate(iterator, (void **) ¤t_payload)) + if (this->encrypted.len) { - length += current_payload->get_length(current_payload); + length = this->encrypted.len; } - iterator->destroy(iterator); - - if (this->crypter && this->signer) + else { - /* append one byte for padding length */ - length++; - /* append padding */ - block_size = this->crypter->get_block_size(this->crypter); - length += block_size - length % block_size; - /* add iv */ - length += block_size; - /* add signature */ - length += this->signer->get_block_size(this->signer); + enumerator = this->payloads->create_enumerator(this->payloads); + while (enumerator->enumerate(enumerator, &payload)) + { + length += payload->get_length(payload); + } + enumerator->destroy(enumerator); + + if (this->aead) + { + /* append padding */ + bs = this->aead->get_block_size(this->aead); + length += bs - (length % bs); + /* add iv */ + length += this->aead->get_iv_size(this->aead); + /* add icv */ + length += this->aead->get_icv_size(this->aead); + } } length += ENCRYPTION_PAYLOAD_HEADER_LENGTH; this->payload_length = length; } -/** - * Implementation of payload_t.get_length. - */ -static size_t get_length(private_encryption_payload_t *this) +METHOD2(payload_t, encryption_payload_t, get_length, size_t, + private_encryption_payload_t *this) { compute_length(this); return this->payload_length; } -/** - * Implementation of payload_t.create_payload_iterator. - */ -static iterator_t *create_payload_iterator (private_encryption_payload_t *this, bool forward) -{ - return (this->payloads->create_iterator(this->payloads, forward)); -} - -/** - * Implementation of payload_t.add_payload. - */ -static void add_payload(private_encryption_payload_t *this, payload_t *payload) +METHOD(encryption_payload_t, add_payload, void, + private_encryption_payload_t *this, payload_t *payload) { payload_t *last_payload; + if (this->payloads->get_count(this->payloads) > 0) { - this->payloads->get_last(this->payloads,(void **) &last_payload); + this->payloads->get_last(this->payloads, (void **)&last_payload); last_payload->set_next_type(last_payload, payload->get_type(payload)); } else @@ -240,339 +200,255 @@ static void add_payload(private_encryption_payload_t *this, payload_t *payload) this->next_payload = payload->get_type(payload); } payload->set_next_type(payload, NO_PAYLOAD); - this->payloads->insert_last(this->payloads, (void*)payload); + this->payloads->insert_last(this->payloads, payload); compute_length(this); } -/** - * Implementation of encryption_payload_t.remove_first_payload. - */ -static status_t remove_first_payload(private_encryption_payload_t *this, payload_t **payload) +METHOD(encryption_payload_t, remove_payload, payload_t *, + private_encryption_payload_t *this) { - return this->payloads->remove_first(this->payloads, (void**)payload); -} + payload_t *payload; -/** - * Implementation of encryption_payload_t.get_payload_count. - */ -static size_t get_payload_count(private_encryption_payload_t *this) -{ - return this->payloads->get_count(this->payloads); + if (this->payloads->remove_first(this->payloads, + (void**)&payload) == SUCCESS) + { + return payload; + } + return NULL; } /** - * Generate payload before encryption. + * Generate payload before encryption */ -static void generate(private_encryption_payload_t *this) +static chunk_t generate(private_encryption_payload_t *this, + generator_t *generator) { - payload_t *current_payload, *next_payload; - generator_t *generator; - iterator_t *iterator; - - /* recalculate length before generating */ - compute_length(this); + payload_t *current, *next; + enumerator_t *enumerator; + u_int32_t *lenpos; + chunk_t chunk = chunk_empty; - /* create iterator */ - iterator = this->payloads->create_iterator(this->payloads, TRUE); - - /* get first payload */ - if (iterator->iterate(iterator, (void**)¤t_payload)) - { - this->next_payload = current_payload->get_type(current_payload); - } - else + enumerator = this->payloads->create_enumerator(this->payloads); + if (enumerator->enumerate(enumerator, ¤t)) { - /* no paylads? */ - DBG2(DBG_ENC, "generating contained payloads, but none available"); - free(this->decrypted.ptr); - this->decrypted = chunk_empty; - iterator->destroy(iterator); - return; - } + this->next_payload = current->get_type(current); - generator = generator_create(); + while (enumerator->enumerate(enumerator, &next)) + { + current->set_next_type(current, next->get_type(next)); + generator->generate_payload(generator, current); + current = next; + } + current->set_next_type(current, NO_PAYLOAD); + generator->generate_payload(generator, current); - /* build all payload, except last */ - while(iterator->iterate(iterator, (void**)&next_payload)) - { - current_payload->set_next_type(current_payload, next_payload->get_type(next_payload)); - generator->generate_payload(generator, current_payload); - current_payload = next_payload; + chunk = generator->get_chunk(generator, &lenpos); + DBG2(DBG_ENC, "generated content in encryption payload"); } - iterator->destroy(iterator); - - /* build last payload */ - current_payload->set_next_type(current_payload, NO_PAYLOAD); - generator->generate_payload(generator, current_payload); - - /* free already generated data */ - free(this->decrypted.ptr); - - generator->write_to_chunk(generator, &(this->decrypted)); - generator->destroy(generator); - DBG2(DBG_ENC, "successfully generated content in encryption payload"); + enumerator->destroy(enumerator); + return chunk; } /** - * Implementation of encryption_payload_t.encrypt. + * Append the encryption payload header to the associated data */ -static status_t encrypt(private_encryption_payload_t *this) +static chunk_t append_header(private_encryption_payload_t *this, chunk_t assoc) { - chunk_t iv, padding, to_crypt, result; + struct { + u_int8_t next_payload; + u_int8_t flags; + u_int16_t length; + } __attribute__((packed)) header = { + .next_payload = this->next_payload, + .flags = this->flags, + .length = htons(get_length(this)), + }; + return chunk_cat("cc", assoc, chunk_from_thing(header)); +} + +METHOD(encryption_payload_t, encrypt, bool, + private_encryption_payload_t *this, chunk_t assoc) +{ + chunk_t iv, plain, padding, icv, crypt; + generator_t *generator; rng_t *rng; - size_t block_size; + size_t bs; - if (this->signer == NULL || this->crypter == NULL) + if (this->aead == NULL) { - DBG1(DBG_ENC, "could not encrypt, signer/crypter not set"); - return INVALID_STATE; + DBG1(DBG_ENC, "encrypting encryption payload failed, transform missing"); + return FALSE; } - /* for random data in iv and padding */ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); if (!rng) { - DBG1(DBG_ENC, "could not encrypt, no RNG found"); - return FAILED; + DBG1(DBG_ENC, "encrypting encryption payload failed, no RNG found"); + return FALSE; } - /* build payload chunk */ - generate(this); - DBG2(DBG_ENC, "encrypting payloads"); - DBG3(DBG_ENC, "data to encrypt %B", &this->decrypted); + assoc = append_header(this, assoc); - /* build padding */ - block_size = this->crypter->get_block_size(this->crypter); - padding.len = block_size - ((this->decrypted.len + 1) % block_size); - rng->allocate_bytes(rng, padding.len, &padding); - - /* concatenate payload data, padding, padding len */ - to_crypt.len = this->decrypted.len + padding.len + 1; - to_crypt.ptr = malloc(to_crypt.len); - - memcpy(to_crypt.ptr, this->decrypted.ptr, this->decrypted.len); - memcpy(to_crypt.ptr + this->decrypted.len, padding.ptr, padding.len); - *(to_crypt.ptr + to_crypt.len - 1) = padding.len; + generator = generator_create(); + plain = generate(this, generator); + bs = this->aead->get_block_size(this->aead); + /* we need at least one byte padding to store the padding length */ + padding.len = bs - (plain.len % bs); + iv.len = this->aead->get_iv_size(this->aead); + icv.len = this->aead->get_icv_size(this->aead); + + /* prepare data to authenticate-encrypt: + * | IV | plain | padding | ICV | + * \____crypt______/ ^ + * | / + * v / + * assoc -> + ------->/ + */ + free(this->encrypted.ptr); + this->encrypted = chunk_alloc(iv.len + plain.len + padding.len + icv.len); + iv.ptr = this->encrypted.ptr; + memcpy(iv.ptr + iv.len, plain.ptr, plain.len); + plain.ptr = iv.ptr + iv.len; + padding.ptr = plain.ptr + plain.len; + icv.ptr = padding.ptr + padding.len; + crypt = chunk_create(plain.ptr, plain.len + padding.len); + generator->destroy(generator); - /* build iv */ - iv.len = block_size; - rng->allocate_bytes(rng, iv.len, &iv); + rng->get_bytes(rng, iv.len, iv.ptr); + rng->get_bytes(rng, padding.len - 1, padding.ptr); + padding.ptr[padding.len - 1] = padding.len - 1; rng->destroy(rng); - DBG3(DBG_ENC, "data before encryption with padding %B", &to_crypt); + DBG3(DBG_ENC, "encryption payload encryption:"); + DBG3(DBG_ENC, "IV %B", &iv); + DBG3(DBG_ENC, "plain %B", &plain); + DBG3(DBG_ENC, "padding %B", &padding); + DBG3(DBG_ENC, "assoc %B", &assoc); - /* encrypt to_crypt chunk */ - free(this->encrypted.ptr); - this->crypter->encrypt(this->crypter, to_crypt, iv, &result); - free(padding.ptr); - free(to_crypt.ptr); - - DBG3(DBG_ENC, "data after encryption %B", &result); - - /* build encrypted result with iv and signature */ - this->encrypted.len = iv.len + result.len + this->signer->get_block_size(this->signer); - free(this->encrypted.ptr); - this->encrypted.ptr = malloc(this->encrypted.len); + this->aead->encrypt(this->aead, crypt, assoc, iv, NULL); - /* fill in result, signature is left out */ - memcpy(this->encrypted.ptr, iv.ptr, iv.len); - memcpy(this->encrypted.ptr + iv.len, result.ptr, result.len); + DBG3(DBG_ENC, "encrypted %B", &crypt); + DBG3(DBG_ENC, "ICV %B", &icv); - free(result.ptr); - free(iv.ptr); - DBG3(DBG_ENC, "data after encryption with IV and (invalid) signature %B", - &this->encrypted); + free(assoc.ptr); - return SUCCESS; + return TRUE; } /** * Parse the payloads after decryption. */ -static status_t parse(private_encryption_payload_t *this) +static status_t parse(private_encryption_payload_t *this, chunk_t plain) { parser_t *parser; - status_t status; - payload_type_t current_payload_type; - - /* build a parser on the decrypted data */ - parser = parser_create(this->decrypted); + payload_type_t type; - current_payload_type = this->next_payload; - /* parse all payloads */ - while (current_payload_type != NO_PAYLOAD) + parser = parser_create(plain); + type = this->next_payload; + while (type != NO_PAYLOAD) { - payload_t *current_payload; + payload_t *payload; - status = parser->parse_payload(parser, current_payload_type, (payload_t**)¤t_payload); - if (status != SUCCESS) + if (parser->parse_payload(parser, type, &payload) != SUCCESS) { parser->destroy(parser); return PARSE_ERROR; } - - status = current_payload->verify(current_payload); - if (status != SUCCESS) + if (payload->verify(payload) != SUCCESS) { DBG1(DBG_ENC, "%N verification failed", - payload_type_names, current_payload->get_type(current_payload)); - current_payload->destroy(current_payload); + payload_type_names, payload->get_type(payload)); + payload->destroy(payload); parser->destroy(parser); return VERIFY_ERROR; } - - /* get next payload type */ - current_payload_type = current_payload->get_next_type(current_payload); - - this->payloads->insert_last(this->payloads,current_payload); + type = payload->get_next_type(payload); + this->payloads->insert_last(this->payloads, payload); } parser->destroy(parser); - DBG2(DBG_ENC, "succesfully parsed content of encryption payload"); + DBG2(DBG_ENC, "parsed content of encryption payload"); return SUCCESS; } -/** - * Implementation of encryption_payload_t.encrypt. - */ -static status_t decrypt(private_encryption_payload_t *this) +METHOD(encryption_payload_t, decrypt, status_t, + private_encryption_payload_t *this, chunk_t assoc) { - chunk_t iv, concatenated; - u_int8_t padding_length; - - DBG2(DBG_ENC, "decrypting encryption payload"); - DBG3(DBG_ENC, "data before decryption with IV and (invalid) signature %B", - &this->encrypted); + chunk_t iv, plain, padding, icv, crypt; + size_t bs; - if (this->signer == NULL || this->crypter == NULL) + if (this->aead == NULL) { - DBG1(DBG_ENC, "could not decrypt, no crypter/signer set"); + DBG1(DBG_ENC, "decrypting encryption payload failed, transform missing"); return INVALID_STATE; } - /* get IV */ - iv.len = this->crypter->get_block_size(this->crypter); + /* prepare data to authenticate-decrypt: + * | IV | plain | padding | ICV | + * \____crypt______/ ^ + * | / + * v / + * assoc -> + ------->/ + */ + bs = this->aead->get_block_size(this->aead); + iv.len = this->aead->get_iv_size(this->aead); iv.ptr = this->encrypted.ptr; + icv.len = this->aead->get_icv_size(this->aead); + icv.ptr = this->encrypted.ptr + this->encrypted.len - icv.len; + crypt.ptr = iv.ptr + iv.len; + crypt.len = this->encrypted.len - iv.len; - /* point concatenated to data + padding + padding_length*/ - concatenated.ptr = this->encrypted.ptr + iv.len; - concatenated.len = this->encrypted.len - iv.len - - this->signer->get_block_size(this->signer); - - /* concatenated must be a multiple of block_size of crypter */ - if (concatenated.len < iv.len || concatenated.len % iv.len) + if (iv.len + icv.len > this->encrypted.len || + (crypt.len - icv.len) % bs) { - DBG1(DBG_ENC, "could not decrypt, invalid input"); + DBG1(DBG_ENC, "decrypting encryption payload failed, invalid length"); return FAILED; } - /* free previus data, if any */ - free(this->decrypted.ptr); - - DBG3(DBG_ENC, "data before decryption %B", &concatenated); - - this->crypter->decrypt(this->crypter, concatenated, iv, &this->decrypted); + assoc = append_header(this, assoc); - DBG3(DBG_ENC, "data after decryption with padding %B", &this->decrypted); + DBG3(DBG_ENC, "encryption payload decryption:"); + DBG3(DBG_ENC, "IV %B", &iv); + DBG3(DBG_ENC, "encrypted %B", &crypt); + DBG3(DBG_ENC, "ICV %B", &icv); + DBG3(DBG_ENC, "assoc %B", &assoc); - /* get padding length, sits just bevore signature */ - padding_length = *(this->decrypted.ptr + this->decrypted.len - 1); - /* add one byte to the padding length, since the padding_length field is - * not included */ - padding_length++; - - /* check size again */ - if (padding_length > concatenated.len || padding_length > this->decrypted.len) + if (!this->aead->decrypt(this->aead, crypt, assoc, iv, NULL)) { - DBG1(DBG_ENC, "decryption failed, invalid padding length found. Invalid key?"); - /* decryption failed :-/ */ + DBG1(DBG_ENC, "verifying encryption payload integrity failed"); + free(assoc.ptr); return FAILED; } - this->decrypted.len -= padding_length; - - /* free padding */ - this->decrypted.ptr = realloc(this->decrypted.ptr, this->decrypted.len); - DBG3(DBG_ENC, "data after decryption without padding %B", &this->decrypted); - DBG2(DBG_ENC, "decryption successful, trying to parse content"); - return parse(this); -} + free(assoc.ptr); -/** - * Implementation of encryption_payload_t.set_transforms. - */ -static void set_transforms(private_encryption_payload_t *this, crypter_t* crypter, signer_t* signer) -{ - this->signer = signer; - this->crypter = crypter; -} - -/** - * Implementation of encryption_payload_t.build_signature. - */ -static status_t build_signature(private_encryption_payload_t *this, chunk_t data) -{ - chunk_t data_without_sig = data; - chunk_t sig; - - if (this->signer == NULL) + plain = chunk_create(crypt.ptr, crypt.len - icv.len); + padding.len = plain.ptr[plain.len - 1] + 1; + if (padding.len > plain.len) { - DBG1(DBG_ENC, "unable to build signature, no signer set"); - return INVALID_STATE; + DBG1(DBG_ENC, "decrypting encryption payload failed, " + "padding invalid %B", &crypt); + return PARSE_ERROR; } + plain.len -= padding.len; + padding.ptr = plain.ptr + plain.len; - sig.len = this->signer->get_block_size(this->signer); - data_without_sig.len -= sig.len; - sig.ptr = data.ptr + data_without_sig.len; - DBG2(DBG_ENC, "building signature"); - this->signer->get_signature(this->signer, data_without_sig, sig.ptr); - return SUCCESS; + DBG3(DBG_ENC, "plain %B", &plain); + DBG3(DBG_ENC, "padding %B", &padding); + + return parse(this, plain); } -/** - * Implementation of encryption_payload_t.verify_signature. - */ -static status_t verify_signature(private_encryption_payload_t *this, chunk_t data) +METHOD(encryption_payload_t, set_transform, void, + private_encryption_payload_t *this, aead_t* aead) { - chunk_t sig, data_without_sig; - bool valid; - - if (this->signer == NULL) - { - DBG1(DBG_ENC, "unable to verify signature, no signer set"); - return INVALID_STATE; - } - /* find signature in data chunk */ - sig.len = this->signer->get_block_size(this->signer); - if (data.len <= sig.len) - { - DBG1(DBG_ENC, "unable to verify signature, invalid input"); - return FAILED; - } - sig.ptr = data.ptr + data.len - sig.len; - - /* verify it */ - data_without_sig.len = data.len - sig.len; - data_without_sig.ptr = data.ptr; - valid = this->signer->verify_signature(this->signer, data_without_sig, sig); - - if (!valid) - { - DBG1(DBG_ENC, "signature verification failed"); - return FAILED; - } - - DBG2(DBG_ENC, "signature verification successful"); - return SUCCESS; + this->aead = aead; } -/** - * Implementation of payload_t.destroy. - */ -static void destroy(private_encryption_payload_t *this) +METHOD2(payload_t, encryption_payload_t, destroy, void, + private_encryption_payload_t *this) { this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy)); free(this->encrypted.ptr); - free(this->decrypted.ptr); free(this); } @@ -581,39 +457,31 @@ static void destroy(private_encryption_payload_t *this) */ encryption_payload_t *encryption_payload_create() { - private_encryption_payload_t *this = malloc_thing(private_encryption_payload_t); - - /* payload_t interface functions */ - this->public.payload_interface.verify = (status_t (*) (payload_t *))verify; - this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules; - this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length; - this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type; - this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type; - this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type; - this->public.payload_interface.destroy = (void (*) (payload_t *))destroy; - - /* public functions */ - this->public.create_payload_iterator = (iterator_t * (*) (encryption_payload_t *,bool)) create_payload_iterator; - this->public.add_payload = (void (*) (encryption_payload_t *,payload_t *)) add_payload; - this->public.remove_first_payload = (status_t (*)(encryption_payload_t*, payload_t **)) remove_first_payload; - this->public.get_payload_count = (size_t (*)(encryption_payload_t*)) get_payload_count; - - this->public.encrypt = (status_t (*) (encryption_payload_t *)) encrypt; - this->public.decrypt = (status_t (*) (encryption_payload_t *)) decrypt; - this->public.set_transforms = (void (*) (encryption_payload_t*,crypter_t*,signer_t*)) set_transforms; - this->public.build_signature = (status_t (*) (encryption_payload_t*, chunk_t)) build_signature; - this->public.verify_signature = (status_t (*) (encryption_payload_t*, chunk_t)) verify_signature; - this->public.destroy = (void (*) (encryption_payload_t *)) destroy; - - /* set default values of the fields */ - this->critical = FALSE; - this->next_payload = NO_PAYLOAD; - this->payload_length = ENCRYPTION_PAYLOAD_HEADER_LENGTH; - this->encrypted = chunk_empty; - this->decrypted = chunk_empty; - this->signer = NULL; - this->crypter = NULL; - this->payloads = linked_list_create(); - - return (&(this->public)); + private_encryption_payload_t *this; + + INIT(this, + .public = { + .payload_interface = { + .verify = _verify, + .get_encoding_rules = _get_encoding_rules, + .get_length = _get_length, + .get_next_type = _get_next_type, + .set_next_type = _set_next_type, + .get_type = _get_type, + .destroy = _destroy, + }, + .get_length = _get_length, + .add_payload = _add_payload, + .remove_payload = _remove_payload, + .set_transform = _set_transform, + .encrypt = _encrypt, + .decrypt = _decrypt, + .destroy = _destroy, + }, + .next_payload = NO_PAYLOAD, + .payload_length = ENCRYPTION_PAYLOAD_HEADER_LENGTH, + .payloads = linked_list_create(), + ); + + return &this->public; } diff --git a/src/libcharon/encoding/payloads/encryption_payload.h b/src/libcharon/encoding/payloads/encryption_payload.h index ac5326b87..e99c42fb7 100644 --- a/src/libcharon/encoding/payloads/encryption_payload.h +++ b/src/libcharon/encoding/payloads/encryption_payload.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2010 Martin Willi + * Copyright (C) 2010 revosec AG * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -25,45 +26,30 @@ typedef struct encryption_payload_t encryption_payload_t; #include <library.h> -#include <crypto/crypters/crypter.h> -#include <crypto/signers/signer.h> +#include <crypto/aead.h> #include <encoding/payloads/payload.h> -#include <utils/linked_list.h> /** * Encrpytion payload length in bytes without IV and following data. */ #define ENCRYPTION_PAYLOAD_HEADER_LENGTH 4 - /** * The encryption payload as described in RFC section 3.14. - * - * Before any crypt/decrypt/sign/verify operation can occur, - * the transforms must be set. After that, a parsed encryption payload - * can be decrypted, which also will parse the contained payloads. - * Encryption is done the same way, added payloads will get generated - * and then encrypted. - * For signature building, there is the FULL packet needed. Meaning it - * must be builded after generation of all payloads and the encryption - * of the encryption payload. - * Signature verificatin is done before decryption. */ struct encryption_payload_t { + /** * Implements payload_t interface. */ payload_t payload_interface; /** - * Creates an iterator for all contained payloads. + * Get the payload length. * - * iterator_t object has to get destroyed by the caller. - * - * @param forward iterator direction (TRUE: front to end) - * return created iterator_t object + * @return (expected) payload length */ - iterator_t *(*create_payload_iterator) (encryption_payload_t *this, bool forward); + size_t (*get_length)(encryption_payload_t *this); /** * Adds a payload to this encryption payload. @@ -73,89 +59,39 @@ struct encryption_payload_t { void (*add_payload) (encryption_payload_t *this, payload_t *payload); /** - * Reove the last payload in the contained payload list. + * Remove the first payload in the list * * @param payload removed payload - * @return - * - SUCCESS, or - * - NOT_FOUND if list empty - */ - status_t (*remove_first_payload) (encryption_payload_t *this, payload_t **payload); - - /** - * Get the number of payloads. - * - * @return number of contained payloads + * @return payload, NULL if none left */ - size_t (*get_payload_count) (encryption_payload_t *this); + payload_t* (*remove_payload)(encryption_payload_t *this); /** - * Set transforms to use. - * - * To decryption, encryption, signature building and verifying, - * the payload needs a crypter and a signer object. + * Set the AEAD transform to use. * - * @warning Do NOT call this function again after encryption, since - * the signer must be the same while encrypting and signature building! - * - * @param crypter crypter_t to use for data de-/encryption - * @param signer signer_t to use for data signing/verifying + * @param aead aead transform to use */ - void (*set_transforms) (encryption_payload_t *this, crypter_t *crypter, signer_t *signer); + void (*set_transform) (encryption_payload_t *this, aead_t *aead); /** - * Generate and encrypt contained payloads. - * - * This function generates the content for added payloads - * and encrypts them. Signature is not built, since we need - * additional data (the full message). + * Generate, encrypt and sign contained payloads. * - * @return SUCCESS, or INVALID_STATE if transforms not set + * @param assoc associated data + * @return TRUE if encrypted */ - status_t (*encrypt) (encryption_payload_t *this); + bool (*encrypt) (encryption_payload_t *this, chunk_t assoc); /** - * Decrypt and parse contained payloads. - * - * This function decrypts the contained data. After, - * the payloads are parsed internally and are accessible - * via the iterator. - * - * @return - * - SUCCESS, or - * - INVALID_STATE if transforms not set, or - * - FAILED if data is invalid - */ - status_t (*decrypt) (encryption_payload_t *this); - - /** - * Build the signature. - * - * The signature is built over the FULL message, so the header - * and every payload (inclusive this one) must already be generated. - * The generated message is supplied via the data paramater. - * - * @param data chunk contains the already generated message - * @return - * - SUCCESS, or - * - INVALID_STATE if transforms not set - */ - status_t (*build_signature) (encryption_payload_t *this, chunk_t data); - - /** - * Verify the signature. - * - * Since the signature is built over the full message, we need - * this data to do the verification. The message data - * is supplied via the data argument. - * - * @param data chunk contains the message - * @return - * - SUCCESS, or - * - FAILED if signature invalid, or - * - INVALID_STATE if transforms not set + * Decrypt, verify and parse contained payloads. + * + * @param assoc associated data + * - SUCCESS if parsing successful + * - PARSE_ERROR if sub-payload parsing failed + * - VERIFY_ERROR if sub-payload verification failed + * - FAILED if integrity check failed + * - INVALID_STATE if aead not supplied, but needed */ - status_t (*verify_signature) (encryption_payload_t *this, chunk_t data); + status_t (*decrypt) (encryption_payload_t *this, chunk_t assoc); /** * Destroys an encryption_payload_t object. @@ -166,7 +102,7 @@ struct encryption_payload_t { /** * Creates an empty encryption_payload_t object. * - * @return encryption_payload_t object + * @return encryption_payload_t object */ encryption_payload_t *encryption_payload_create(void); diff --git a/src/libcharon/encoding/payloads/notify_payload.c b/src/libcharon/encoding/payloads/notify_payload.c index 469698ef5..a56fd1869 100644 --- a/src/libcharon/encoding/payloads/notify_payload.c +++ b/src/libcharon/encoding/payloads/notify_payload.c @@ -41,7 +41,7 @@ ENUM_NEXT(notify_type_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PROPOSAL "INVALID_KE_PAYLOAD"); ENUM_NEXT(notify_type_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD, "AUTHENTICATION_FAILED"); -ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, USE_ASSIGNED_HoA, AUTHENTICATION_FAILED, +ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED, "SINGLE_PAIR_REQUIRED", "NO_ADDITIONAL_SAS", "INTERNAL_ADDRESS_FAILURE", @@ -50,10 +50,12 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, USE_ASSIGNED_HoA, AUTHENTICAT "INVALID_SELECTORS", "UNACCEPTABLE_ADDRESSES", "UNEXPECTED_NAT_DETECTED", - "USE_ASSIGNED_HoA"); -ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, USE_ASSIGNED_HoA, + "USE_ASSIGNED_HoA", + "TEMPORARY_FAILURE", + "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, LINK_ID, ME_CONNECT_FAILED, +ENUM_NEXT(notify_type_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_CONNECT_FAILED, "INITIAL_CONTACT", "SET_WINDOW_SIZE", "ADDITIONAL_TS_POSSIBLE", @@ -84,8 +86,9 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, LINK_ID, ME_CONNECT_FAILED, "TICKET_ACK", "TICKET_NACK", "TICKET_OPAQUE", - "LINK_ID"); -ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, LINK_ID, + "LINK_ID", + "USE_WESP_MODE", + "ROHC_SUPPORTED", "EAP_ONLY_AUTHENTICATION"); ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION, "USE_BEET_MODE"); @@ -117,7 +120,7 @@ ENUM_NEXT(notify_type_short_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PR "INVAL_KE"); ENUM_NEXT(notify_type_short_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD, "AUTH_FAILED"); -ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, USE_ASSIGNED_HoA, AUTHENTICATION_FAILED, +ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED, "SINGLE_PAIR", "NO_ADD_SAS", "INT_ADDR_FAIL", @@ -126,10 +129,12 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, USE_ASSIGNED_HoA, AUTHE "INVAL_SEL", "UNACCEPT_ADDR", "UNEXPECT_NAT", - "ASSIGNED_HoA"); -ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, USE_ASSIGNED_HoA, + "ASSIGNED_HoA", + "TEMP_FAIL", + "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, LINK_ID, ME_CONNECT_FAILED, +ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_CONNECT_FAILED, "INIT_CONTACT", "SET_WINSIZE", "ADD_TS_POSS", @@ -160,8 +165,9 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, LINK_ID, ME_CONNECT_FAILED, "TKT_ACK", "TKT_NACK", "TKT_OPAK", - "LINK_ID"); -ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, LINK_ID, + "LINK_ID", + "WESP_MODE", + "ROHC_SUP", "EAP_ONLY"); ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION, "BEET_MODE"); @@ -238,29 +244,29 @@ struct private_notify_payload_t { */ encoding_rule_t notify_payload_encodings[] = { /* 1 Byte next payload type, stored in the field next_payload */ - { U_INT_8, offsetof(private_notify_payload_t, next_payload) }, + { U_INT_8, offsetof(private_notify_payload_t, next_payload) }, /* the critical bit */ - { FLAG, offsetof(private_notify_payload_t, critical) }, + { FLAG, offsetof(private_notify_payload_t, critical) }, /* 7 Bit reserved bits, nowhere stored */ - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, /* Length of the whole payload*/ - { PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) }, + { PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) }, /* Protocol ID as 8 bit field*/ - { U_INT_8, offsetof(private_notify_payload_t, protocol_id) }, + { U_INT_8, offsetof(private_notify_payload_t, protocol_id) }, /* SPI Size as 8 bit field*/ - { SPI_SIZE, offsetof(private_notify_payload_t, spi_size) }, + { SPI_SIZE, offsetof(private_notify_payload_t, spi_size) }, /* Notify message type as 16 bit field*/ { U_INT_16, offsetof(private_notify_payload_t, notify_type) }, /* SPI as variable length field*/ { SPI, offsetof(private_notify_payload_t, spi) }, /* Key Exchange Data is from variable size */ - { NOTIFICATION_DATA, offsetof(private_notify_payload_t, notification_data) } + { NOTIFICATION_DATA, offsetof(private_notify_payload_t, notification_data) } }; /* diff --git a/src/libcharon/encoding/payloads/notify_payload.h b/src/libcharon/encoding/payloads/notify_payload.h index 0e1bc23b8..8abc236e1 100644 --- a/src/libcharon/encoding/payloads/notify_payload.h +++ b/src/libcharon/encoding/payloads/notify_payload.h @@ -64,6 +64,9 @@ enum notify_type_t { UNEXPECTED_NAT_DETECTED = 41, /* mobile IPv6 bootstrapping, RFC 5026 */ USE_ASSIGNED_HoA = 42, + /* IKEv2 RFC 5996 */ + TEMPORARY_FAILURE = 43, + CHILD_SA_NOT_FOUND = 44, /* IKE-ME, private use */ ME_CONNECT_FAILED = 8192, @@ -98,16 +101,21 @@ enum notify_type_t { REDIRECT_SUPPORTED = 16406, REDIRECT = 16407, REDIRECTED_FROM = 16408, - /* draft-ietf-ipsecme-ikev2-resumption, assigned by IANA */ + /* session resumption, RFC 5723 */ TICKET_LT_OPAQUE = 16409, TICKET_REQUEST = 16410, TICKET_ACK = 16411, TICKET_NACK = 16412, TICKET_OPAQUE = 16413, + /* IPv6 configuration, RFC 5739 */ LINK_ID = 16414, + /* wrapped esp, RFC 5840 */ + USE_WESP_MODE = 16415, + /* robust header compression, RFC 5857 */ + ROHC_SUPPORTED = 16416, + /* EAP-only authentication, RFC 5998 */ + EAP_ONLY_AUTHENTICATION = 16417, - /* draft-eronen-ipsec-ikev2-eap-auth, not assigned by IANA yet */ - EAP_ONLY_AUTHENTICATION = 40960, /* BEET mode, not even a draft yet. private use */ USE_BEET_MODE = 40961, /* IKE-ME, private use */ @@ -144,7 +152,7 @@ struct notify_payload_t { /** * Gets the protocol id of this payload. * - * @return protocol id of this payload + * @return protocol id of this payload */ u_int8_t (*get_protocol_id) (notify_payload_t *this); @@ -158,7 +166,7 @@ struct notify_payload_t { /** * Gets the notify message type of this payload. * - * @return notify message type of this payload + * @return notify message type of this payload */ notify_type_t (*get_notify_type) (notify_payload_t *this); @@ -174,7 +182,7 @@ struct notify_payload_t { * * This is only valid for notifys with protocol AH|ESP * - * @return SPI value + * @return SPI value */ u_int32_t (*get_spi) (notify_payload_t *this); @@ -192,7 +200,7 @@ struct notify_payload_t { * * Returned data are not copied. * - * @return chunk_t pointing to the value + * @return chunk_t pointing to the value */ chunk_t (*get_notification_data) (notify_payload_t *this); @@ -201,7 +209,7 @@ struct notify_payload_t { * * @warning Value is getting copied. * - * @param notification_data chunk_t pointing to the value to set + * @param notification_data chunk_t pointing to the value to set */ void (*set_notification_data) (notify_payload_t *this, chunk_t notification_data); diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c index c93f73a68..985b03255 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.c +++ b/src/libcharon/encoding/payloads/proposal_substructure.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -24,20 +24,18 @@ #include <utils/linked_list.h> #include <daemon.h> - /** * IKEv1 Value for a proposal payload. */ #define PROPOSAL_TYPE_VALUE 2 - typedef struct private_proposal_substructure_t private_proposal_substructure_t; /** * Private data of an proposal_substructure_t object. - * */ struct private_proposal_substructure_t { + /** * Public proposal_substructure_t interface. */ @@ -92,24 +90,24 @@ struct private_proposal_substructure_t { */ encoding_rule_t proposal_substructure_encodings[] = { /* 1 Byte next payload type, stored in the field next_payload */ - { U_INT_8, offsetof(private_proposal_substructure_t, next_payload) }, + { U_INT_8, offsetof(private_proposal_substructure_t, next_payload) }, /* Reserved Byte is skipped */ - { RESERVED_BYTE, 0 }, + { RESERVED_BYTE, 0 }, /* Length of the whole proposal substructure payload*/ - { PAYLOAD_LENGTH, offsetof(private_proposal_substructure_t, proposal_length) }, + { PAYLOAD_LENGTH, offsetof(private_proposal_substructure_t, proposal_length) }, /* proposal number is a number of 8 bit */ - { U_INT_8, offsetof(private_proposal_substructure_t, proposal_number) }, + { U_INT_8, offsetof(private_proposal_substructure_t, proposal_number) }, /* protocol ID is a number of 8 bit */ - { U_INT_8, offsetof(private_proposal_substructure_t, protocol_id) }, + { U_INT_8, offsetof(private_proposal_substructure_t, protocol_id) }, /* SPI Size has its own type */ - { SPI_SIZE, offsetof(private_proposal_substructure_t, spi_size) }, + { SPI_SIZE, offsetof(private_proposal_substructure_t, spi_size) }, /* Number of transforms is a number of 8 bit */ - { U_INT_8, offsetof(private_proposal_substructure_t, transforms_count) }, + { U_INT_8, offsetof(private_proposal_substructure_t, transforms_count) }, /* SPI is a chunk of variable size*/ - { SPI, offsetof(private_proposal_substructure_t, spi) }, + { SPI, offsetof(private_proposal_substructure_t, spi) }, /* Transforms are stored in a transform substructure, offset points to a linked_list_t pointer */ - { TRANSFORMS, offsetof(private_proposal_substructure_t, transforms) } + { TRANSFORMS, offsetof(private_proposal_substructure_t, transforms) } }; /* @@ -128,16 +126,14 @@ encoding_rule_t proposal_substructure_encodings[] = { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -/** - * Implementation of payload_t.verify. - */ -static status_t verify(private_proposal_substructure_t *this) +METHOD(payload_t, verify, status_t, + private_proposal_substructure_t *this) { status_t status = SUCCESS; - iterator_t *iterator; - payload_t *current_transform; + enumerator_t *enumerator; + payload_t *current; - if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 2)) + if (this->next_payload != NO_PAYLOAD && this->next_payload != 2) { /* must be 0 or 2 */ DBG1(DBG_ENC, "inconsistent next payload"); @@ -169,61 +165,46 @@ static status_t verify(private_proposal_substructure_t *this) } break; default: - DBG1(DBG_ENC, "invalid proposal protocol (%d)", this->protocol_id); - return FAILED; - } - if ((this->protocol_id == 0) || (this->protocol_id >= 4)) - { - /* reserved are not supported */ - DBG1(DBG_ENC, "invalid protocol"); - return FAILED; + break; } - - iterator = this->transforms->create_iterator(this->transforms,TRUE); - while(iterator->iterate(iterator, (void**)¤t_transform)) + enumerator = this->transforms->create_enumerator(this->transforms); + while (enumerator->enumerate(enumerator, ¤t)) { - status = current_transform->verify(current_transform); + status = current->verify(current); if (status != SUCCESS) { DBG1(DBG_ENC, "TRANSFORM_SUBSTRUCTURE verification failed"); break; } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); /* proposal number is checked in SA payload */ return status; } -/** - * Implementation of payload_t.get_encoding_rules. - */ -static void get_encoding_rules(private_proposal_substructure_t *this, encoding_rule_t **rules, size_t *rule_count) +METHOD(payload_t, get_encoding_rules, void, + private_proposal_substructure_t *this, encoding_rule_t **rules, + size_t *rule_count) { *rules = proposal_substructure_encodings; - *rule_count = sizeof(proposal_substructure_encodings) / sizeof(encoding_rule_t); + *rule_count = countof(proposal_substructure_encodings); } -/** - * Implementation of payload_t.get_type. - */ -static payload_type_t get_type(private_proposal_substructure_t *this) +METHOD(payload_t, get_type, payload_type_t, + private_proposal_substructure_t *this) { return PROPOSAL_SUBSTRUCTURE; } -/** - * Implementation of payload_t.get_next_type. - */ -static payload_type_t get_next_type(private_proposal_substructure_t *this) +METHOD(payload_t, get_next_type, payload_type_t, + private_proposal_substructure_t *this) { - return (this->next_payload); + return this->next_payload; } -/** - * Implementation of payload_t.set_next_type. - */ -static void set_next_type(private_proposal_substructure_t *this,payload_type_t type) +METHOD(payload_t, set_next_type, void, + private_proposal_substructure_t *this, payload_type_t type) { } @@ -250,145 +231,88 @@ static void compute_length(private_proposal_substructure_t *this) this->proposal_length = length; } -/** - * Implementation of payload_t.get_length. - */ -static size_t get_length(private_proposal_substructure_t *this) +METHOD(payload_t, get_length, size_t, + private_proposal_substructure_t *this) { compute_length(this); return this->proposal_length; } /** - * Implementation of proposal_substructure_t.create_transform_substructure_iterator. - */ -static iterator_t *create_transform_substructure_iterator (private_proposal_substructure_t *this,bool forward) -{ - return (this->transforms->create_iterator(this->transforms,forward)); -} - -/** - * Implementation of proposal_substructure_t.add_transform_substructure. + * Add a transform substructure to the proposal */ -static void add_transform_substructure (private_proposal_substructure_t *this,transform_substructure_t *transform) +static void add_transform_substructure(private_proposal_substructure_t *this, + transform_substructure_t *transform) { - status_t status; if (this->transforms->get_count(this->transforms) > 0) { - transform_substructure_t *last_transform; - status = this->transforms->get_last(this->transforms,(void **) &last_transform); - /* last transform is now not anymore last one */ - last_transform->set_is_last_transform(last_transform,FALSE); + transform_substructure_t *last; + this->transforms->get_last(this->transforms, (void **)&last); + last->set_is_last_transform(last, FALSE); } transform->set_is_last_transform(transform,TRUE); - - this->transforms->insert_last(this->transforms,(void *) transform); + this->transforms->insert_last(this->transforms, transform); compute_length(this); } -/** - * Implementation of proposal_substructure_t.proposal_substructure_t. - */ -static void set_is_last_proposal (private_proposal_substructure_t *this, bool is_last) +METHOD(proposal_substructure_t, set_is_last_proposal, void, + private_proposal_substructure_t *this, bool is_last) { - this->next_payload = (is_last) ? 0: PROPOSAL_TYPE_VALUE; + this->next_payload = is_last ? 0 : PROPOSAL_TYPE_VALUE; } -/** - * Implementation of proposal_substructure_t.set_proposal_number. - */ -static void set_proposal_number(private_proposal_substructure_t *this,u_int8_t proposal_number) +METHOD(proposal_substructure_t, set_proposal_number, void, + private_proposal_substructure_t *this,u_int8_t proposal_number) { this->proposal_number = proposal_number; } -/** - * Implementation of proposal_substructure_t.get_proposal_number. - */ -static u_int8_t get_proposal_number (private_proposal_substructure_t *this) +METHOD(proposal_substructure_t, get_proposal_number, u_int8_t, + private_proposal_substructure_t *this) { - return (this->proposal_number); + return this->proposal_number; } -/** - * Implementation of proposal_substructure_t.set_protocol_id. - */ -static void set_protocol_id(private_proposal_substructure_t *this,u_int8_t protocol_id) +METHOD(proposal_substructure_t, set_protocol_id, void, + private_proposal_substructure_t *this,u_int8_t protocol_id) { this->protocol_id = protocol_id; } -/** - * Implementation of proposal_substructure_t.get_protocol_id. - */ -static u_int8_t get_protocol_id(private_proposal_substructure_t *this) +METHOD(proposal_substructure_t, get_protocol_id, u_int8_t, + private_proposal_substructure_t *this) { - return (this->protocol_id); + return this->protocol_id; } -/** - * Implementation of proposal_substructure_t.set_spi. - */ -static void set_spi(private_proposal_substructure_t *this, chunk_t spi) +METHOD(proposal_substructure_t, set_spi, void, + private_proposal_substructure_t *this, chunk_t spi) { - /* first delete already set spi value */ - if (this->spi.ptr != NULL) - { - free(this->spi.ptr); - this->spi.ptr = NULL; - this->spi.len = 0; - compute_length(this); - } - - this->spi.ptr = clalloc(spi.ptr,spi.len); - this->spi.len = spi.len; + free(this->spi.ptr); + this->spi = chunk_clone(spi); this->spi_size = spi.len; compute_length(this); } -/** - * Implementation of proposal_substructure_t.get_spi. - */ -static chunk_t get_spi(private_proposal_substructure_t *this) -{ - chunk_t spi; - spi.ptr = this->spi.ptr; - spi.len = this->spi.len; - - return spi; -} - -/** - * Implementation of proposal_substructure_t.get_transform_count. - */ -static size_t get_transform_count (private_proposal_substructure_t *this) -{ - return this->transforms->get_count(this->transforms); -} - -/** - * Implementation of proposal_substructure_t.get_spi_size. - */ -static size_t get_spi_size (private_proposal_substructure_t *this) +METHOD(proposal_substructure_t, get_spi, chunk_t, + private_proposal_substructure_t *this) { - return this->spi.len; + return this->spi; } -/** - * Implementation of proposal_substructure_t.get_proposal. - */ -proposal_t* get_proposal(private_proposal_substructure_t *this) +METHOD(proposal_substructure_t, get_proposal, proposal_t*, + private_proposal_substructure_t *this) { - iterator_t *iterator; + enumerator_t *enumerator; transform_substructure_t *transform; proposal_t *proposal; u_int64_t spi; - proposal = proposal_create(this->protocol_id); + proposal = proposal_create(this->protocol_id, this->proposal_number); - iterator = this->transforms->create_iterator(this->transforms, TRUE); - while (iterator->iterate(iterator, (void**)&transform)) + enumerator = this->transforms->create_enumerator(this->transforms); + while (enumerator->enumerate(enumerator, &transform)) { transform_type_t transform_type; u_int16_t transform_id; @@ -400,7 +324,7 @@ proposal_t* get_proposal(private_proposal_substructure_t *this) proposal->add_algorithm(proposal, transform_type, transform_id, key_length); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); switch (this->spi.len) { @@ -418,42 +342,36 @@ proposal_t* get_proposal(private_proposal_substructure_t *this) return proposal; } -/** - * Implementation of proposal_substructure_t.clone. - */ -static private_proposal_substructure_t* clone_(private_proposal_substructure_t *this) +METHOD(proposal_substructure_t, clone_, proposal_substructure_t*, + private_proposal_substructure_t *this) { private_proposal_substructure_t *clone; - iterator_t *transforms; - transform_substructure_t *current_transform; + enumerator_t *enumerator; + transform_substructure_t *current; - clone = (private_proposal_substructure_t *) proposal_substructure_create(); + clone = (private_proposal_substructure_t*)proposal_substructure_create(); clone->next_payload = this->next_payload; clone->proposal_number = this->proposal_number; clone->protocol_id = this->protocol_id; clone->spi_size = this->spi_size; if (this->spi.ptr != NULL) { - clone->spi.ptr = clalloc(this->spi.ptr,this->spi.len); + clone->spi.ptr = clalloc(this->spi.ptr, this->spi.len); clone->spi.len = this->spi.len; } - - transforms = this->transforms->create_iterator(this->transforms,FALSE); - while (transforms->iterate(transforms, (void**)¤t_transform)) + enumerator = this->transforms->create_enumerator(this->transforms); + while (enumerator->enumerate(enumerator, ¤t)) { - current_transform = current_transform->clone(current_transform); - clone->public.add_transform_substructure(&clone->public, current_transform); + current = current->clone(current); + add_transform_substructure(clone, current); } - transforms->destroy(transforms); + enumerator->destroy(enumerator); - return clone; + return &clone->public; } -/** - * Implements payload_t's and proposal_substructure_t's destroy function. - * See #payload_s.destroy or proposal_substructure_s.destroy for description. - */ -static void destroy(private_proposal_substructure_t *this) +METHOD2(payload_t, proposal_substructure_t, destroy, void, + private_proposal_substructure_t *this) { this->transforms->destroy_offset(this->transforms, offsetof(transform_substructure_t, destroy)); @@ -466,53 +384,42 @@ static void destroy(private_proposal_substructure_t *this) */ proposal_substructure_t *proposal_substructure_create() { - private_proposal_substructure_t *this = malloc_thing(private_proposal_substructure_t); - - /* interface functions */ - this->public.payload_interface.verify = (status_t (*) (payload_t *))verify; - this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules; - this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length; - this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type; - this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type; - this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type; - this->public.payload_interface.destroy = (void (*) (payload_t *))destroy; - - - /* public functions */ - this->public.create_transform_substructure_iterator = (iterator_t* (*) (proposal_substructure_t *,bool)) create_transform_substructure_iterator; - this->public.add_transform_substructure = (void (*) (proposal_substructure_t *,transform_substructure_t *)) add_transform_substructure; - this->public.set_proposal_number = (void (*) (proposal_substructure_t *,u_int8_t))set_proposal_number; - this->public.get_proposal_number = (u_int8_t (*) (proposal_substructure_t *)) get_proposal_number; - this->public.set_protocol_id = (void (*) (proposal_substructure_t *,u_int8_t))set_protocol_id; - this->public.get_protocol_id = (u_int8_t (*) (proposal_substructure_t *)) get_protocol_id; - this->public.set_is_last_proposal = (void (*) (proposal_substructure_t *,bool)) set_is_last_proposal; - this->public.get_proposal = (proposal_t* (*) (proposal_substructure_t*))get_proposal; - this->public.set_spi = (void (*) (proposal_substructure_t *,chunk_t))set_spi; - this->public.get_spi = (chunk_t (*) (proposal_substructure_t *)) get_spi; - this->public.get_transform_count = (size_t (*) (proposal_substructure_t *)) get_transform_count; - this->public.get_spi_size = (size_t (*) (proposal_substructure_t *)) get_spi_size; - this->public.clone = (proposal_substructure_t * (*) (proposal_substructure_t *)) clone_; - this->public.destroy = (void (*) (proposal_substructure_t *)) destroy; - - /* set default values of the fields */ - this->next_payload = NO_PAYLOAD; - this->proposal_length = 0; - this->proposal_number = 0; - this->protocol_id = 0; - this->transforms_count = 0; - this->spi_size = 0; - this->spi.ptr = NULL; - this->spi.len = 0; - - this->transforms = linked_list_create(); - - return (&(this->public)); + private_proposal_substructure_t *this; + + INIT(this, + .public = { + .payload_interface = { + .verify = _verify, + .get_encoding_rules = _get_encoding_rules, + .get_length = _get_length, + .get_next_type = _get_next_type, + .set_next_type = _set_next_type, + .get_type = _get_type, + .destroy = _destroy, + }, + .set_proposal_number = _set_proposal_number, + .get_proposal_number = _get_proposal_number, + .set_protocol_id = _set_protocol_id, + .get_protocol_id = _get_protocol_id, + .set_is_last_proposal = _set_is_last_proposal, + .get_proposal = _get_proposal, + .set_spi = _set_spi, + .get_spi = _get_spi, + .clone = _clone_, + .destroy = _destroy, + }, + .next_payload = NO_PAYLOAD, + .transforms = linked_list_create(), + ); + + return &this->public; } /* * Described in header. */ -proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal) +proposal_substructure_t *proposal_substructure_create_from_proposal( + proposal_t *proposal) { transform_substructure_t *transform; private_proposal_substructure_t *this; @@ -591,7 +498,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t * default: break; } - this->proposal_number = 0; + this->proposal_number = proposal->get_number(proposal); this->protocol_id = proposal->get_protocol(proposal); return &this->public; diff --git a/src/libcharon/encoding/payloads/proposal_substructure.h b/src/libcharon/encoding/payloads/proposal_substructure.h index 4934802af..56e7184b6 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.h +++ b/src/libcharon/encoding/payloads/proposal_substructure.h @@ -42,36 +42,19 @@ typedef struct proposal_substructure_t proposal_substructure_t; * The PROPOSAL SUBSTRUCTURE format is described in RFC section 3.3.1. */ struct proposal_substructure_t { + /** * The payload_t interface. */ payload_t payload_interface; /** - * Creates an iterator of stored transform_substructure_t objects. - * - * @param forward iterator direction (TRUE: front to end) - * @return created iterator_t object - */ - iterator_t *(*create_transform_substructure_iterator) ( - proposal_substructure_t *this, bool forward); - - /** - * Adds a transform_substructure_t object to this object. - * - * @param transform transform_substructure_t object to add - */ - void (*add_transform_substructure) (proposal_substructure_t *this, - transform_substructure_t *transform); - - /** * Sets the proposal number of current proposal. * * @param id proposal number to set */ void (*set_proposal_number) (proposal_substructure_t *this, u_int8_t proposal_number); - /** * get proposal number of current proposal. * @@ -80,20 +63,6 @@ struct proposal_substructure_t { u_int8_t (*get_proposal_number) (proposal_substructure_t *this); /** - * get the number of transforms in current proposal. - * - * @return transform count in current proposal - */ - size_t (*get_transform_count) (proposal_substructure_t *this); - - /** - * get size of the set spi in bytes. - * - * @return size of the spi in bytes - */ - size_t (*get_spi_size) (proposal_substructure_t *this); - - /** * Sets the protocol id of current proposal. * * @param id protocol id to set diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c index 187a8fee0..4fbd4cac0 100644 --- a/src/libcharon/encoding/payloads/sa_payload.c +++ b/src/libcharon/encoding/payloads/sa_payload.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -27,9 +27,9 @@ typedef struct private_sa_payload_t private_sa_payload_t; /** * Private data of an sa_payload_t object. - * */ struct private_sa_payload_t { + /** * Public sa_payload_t interface. */ @@ -61,26 +61,25 @@ struct private_sa_payload_t { * * The defined offsets are the positions in a object of type * private_sa_payload_t. - * */ encoding_rule_t sa_payload_encodings[] = { /* 1 Byte next payload type, stored in the field next_payload */ - { U_INT_8, offsetof(private_sa_payload_t, next_payload) }, + { U_INT_8, offsetof(private_sa_payload_t, next_payload) }, /* the critical bit */ - { FLAG, offsetof(private_sa_payload_t, critical) }, + { FLAG, offsetof(private_sa_payload_t, critical) }, /* 7 Bit reserved bits, nowhere stored */ - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, - { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, + { RESERVED_BIT, 0 }, /* Length of the whole SA payload*/ - { PAYLOAD_LENGTH, offsetof(private_sa_payload_t, payload_length) }, + { PAYLOAD_LENGTH, offsetof(private_sa_payload_t, payload_length) }, /* Proposals are stored in a proposal substructure, offset points to a linked_list_t pointer */ - { PROPOSALS, offsetof(private_sa_payload_t, proposals) } + { PROPOSALS, offsetof(private_sa_payload_t, proposals) }, }; /* @@ -95,26 +94,23 @@ encoding_rule_t sa_payload_encodings[] = { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -/** - * Implementation of payload_t.verify. - */ -static status_t verify(private_sa_payload_t *this) +METHOD(payload_t, verify, status_t, + private_sa_payload_t *this) { int expected_number = 1, current_number; status_t status = SUCCESS; - iterator_t *iterator; - proposal_substructure_t *current_proposal; + enumerator_t *enumerator; + proposal_substructure_t *substruct; bool first = TRUE; /* check proposal numbering */ - iterator = this->proposals->create_iterator(this->proposals,TRUE); - - while(iterator->iterate(iterator, (void**)¤t_proposal)) + enumerator = this->proposals->create_enumerator(this->proposals); + while (enumerator->enumerate(enumerator, (void**)&substruct)) { - current_number = current_proposal->get_proposal_number(current_proposal); + current_number = substruct->get_proposal_number(substruct); if (current_number < expected_number) { - if (current_number != (expected_number + 1)) + if (current_number != expected_number + 1) { DBG1(DBG_ENC, "proposal number is %d, expected %d or %d", current_number, expected_number, expected_number + 1); @@ -124,13 +120,12 @@ static status_t verify(private_sa_payload_t *this) } else if (current_number < expected_number) { - /* must not be smaller then proceeding one */ - DBG1(DBG_ENC, "proposal number smaller than that of previous proposal"); + DBG1(DBG_ENC, "proposal number smaller than previous"); status = FAILED; break; } - status = current_proposal->payload_interface.verify(&(current_proposal->payload_interface)); + status = substruct->payload_interface.verify(&substruct->payload_interface); if (status != SUCCESS) { DBG1(DBG_ENC, "PROPOSAL_SUBSTRUCTURE verification failed"); @@ -139,52 +134,31 @@ static status_t verify(private_sa_payload_t *this) first = FALSE; expected_number = current_number; } - - iterator->destroy(iterator); + enumerator->destroy(enumerator); return status; } - -/** - * Implementation of payload_t.destroy and sa_payload_t.destroy. - */ -static status_t destroy(private_sa_payload_t *this) -{ - this->proposals->destroy_offset(this->proposals, - offsetof(proposal_substructure_t, destroy)); - free(this); - return SUCCESS; -} - -/** - * Implementation of payload_t.get_encoding_rules. - */ -static void get_encoding_rules(private_sa_payload_t *this, encoding_rule_t **rules, size_t *rule_count) +METHOD(payload_t, get_encoding_rules, void, + private_sa_payload_t *this, encoding_rule_t **rules, size_t *rule_count) { *rules = sa_payload_encodings; - *rule_count = sizeof(sa_payload_encodings) / sizeof(encoding_rule_t); + *rule_count = countof(sa_payload_encodings); } -/** - * Implementation of payload_t.get_type. - */ -static payload_type_t get_type(private_sa_payload_t *this) +METHOD(payload_t, get_type, payload_type_t, + private_sa_payload_t *this) { return SECURITY_ASSOCIATION; } -/** - * Implementation of payload_t.get_next_type. - */ -static payload_type_t get_next_type(private_sa_payload_t *this) +METHOD(payload_t, get_next_type, payload_type_t, + private_sa_payload_t *this) { - return (this->next_payload); + return this->next_payload; } -/** - * Implementation of payload_t.set_next_type. - */ -static void set_next_type(private_sa_payload_t *this,payload_type_t type) +METHOD(payload_t, set_next_type, void, + private_sa_payload_t *this,payload_type_t type) { this->next_payload = type; } @@ -192,116 +166,104 @@ static void set_next_type(private_sa_payload_t *this,payload_type_t type) /** * recompute length of the payload. */ -static void compute_length (private_sa_payload_t *this) +static void compute_length(private_sa_payload_t *this) { - iterator_t *iterator; - payload_t *current_proposal; + enumerator_t *enumerator; + payload_t *current; size_t length = SA_PAYLOAD_HEADER_LENGTH; - iterator = this->proposals->create_iterator(this->proposals,TRUE); - while (iterator->iterate(iterator, (void **)¤t_proposal)) + enumerator = this->proposals->create_enumerator(this->proposals); + while (enumerator->enumerate(enumerator, (void **)¤t)) { - length += current_proposal->get_length(current_proposal); + length += current->get_length(current); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); this->payload_length = length; } -/** - * Implementation of payload_t.get_length. - */ -static size_t get_length(private_sa_payload_t *this) +METHOD(payload_t, get_length, size_t, + private_sa_payload_t *this) { compute_length(this); return this->payload_length; } -/** - * Implementation of sa_payload_t.create_proposal_substructure_iterator. - */ -static iterator_t *create_proposal_substructure_iterator (private_sa_payload_t *this,bool forward) +METHOD(sa_payload_t, add_proposal, void, + private_sa_payload_t *this, proposal_t *proposal) { - return this->proposals->create_iterator(this->proposals,forward); -} + proposal_substructure_t *substruct, *last; + u_int count; -/** - * Implementation of sa_payload_t.add_proposal_substructure. - */ -static void add_proposal_substructure(private_sa_payload_t *this,proposal_substructure_t *proposal) -{ - status_t status; - u_int proposal_count = this->proposals->get_count(this->proposals); - - if (proposal_count > 0) + count = this->proposals->get_count(this->proposals); + substruct = proposal_substructure_create_from_proposal(proposal); + if (count > 0) { - proposal_substructure_t *last_proposal; - status = this->proposals->get_last(this->proposals,(void **) &last_proposal); + this->proposals->get_last(this->proposals, (void**)&last); /* last transform is now not anymore last one */ - last_proposal->set_is_last_proposal(last_proposal, FALSE); + last->set_is_last_proposal(last, FALSE); + } + substruct->set_is_last_proposal(substruct, TRUE); + if (proposal->get_number(proposal)) + { /* use the selected proposals number, if any */ + substruct->set_proposal_number(substruct, proposal->get_number(proposal)); + } + else + { + substruct->set_proposal_number(substruct, count + 1); } - proposal->set_is_last_proposal(proposal, TRUE); - proposal->set_proposal_number(proposal, proposal_count + 1); - this->proposals->insert_last(this->proposals,(void *) proposal); + this->proposals->insert_last(this->proposals, substruct); compute_length(this); } -/** - * Implementation of sa_payload_t.add_proposal. - */ -static void add_proposal(private_sa_payload_t *this, proposal_t *proposal) -{ - proposal_substructure_t *substructure; - - substructure = proposal_substructure_create_from_proposal(proposal); - add_proposal_substructure(this, substructure); -} - -/** - * Implementation of sa_payload_t.get_proposals. - */ -static linked_list_t *get_proposals(private_sa_payload_t *this) +METHOD(sa_payload_t, get_proposals, linked_list_t*, + private_sa_payload_t *this) { int struct_number = 0; int ignore_struct_number = 0; - iterator_t *iterator; - proposal_substructure_t *proposal_struct; - linked_list_t *proposal_list; - - /* this list will hold our proposals */ - proposal_list = linked_list_create(); + enumerator_t *enumerator; + proposal_substructure_t *substruct; + linked_list_t *list; + proposal_t *proposal; + list = linked_list_create(); /* we do not support proposals split up to two proposal substructures, as * AH+ESP bundles are not supported in RFC4301 anymore. * To handle such structures safely, we just skip proposals with multiple * protocols. */ - iterator = this->proposals->create_iterator(this->proposals, TRUE); - while (iterator->iterate(iterator, (void **)&proposal_struct)) + enumerator = this->proposals->create_enumerator(this->proposals); + while (enumerator->enumerate(enumerator, &substruct)) { - proposal_t *proposal; - /* check if a proposal has a single protocol */ - if (proposal_struct->get_proposal_number(proposal_struct) == struct_number) + if (substruct->get_proposal_number(substruct) == struct_number) { if (ignore_struct_number < struct_number) { - /* remova an already added, if first of series */ - proposal_list->remove_last(proposal_list, (void**)&proposal); + /* remove an already added, if first of series */ + list->remove_last(list, (void**)&proposal); proposal->destroy(proposal); ignore_struct_number = struct_number; } continue; } struct_number++; - proposal = proposal_struct->get_proposal(proposal_struct); + proposal = substruct->get_proposal(substruct); if (proposal) { - proposal_list->insert_last(proposal_list, proposal); + list->insert_last(list, proposal); } } - iterator->destroy(iterator); - return proposal_list; + enumerator->destroy(enumerator); + return list; +} + +METHOD2(payload_t, sa_payload_t, destroy, void, + private_sa_payload_t *this) +{ + this->proposals->destroy_offset(this->proposals, + offsetof(proposal_substructure_t, destroy)); + free(this); } /* @@ -309,29 +271,27 @@ static linked_list_t *get_proposals(private_sa_payload_t *this) */ sa_payload_t *sa_payload_create() { - private_sa_payload_t *this = malloc_thing(private_sa_payload_t); - - /* public interface */ - this->public.payload_interface.verify = (status_t (*) (payload_t *))verify; - this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules; - this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length; - this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type; - this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type; - this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type; - this->public.payload_interface.destroy = (void (*) (payload_t *))destroy; - - /* public functions */ - this->public.create_proposal_substructure_iterator = (iterator_t* (*) (sa_payload_t *,bool)) create_proposal_substructure_iterator; - this->public.add_proposal_substructure = (void (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure; - this->public.add_proposal = (void (*) (sa_payload_t*,proposal_t*))add_proposal; - this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals; - this->public.destroy = (void (*) (sa_payload_t *)) destroy; - - /* set default values of the fields */ - this->critical = FALSE; - this->next_payload = NO_PAYLOAD; - this->payload_length = SA_PAYLOAD_HEADER_LENGTH; - this->proposals = linked_list_create(); + private_sa_payload_t *this; + + INIT(this, + .public = { + .payload_interface = { + .verify = _verify, + .get_encoding_rules = _get_encoding_rules, + .get_length = _get_length, + .get_next_type = _get_next_type, + .set_next_type = _set_next_type, + .get_type = _get_type, + .destroy = _destroy, + }, + .add_proposal = _add_proposal, + .get_proposals = _get_proposals, + .destroy = _destroy, + }, + .next_payload = NO_PAYLOAD, + .payload_length = SA_PAYLOAD_HEADER_LENGTH, + .proposals = linked_list_create(), + ); return &this->public; } @@ -340,19 +300,19 @@ sa_payload_t *sa_payload_create() */ sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals) { - iterator_t *iterator; + private_sa_payload_t *this; + enumerator_t *enumerator; proposal_t *proposal; - sa_payload_t *sa_payload = sa_payload_create(); - /* add every payload from the list */ - iterator = proposals->create_iterator(proposals, TRUE); - while (iterator->iterate(iterator, (void**)&proposal)) + this = (private_sa_payload_t*)sa_payload_create(); + enumerator = proposals->create_enumerator(proposals); + while (enumerator->enumerate(enumerator, &proposal)) { - add_proposal((private_sa_payload_t*)sa_payload, proposal); + add_proposal(this, proposal); } - iterator->destroy(iterator); + enumerator->destroy(enumerator); - return sa_payload; + return &this->public; } /* @@ -360,9 +320,10 @@ sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals) */ sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal) { - sa_payload_t *sa_payload = sa_payload_create(); + private_sa_payload_t *this; - add_proposal((private_sa_payload_t*)sa_payload, proposal); + this = (private_sa_payload_t*)sa_payload_create(); + add_proposal(this, proposal); - return sa_payload; + return &this->public; } diff --git a/src/libcharon/encoding/payloads/sa_payload.h b/src/libcharon/encoding/payloads/sa_payload.h index 25f5a2407..801a70738 100644 --- a/src/libcharon/encoding/payloads/sa_payload.h +++ b/src/libcharon/encoding/payloads/sa_payload.h @@ -40,33 +40,13 @@ typedef struct sa_payload_t sa_payload_t; * The SA Payload format is described in RFC section 3.3. */ struct sa_payload_t { + /** * The payload_t interface. */ payload_t payload_interface; /** - * Creates an iterator of stored proposal_substructure_t objects. - * - * When deleting an proposal using this iterator, - * the length of this transform substructure has to be refreshed - * by calling get_length()! - * - * @param forward iterator direction (TRUE: front to end) - * @return created iterator_t object - */ - iterator_t *(*create_proposal_substructure_iterator) (sa_payload_t *this, - bool forward); - - /** - * Adds a proposal_substructure_t object to this object. - * - * @param proposal proposal_substructure_t object to add - */ - void (*add_proposal_substructure) (sa_payload_t *this, - proposal_substructure_t *proposal); - - /** * Gets the proposals in this payload as a list. * * @return a list containing proposal_t s diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c new file mode 100644 index 000000000..d9e39fe43 --- /dev/null +++ b/src/libcharon/kernel/kernel_handler.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2010 Tobias Brunner + * 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 "kernel_handler.h" + +#include <hydra.h> +#include <daemon.h> +#include <processing/jobs/acquire_job.h> +#include <processing/jobs/delete_child_sa_job.h> +#include <processing/jobs/migrate_job.h> +#include <processing/jobs/rekey_child_sa_job.h> +#include <processing/jobs/roam_job.h> +#include <processing/jobs/update_sa_job.h> + +typedef struct private_kernel_handler_t private_kernel_handler_t; + +/** + * Private data of a kernel_handler_t object. + */ +struct private_kernel_handler_t { + + /** + * Public part of kernel_handler_t object. + */ + kernel_handler_t public; + +}; + +/** + * convert an IP protocol identifier to the IKEv2 specific protocol identifier. + */ +static inline protocol_id_t proto_ip2ike(u_int8_t protocol) +{ + switch (protocol) + { + case IPPROTO_ESP: + return PROTO_ESP; + case IPPROTO_AH: + return PROTO_AH; + default: + return protocol; + } +} + +METHOD(kernel_listener_t, acquire, bool, + private_kernel_handler_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts) +{ + job_t *job; + if (src_ts && dst_ts) + { + DBG1(DBG_KNL, "creating acquire job for policy %R === %R " + "with reqid {%u}", src_ts, dst_ts, reqid); + } + else + { + DBG1(DBG_KNL, "creating acquire job for policy with reqid {%u}", reqid); + } + job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts); + lib->processor->queue_job(lib->processor, job); + return TRUE; +} + +METHOD(kernel_listener_t, expire, bool, + private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol, + u_int32_t spi, bool hard) +{ + job_t *job; + protocol_id_t proto = proto_ip2ike(protocol); + DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x " + "and reqid {%u}", hard ? "delete" : "rekey", + protocol_id_names, proto, ntohl(spi), reqid); + if (hard) + { + job = (job_t*)delete_child_sa_job_create(reqid, proto, spi); + } + else + { + job = (job_t*)rekey_child_sa_job_create(reqid, proto, spi); + } + lib->processor->queue_job(lib->processor, job); + return TRUE; +} + +METHOD(kernel_listener_t, mapping, bool, + private_kernel_handler_t *this, u_int32_t reqid, u_int32_t spi, + host_t *remote) +{ + job_t *job; + DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and " + "reqid {%u} changed, queuing update job", ntohl(spi), reqid); + job = (job_t*)update_sa_job_create(reqid, remote); + lib->processor->queue_job(lib->processor, job); + return TRUE; +} + +METHOD(kernel_listener_t, migrate, bool, + private_kernel_handler_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, host_t *local, host_t *remote) +{ + job_t *job; + DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with " + "reqid {%u}", src_ts, dst_ts, policy_dir_names, direction, + reqid, local); + job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, direction, local, + remote); + lib->processor->queue_job(lib->processor, job); + return TRUE; +} + +METHOD(kernel_listener_t, roam, bool, + private_kernel_handler_t *this, bool address) +{ + job_t *job; + job = (job_t*)roam_job_create(address); + lib->processor->queue_job(lib->processor, job); + return TRUE; +} + +METHOD(kernel_handler_t, destroy, void, + private_kernel_handler_t *this) +{ + hydra->kernel_interface->remove_listener(hydra->kernel_interface, + &this->public.listener); + free(this); +} + +kernel_handler_t *kernel_handler_create() +{ + private_kernel_handler_t *this; + + INIT(this, + .public = { + .listener = { + .acquire = _acquire, + .expire = _expire, + .mapping = _mapping, + .migrate = _migrate, + .roam = _roam, + }, + .destroy = _destroy, + }, + ); + + hydra->kernel_interface->add_listener(hydra->kernel_interface, + &this->public.listener); + + return &this->public; +} + diff --git a/src/libcharon/kernel/kernel_handler.h b/src/libcharon/kernel/kernel_handler.h new file mode 100644 index 000000000..48ad6889c --- /dev/null +++ b/src/libcharon/kernel/kernel_handler.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Tobias Brunner + * 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 kernel_handler kernel_handler + * @{ @ingroup ckernel + */ + +#ifndef KERNEL_HANDLER_H_ +#define KERNEL_HANDLER_H_ + +typedef struct kernel_handler_t kernel_handler_t; + +#include <kernel/kernel_listener.h> + +/** + * Listens to and handles kernel events. + */ +struct kernel_handler_t { + + /** + * Implements the kernel listener interface. + */ + kernel_listener_t listener; + + /** + * Destroy this instance. + */ + void (*destroy)(kernel_handler_t *this); + +}; + +/** + * Create an object of type kernel_handler_t. + */ +kernel_handler_t *kernel_handler_create(); + +#endif /** KERNEL_HANDLER_H_ @}*/ diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c deleted file mode 100644 index 837e628bc..000000000 --- a/src/libcharon/kernel/kernel_interface.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2008-2009 Tobias Brunner - * Hochschule fuer Technik Rapperswil - * 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 "kernel_interface.h" - -#include <daemon.h> - -typedef struct private_kernel_interface_t private_kernel_interface_t; - -/** - * Private data of a kernel_interface_t object. - */ -struct private_kernel_interface_t { - - /** - * Public part of kernel_interface_t object. - */ - kernel_interface_t public; - - /** - * ipsec interface - */ - kernel_ipsec_t *ipsec; - - /** - * network interface - */ - kernel_net_t *net; -}; - -METHOD(kernel_interface_t, get_spi, status_t, - private_kernel_interface_t *this, host_t *src, host_t *dst, - protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->get_spi(this->ipsec, src, dst, protocol, reqid, spi); -} - -METHOD(kernel_interface_t, get_cpi, status_t, - private_kernel_interface_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->get_cpi(this->ipsec, src, dst, reqid, cpi); -} - -METHOD(kernel_interface_t, add_sa, status_t, - private_kernel_interface_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, u_int32_t reqid, - mark_t mark, 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 inbound, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid, - mark, lifetime, enc_alg, enc_key, int_alg, int_key, mode, ipcomp, - cpi, encap, inbound, src_ts, dst_ts); -} - -METHOD(kernel_interface_t, update_sa, status_t, - private_kernel_interface_t *this, u_int32_t spi, protocol_id_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) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->update_sa(this->ipsec, spi, protocol, cpi, src, dst, - new_src, new_dst, encap, new_encap, mark); -} - -METHOD(kernel_interface_t, query_sa, status_t, - private_kernel_interface_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, mark, bytes); -} - -METHOD(kernel_interface_t, del_sa, status_t, - private_kernel_interface_t *this, host_t *src, host_t *dst, u_int32_t spi, - protocol_id_t protocol, u_int16_t cpi, mark_t mark) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi, mark); -} - -METHOD(kernel_interface_t, add_policy, status_t, - private_kernel_interface_t *this, host_t *src, host_t *dst, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts, - policy_dir_t direction, u_int32_t spi, protocol_id_t protocol, - u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp, - u_int16_t cpi, bool routed) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts, - direction, spi, protocol, reqid, mark, mode, ipcomp, cpi, routed); -} - -METHOD(kernel_interface_t, query_policy, status_t, - private_kernel_interface_t *this, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, - u_int32_t *use_time) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->query_policy(this->ipsec, src_ts, dst_ts, - direction, mark, use_time); -} - -METHOD(kernel_interface_t, del_policy, status_t, - private_kernel_interface_t *this, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, - bool unrouted) -{ - if (!this->ipsec) - { - return NOT_SUPPORTED; - } - return this->ipsec->del_policy(this->ipsec, src_ts, dst_ts, - direction, mark, unrouted); -} - -METHOD(kernel_interface_t, get_source_addr, host_t*, - private_kernel_interface_t *this, host_t *dest, host_t *src) -{ - if (!this->net) - { - return NULL; - } - return this->net->get_source_addr(this->net, dest, src); -} - -METHOD(kernel_interface_t, get_nexthop, host_t*, - private_kernel_interface_t *this, host_t *dest) -{ - if (!this->net) - { - return NULL; - } - return this->net->get_nexthop(this->net, dest); -} - -METHOD(kernel_interface_t, get_interface, char*, - private_kernel_interface_t *this, host_t *host) -{ - if (!this->net) - { - return NULL; - } - return this->net->get_interface(this->net, host); -} - -METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*, - private_kernel_interface_t *this, bool include_down_ifaces, - bool include_virtual_ips) -{ - if (!this->net) - { - return enumerator_create_empty(); - } - return this->net->create_address_enumerator(this->net, include_down_ifaces, - include_virtual_ips); -} - -METHOD(kernel_interface_t, add_ip, status_t, - private_kernel_interface_t *this, host_t *virtual_ip, host_t *iface_ip) -{ - if (!this->net) - { - return NOT_SUPPORTED; - } - return this->net->add_ip(this->net, virtual_ip, iface_ip); -} - -METHOD(kernel_interface_t, del_ip, status_t, - private_kernel_interface_t *this, host_t *virtual_ip) -{ - if (!this->net) - { - return NOT_SUPPORTED; - } - return this->net->del_ip(this->net, virtual_ip); -} - -METHOD(kernel_interface_t, add_route, status_t, - private_kernel_interface_t *this, chunk_t dst_net, - u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name) -{ - if (!this->net) - { - return NOT_SUPPORTED; - } - return this->net->add_route(this->net, dst_net, prefixlen, gateway, - src_ip, if_name); -} - -METHOD(kernel_interface_t, del_route, status_t, - private_kernel_interface_t *this, chunk_t dst_net, - u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name) -{ - if (!this->net) - { - return NOT_SUPPORTED; - } - return this->net->del_route(this->net, dst_net, prefixlen, gateway, - src_ip, if_name); -} - -METHOD(kernel_interface_t, bypass_socket, bool, - private_kernel_interface_t *this, int fd, int family) -{ - if (!this->ipsec) - { - return FALSE; - } - return this->ipsec->bypass_socket(this->ipsec, fd, family); -} - -METHOD(kernel_interface_t, get_address_by_ts, status_t, - private_kernel_interface_t *this, traffic_selector_t *ts, host_t **ip) -{ - enumerator_t *addrs; - host_t *host; - int family; - bool found = FALSE; - - DBG2(DBG_KNL, "getting a local address in traffic selector %R", ts); - - /* if we have a family which includes localhost, we do not - * search for an IP, we use the default */ - family = ts->get_type(ts) == TS_IPV4_ADDR_RANGE ? AF_INET : AF_INET6; - - if (family == AF_INET) - { - host = host_create_from_string("127.0.0.1", 0); - } - else - { - host = host_create_from_string("::1", 0); - } - - if (ts->includes(ts, host)) - { - *ip = host_create_any(family); - host->destroy(host); - DBG2(DBG_KNL, "using host %H", *ip); - return SUCCESS; - } - host->destroy(host); - - addrs = create_address_enumerator(this, TRUE, TRUE); - while (addrs->enumerate(addrs, (void**)&host)) - { - if (ts->includes(ts, host)) - { - found = TRUE; - *ip = host->clone(host); - break; - } - } - addrs->destroy(addrs); - - if (!found) - { - DBG1(DBG_KNL, "no local address found in traffic selector %R", ts); - return FAILED; - } - - DBG2(DBG_KNL, "using host %H", *ip); - return SUCCESS; -} - - -METHOD(kernel_interface_t, add_ipsec_interface, void, - private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor) -{ - if (!this->ipsec) - { - this->ipsec = constructor(); - } -} - -METHOD(kernel_interface_t, remove_ipsec_interface, void, - private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor) -{ - /* TODO: replace if interface currently in use */ -} - -METHOD(kernel_interface_t, add_net_interface, void, - private_kernel_interface_t *this, kernel_net_constructor_t constructor) -{ - if (!this->net) - { - this->net = constructor(); - } -} - -METHOD(kernel_interface_t, remove_net_interface, void, - private_kernel_interface_t *this, kernel_net_constructor_t constructor) -{ - /* TODO: replace if interface currently in use */ -} - -METHOD(kernel_interface_t, destroy, void, - private_kernel_interface_t *this) -{ - DESTROY_IF(this->ipsec); - DESTROY_IF(this->net); - free(this); -} - -/* - * Described in header-file - */ -kernel_interface_t *kernel_interface_create() -{ - private_kernel_interface_t *this; - - INIT(this, - .public = { - .get_spi = _get_spi, - .get_cpi = _get_cpi, - .add_sa = _add_sa, - .update_sa = _update_sa, - .query_sa = _query_sa, - .del_sa = _del_sa, - .add_policy = _add_policy, - .query_policy = _query_policy, - .del_policy = _del_policy, - .get_source_addr = _get_source_addr, - .get_nexthop = _get_nexthop, - .get_interface = _get_interface, - .create_address_enumerator = _create_address_enumerator, - .add_ip = _add_ip, - .del_ip = _del_ip, - .add_route = _add_route, - .del_route = _del_route, - .bypass_socket = _bypass_socket, - - .get_address_by_ts = _get_address_by_ts, - .add_ipsec_interface = _add_ipsec_interface, - .remove_ipsec_interface = _remove_ipsec_interface, - .add_net_interface = _add_net_interface, - .remove_net_interface = _remove_net_interface, - .destroy = _destroy, - }, - ); - - return &this->public; -} - diff --git a/src/libcharon/kernel/kernel_interface.h b/src/libcharon/kernel/kernel_interface.h deleted file mode 100644 index 92d85f9c9..000000000 --- a/src/libcharon/kernel/kernel_interface.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright (C) 2006-2009 Tobias Brunner - * Copyright (C) 2006 Daniel Roethlisberger - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 kernel_interface kernel_interface - * @{ @ingroup kernel - */ - -#ifndef KERNEL_INTERFACE_H_ -#define KERNEL_INTERFACE_H_ - -typedef struct kernel_interface_t kernel_interface_t; - -#include <utils/host.h> -#include <crypto/prf_plus.h> -#include <encoding/payloads/proposal_substructure.h> - -#include <kernel/kernel_ipsec.h> -#include <kernel/kernel_net.h> - -/** - * Constructor function for ipsec kernel interface - */ -typedef kernel_ipsec_t* (*kernel_ipsec_constructor_t)(void); - -/** - * Constructor function for network kernel interface - */ -typedef kernel_net_t* (*kernel_net_constructor_t)(void); - -/** - * Manager and wrapper for different kernel interfaces. - * - * The kernel interface handles the communication with the kernel - * for SA and policy management and interface and IP address management. - */ -struct kernel_interface_t { - - /** - * Get a SPI from the kernel. - * - * @param src source address of SA - * @param dst destination address of SA - * @param protocol protocol for SA (ESP/AH) - * @param reqid unique ID for this SA - * @param spi allocated spi - * @return SUCCESS if operation completed - */ - status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst, - protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi); - - /** - * Get a Compression Parameter Index (CPI) from the kernel. - * - * @param src source address of SA - * @param dst destination address of SA - * @param reqid unique ID for the corresponding SA - * @param cpi allocated cpi - * @return SUCCESS if operation completed - */ - status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi); - - /** - * Add an SA to the SAD. - * - * add_sa() may update an already allocated - * SPI (via get_spi). In this case, the replace - * flag must be set. - * This function does install a single SA for a - * single protocol in one direction. - * - * @param src source address for this SA - * @param dst destination address for this SA - * @param spi SPI allocated by us or remote peer - * @param protocol protocol for this SA (ESP/AH) - * @param reqid unique ID for this SA - * @param mark optional mark for this SA - * @param lifetime lifetime_cfg_t for this SA - * @param enc_alg Algorithm to use for encryption (ESP only) - * @param enc_key key to use for encryption - * @param int_alg Algorithm to use for integrity protection - * @param int_key key to use for integrity protection - * @param mode mode of the SA (tunnel, transport) - * @param ipcomp IPComp transform to use - * @param cpi CPI for IPComp - * @param encap enable UDP encapsulation for NAT traversal - * @param inbound TRUE if this is an inbound SA - * @param src_ts traffic selector with BEET source address - * @param dst_ts traffic selector with BEET destination address - * @return SUCCESS if operation completed - */ - status_t (*add_sa) (kernel_interface_t *this, - host_t *src, host_t *dst, u_int32_t spi, - protocol_id_t protocol, u_int32_t reqid, mark_t mark, - 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 inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts); - - /** - * Update the hosts on an installed SA. - * - * We cannot directly update the destination address as the kernel - * requires the spi, the protocol AND the destination address (and family) - * to identify SAs. Therefore if the destination address changed we - * create a new SA and delete the old one. - * - * @param spi SPI of the SA - * @param protocol protocol for this SA (ESP/AH) - * @param cpi CPI for IPComp, 0 if no IPComp is used - * @param src current source address - * @param dst current destination address - * @param new_src new source address - * @param new_dst new destination address - * @param encap current use of UDP encapsulation - * @param new_encap new use of UDP encapsulation - * @param mark optional mark for this SA - * @return SUCCESS if operation completed, NOT_SUPPORTED if - * the kernel interface can't update the SA - */ - status_t (*update_sa)(kernel_interface_t *this, - u_int32_t spi, protocol_id_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); - - /** - * Query the number of bytes processed by an SA from the SAD. - * - * @param src source address for this SA - * @param dst destination address for this SA - * @param spi SPI allocated by us or remote peer - * @param protocol protocol for this SA (ESP/AH) - * @param mark optional mark for this SA - * @param[out] bytes the number of bytes processed by SA - * @return SUCCESS if operation completed - */ - status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, mark_t mark, - u_int64_t *bytes); - - /** - * Delete a previously installed SA from the SAD. - * - * @param src source address for this SA - * @param dst destination address for this SA - * @param spi SPI allocated by us or remote peer - * @param protocol protocol for this SA (ESP/AH) - * @param cpi CPI for IPComp or 0 - * @param mark optional mark for this SA - * @return SUCCESS if operation completed - */ - status_t (*del_sa) (kernel_interface_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, - mark_t mark); - - /** - * Add a policy to the SPD. - * - * A policy is always associated to an SA. Traffic which matches a - * policy is handled by the SA with the same reqid. - * - * @param src source address of SA - * @param dst dest address of SA - * @param src_ts traffic selector to match traffic source - * @param dst_ts traffic selector to match traffic dest - * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD - * @param spi SPI of SA - * @param protocol protocol to use to protect traffic (AH/ESP) - * @param reqid unique ID of an SA to use to enforce policy - * @param mark mark for this policy - * @param mode mode of SA (tunnel, transport) - * @param ipcomp the IPComp transform used - * @param cpi CPI for IPComp - * @param routed TRUE, if this policy is routed in the kernel - * @return SUCCESS if operation completed - */ - status_t (*add_policy) (kernel_interface_t *this, - host_t *src, host_t *dst, - traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, - policy_dir_t direction, u_int32_t spi, - protocol_id_t protocol, u_int32_t reqid, - mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp, - u_int16_t cpi, bool routed); - - /** - * Query the use time of a policy. - * - * The use time of a policy is the time the policy was used - * for the last time. - * - * @param src_ts traffic selector to match traffic source - * @param dst_ts traffic selector to match traffic dest - * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD - * @param mark optional mark - * @param[out] use_time the time of this SA's last use - * @return SUCCESS if operation completed - */ - status_t (*query_policy) (kernel_interface_t *this, - traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, - policy_dir_t direction, mark_t mark, - u_int32_t *use_time); - - /** - * Remove a policy from the SPD. - * - * The kernel interface implements reference counting for policies. - * If the same policy is installed multiple times (in the case of rekeying), - * the reference counter is increased. del_policy() decreases the ref counter - * and removes the policy only when no more references are available. - * - * @param src_ts traffic selector to match traffic source - * @param dst_ts traffic selector to match traffic dest - * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD - * @param mark optional mark - * @param unrouted TRUE, if this policy is unrouted from the kernel - * @return SUCCESS if operation completed - */ - status_t (*del_policy) (kernel_interface_t *this, - traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, - policy_dir_t direction, mark_t mark, - bool unrouted); - - /** - * Get our outgoing source address for a destination. - * - * Does a route lookup to get the source address used to reach dest. - * The returned host is allocated and must be destroyed. - * An optional src address can be used to check if a route is available - * for given source to dest. - * - * @param dest target destination address - * @param src source address to check, or NULL - * @return outgoing source address, NULL if unreachable - */ - host_t* (*get_source_addr)(kernel_interface_t *this, - host_t *dest, host_t *src); - - /** - * Get the next hop for a destination. - * - * Does a route lookup to get the next hop used to reach dest. - * The returned host is allocated and must be destroyed. - * - * @param dest target destination address - * @return next hop address, NULL if unreachable - */ - host_t* (*get_nexthop)(kernel_interface_t *this, host_t *dest); - - /** - * Get the interface name of a local address. - * - * @param host address to get interface name from - * @return allocated interface name, or NULL if not found - */ - char* (*get_interface) (kernel_interface_t *this, host_t *host); - - /** - * Creates an enumerator over all local addresses. - * - * This function blocks an internal cached address list until the - * enumerator gets destroyed. - * The hosts are read-only, do not modify of free. - * - * @param include_down_ifaces TRUE to enumerate addresses from down interfaces - * @param include_virtual_ips TRUE to enumerate virtual ip addresses - * @return enumerator over host_t's - */ - enumerator_t *(*create_address_enumerator) (kernel_interface_t *this, - bool include_down_ifaces, bool include_virtual_ips); - - /** - * Add a virtual IP to an interface. - * - * Virtual IPs are attached to an interface. If an IP is added multiple - * times, the IP is refcounted and not removed until del_ip() was called - * as many times as add_ip(). - * The virtual IP is attached to the interface where the iface_ip is found. - * - * @param virtual_ip virtual ip address to assign - * @param iface_ip IP of an interface to attach virtual IP - * @return SUCCESS if operation completed - */ - status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip, - host_t *iface_ip); - - /** - * Remove a virtual IP from an interface. - * - * The kernel interface uses refcounting, see add_ip(). - * - * @param virtual_ip virtual ip address to assign - * @return SUCCESS if operation completed - */ - status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip); - - /** - * Add a route. - * - * @param dst_net destination net - * @param prefixlen destination net prefix length - * @param gateway gateway for this route - * @param src_ip sourc ip of the route - * @param if_name name of the interface the route is bound to - * @return SUCCESS if operation completed - * ALREADY_DONE if the route already exists - */ - status_t (*add_route) (kernel_interface_t *this, chunk_t dst_net, u_int8_t prefixlen, - host_t *gateway, host_t *src_ip, char *if_name); - - /** - * Delete a route. - * - * @param dst_net destination net - * @param prefixlen destination net prefix length - * @param gateway gateway for this route - * @param src_ip sourc ip of the route - * @param if_name name of the interface the route is bound to - * @return SUCCESS if operation completed - */ - status_t (*del_route) (kernel_interface_t *this, chunk_t dst_net, u_int8_t prefixlen, - host_t *gateway, host_t *src_ip, char *if_name); - - /** - * Set up a bypass policy for a given socket. - * - * @param fd socket file descriptor to setup policy for - * @param family protocol family of the socket - * @return TRUE of policy set up successfully - */ - bool (*bypass_socket)(kernel_interface_t *this, int fd, int family); - - /** - * manager methods - */ - - /** - * Tries to find an ip address of a local interface that is included in the - * supplied traffic selector. - * - * @param ts traffic selector - * @param ip returned ip (has to be destroyed) - * @return SUCCESS if address found - */ - status_t (*get_address_by_ts) (kernel_interface_t *this, - traffic_selector_t *ts, host_t **ip); - - /** - * Register an ipsec kernel interface constructor on the manager. - * - * @param create constructor to register - */ - void (*add_ipsec_interface)(kernel_interface_t *this, kernel_ipsec_constructor_t create); - - /** - * Unregister an ipsec kernel interface constructor. - * - * @param create constructor to unregister - */ - void (*remove_ipsec_interface)(kernel_interface_t *this, kernel_ipsec_constructor_t create); - - /** - * Register a network kernel interface constructor on the manager. - * - * @param create constructor to register - */ - void (*add_net_interface)(kernel_interface_t *this, kernel_net_constructor_t create); - - /** - * Unregister a network kernel interface constructor. - * - * @param create constructor to unregister - */ - void (*remove_net_interface)(kernel_interface_t *this, kernel_net_constructor_t create); - - /** - * Destroys a kernel_interface_manager_t object. - */ - void (*destroy) (kernel_interface_t *this); -}; - -/** - * Creates an object of type kernel_interface_t. - */ -kernel_interface_t *kernel_interface_create(void); - -#endif /** KERNEL_INTERFACE_H_ @}*/ diff --git a/src/libcharon/kernel/kernel_ipsec.h b/src/libcharon/kernel/kernel_ipsec.h deleted file mode 100644 index d09265cc9..000000000 --- a/src/libcharon/kernel/kernel_ipsec.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2006-2009 Tobias Brunner - * Copyright (C) 2006 Daniel Roethlisberger - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 kernel_ipsec kernel_ipsec - * @{ @ingroup kernel - */ - -#ifndef KERNEL_IPSEC_H_ -#define KERNEL_IPSEC_H_ - -typedef enum ipsec_mode_t ipsec_mode_t; -typedef enum policy_dir_t policy_dir_t; -typedef struct kernel_ipsec_t kernel_ipsec_t; - -#include <utils/host.h> -#include <crypto/prf_plus.h> -#include <config/proposal.h> -#include <config/child_cfg.h> - -/** - * Mode of a CHILD_SA. - */ -enum ipsec_mode_t { - /** transport mode, no inner address */ - MODE_TRANSPORT = 1, - /** tunnel mode, inner and outer addresses */ - MODE_TUNNEL, - /** BEET mode, tunnel mode but fixed, bound inner addresses */ - MODE_BEET, -}; - -/** - * enum names for ipsec_mode_t. - */ -extern enum_name_t *ipsec_mode_names; - -/** - * Direction of a policy. These are equal to those - * defined in xfrm.h, but we want to stay implementation - * neutral here. - */ -enum policy_dir_t { - /** Policy for inbound traffic */ - POLICY_IN = 0, - /** Policy for outbound traffic */ - POLICY_OUT = 1, - /** Policy for forwarded traffic */ - POLICY_FWD = 2, -}; - -/** - * enum names for policy_dir_t. - */ -extern enum_name_t *policy_dir_names; - -/** - * Interface to the ipsec subsystem of the kernel. - * - * The kernel ipsec interface handles the communication with the kernel - * for SA and policy management. It allows setup of these, and provides - * further the handling of kernel events. - * Policy information are cached in the interface. This is necessary to do - * reference counting. The Linux kernel does not allow the same policy - * installed twice, but we need this as CHILD_SA exist multiple times - * when rekeying. Thats why we do reference counting of policies. - */ -struct kernel_ipsec_t { - - /** - * Get a SPI from the kernel. - * - * @param src source address of SA - * @param dst destination address of SA - * @param protocol protocol for SA (ESP/AH) - * @param reqid unique ID for this SA - * @param spi allocated spi - * @return SUCCESS if operation completed - */ - status_t (*get_spi)(kernel_ipsec_t *this, host_t *src, host_t *dst, - protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi); - - /** - * Get a Compression Parameter Index (CPI) from the kernel. - * - * @param src source address of SA - * @param dst destination address of SA - * @param reqid unique ID for the corresponding SA - * @param cpi allocated cpi - * @return SUCCESS if operation completed - */ - status_t (*get_cpi)(kernel_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi); - - /** - * Add an SA to the SAD. - * - * add_sa() may update an already allocated - * SPI (via get_spi). In this case, the replace - * flag must be set. - * This function does install a single SA for a - * single protocol in one direction. - * - * @param src source address for this SA - * @param dst destination address for this SA - * @param spi SPI allocated by us or remote peer - * @param protocol protocol for this SA (ESP/AH) - * @param reqid unique ID for this SA - * @param mark mark for this SA - * @param lifetime lifetime_cfg_t for this SA - * @param enc_alg Algorithm to use for encryption (ESP only) - * @param enc_key key to use for encryption - * @param int_alg Algorithm to use for integrity protection - * @param int_key key to use for integrity protection - * @param mode mode of the SA (tunnel, transport) - * @param ipcomp IPComp transform to use - * @param cpi CPI for IPComp - * @param encap enable UDP encapsulation for NAT traversal - * @param inbound TRUE if this is an inbound SA - * @param src_ts traffic selector with BEET source address - * @param dst_ts traffic selector with BEET destination address - * @return SUCCESS if operation completed - */ - status_t (*add_sa) (kernel_ipsec_t *this, - host_t *src, host_t *dst, u_int32_t spi, - protocol_id_t protocol, u_int32_t reqid, - mark_t mark, 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 inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts); - - /** - * Update the hosts on an installed SA. - * - * We cannot directly update the destination address as the kernel - * requires the spi, the protocol AND the destination address (and family) - * to identify SAs. Therefore if the destination address changed we - * create a new SA and delete the old one. - * - * @param spi SPI of the SA - * @param protocol protocol for this SA (ESP/AH) - * @param cpi CPI for IPComp, 0 if no IPComp is used - * @param src current source address - * @param dst current destination address - * @param new_src new source address - * @param new_dst new destination address - * @param encap current use of UDP encapsulation - * @param new_encap new use of UDP encapsulation - * @param mark optional mark for this SA - * @return SUCCESS if operation completed, NOT_SUPPORTED if - * the kernel interface can't update the SA - */ - status_t (*update_sa)(kernel_ipsec_t *this, - u_int32_t spi, protocol_id_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); - - /** - * Query the number of bytes processed by an SA from the SAD. - * - * @param src source address for this SA - * @param dst destination address for this SA - * @param spi SPI allocated by us or remote peer - * @param protocol protocol for this SA (ESP/AH) - * @param mark optional mark for this SA - * @param[out] bytes the number of bytes processed by SA - * @return SUCCESS if operation completed - */ - status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, mark_t mark, - u_int64_t *bytes); - - /** - * Delete a previusly installed SA from the SAD. - * - * @param src source address for this SA - * @param dst destination address for this SA - * @param spi SPI allocated by us or remote peer - * @param protocol protocol for this SA (ESP/AH) - * @param cpi CPI for IPComp or 0 - * @param mark optional mark for this SA - * @return SUCCESS if operation completed - */ - status_t (*del_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, - mark_t mark); - - /** - * Add a policy to the SPD. - * - * A policy is always associated to an SA. Traffic which matches a - * policy is handled by the SA with the same reqid. - * - * @param src source address of SA - * @param dst dest address of SA - * @param src_ts traffic selector to match traffic source - * @param dst_ts traffic selector to match traffic dest - * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD - * @param spi SPI of SA - * @param protocol protocol to use to protect traffic (AH/ESP) - * @param reqid unique ID of an SA to use to enforce policy - * @param mark mark for this policy - * @param mode mode of SA (tunnel, transport) - * @param ipcomp the IPComp transform used - * @param cpi CPI for IPComp - * @param routed TRUE, if this policy is routed in the kernel - * @return SUCCESS if operation completed - */ - status_t (*add_policy) (kernel_ipsec_t *this, - host_t *src, host_t *dst, - traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, - policy_dir_t direction, u_int32_t spi, - protocol_id_t protocol, u_int32_t reqid, - mark_t mark, ipsec_mode_t mode, - u_int16_t ipcomp, u_int16_t cpi, bool routed); - - /** - * Query the use time of a policy. - * - * The use time of a policy is the time the policy was used for the last - * time. It is not the system time, but a monotonic timestamp as returned - * by time_monotonic. - * - * @param src_ts traffic selector to match traffic source - * @param dst_ts traffic selector to match traffic dest - * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD - * @param mark optional mark - * @param[out] use_time the monotonic timestamp of this SA's last use - * @return SUCCESS if operation completed - */ - status_t (*query_policy) (kernel_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); - - /** - * Remove a policy from the SPD. - * - * The kernel interface implements reference counting for policies. - * If the same policy is installed multiple times (in the case of rekeying), - * the reference counter is increased. del_policy() decreases the ref counter - * and removes the policy only when no more references are available. - * - * @param src_ts traffic selector to match traffic source - * @param dst_ts traffic selector to match traffic dest - * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD - * @param mark optional mark - * @param unrouted TRUE, if this policy is unrouted from the kernel - * @return SUCCESS if operation completed - */ - status_t (*del_policy) (kernel_ipsec_t *this, - traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, - policy_dir_t direction, mark_t mark, - bool unrouted); - - /** - * Install a bypass policy for the given socket. - * - * @param fd socket file descriptor to setup policy for - * @param family protocol family of the socket - * @return TRUE of policy set up successfully - */ - bool (*bypass_socket)(kernel_ipsec_t *this, int fd, int family); - - /** - * Destroy the implementation. - */ - void (*destroy) (kernel_ipsec_t *this); -}; - -#endif /** KERNEL_IPSEC_H_ @}*/ diff --git a/src/libcharon/kernel/kernel_net.h b/src/libcharon/kernel/kernel_net.h deleted file mode 100644 index efb221f88..000000000 --- a/src/libcharon/kernel/kernel_net.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2007 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 kernel_net kernel_net - * @{ @ingroup kernel - */ - -#ifndef KERNEL_NET_H_ -#define KERNEL_NET_H_ - -typedef struct kernel_net_t kernel_net_t; - -#include <utils/enumerator.h> -#include <utils/host.h> - -/** - * Interface to the network subsystem of the kernel. - * - * The kernel network interface handles the communication with the kernel - * for interface and IP address management. - */ -struct kernel_net_t { - - /** - * Get our outgoing source address for a destination. - * - * Does a route lookup to get the source address used to reach dest. - * The returned host is allocated and must be destroyed. - * An optional src address can be used to check if a route is available - * for given source to dest. - * - * @param dest target destination address - * @param src source address to check, or NULL - * @return outgoing source address, NULL if unreachable - */ - host_t* (*get_source_addr)(kernel_net_t *this, host_t *dest, host_t *src); - - /** - * Get the next hop for a destination. - * - * Does a route lookup to get the next hop used to reach dest. - * The returned host is allocated and must be destroyed. - * - * @param dest target destination address - * @return next hop address, NULL if unreachable - */ - host_t* (*get_nexthop)(kernel_net_t *this, host_t *dest); - - /** - * Get the interface name of a local address. - * - * @param host address to get interface name from - * @return allocated interface name, or NULL if not found - */ - char* (*get_interface) (kernel_net_t *this, host_t *host); - - /** - * Creates an enumerator over all local addresses. - * - * This function blocks an internal cached address list until the - * enumerator gets destroyed. - * The hosts are read-only, do not modify of free. - * - * @param include_down_ifaces TRUE to enumerate addresses from down interfaces - * @param include_virtual_ips TRUE to enumerate virtual ip addresses - * @return enumerator over host_t's - */ - enumerator_t *(*create_address_enumerator) (kernel_net_t *this, - bool include_down_ifaces, bool include_virtual_ips); - - /** - * Add a virtual IP to an interface. - * - * Virtual IPs are attached to an interface. If an IP is added multiple - * times, the IP is refcounted and not removed until del_ip() was called - * as many times as add_ip(). - * The virtual IP is attached to the interface where the iface_ip is found. - * - * @param virtual_ip virtual ip address to assign - * @param iface_ip IP of an interface to attach virtual IP - * @return SUCCESS if operation completed - */ - status_t (*add_ip) (kernel_net_t *this, host_t *virtual_ip, - host_t *iface_ip); - - /** - * Remove a virtual IP from an interface. - * - * The kernel interface uses refcounting, see add_ip(). - * - * @param virtual_ip virtual ip address to assign - * @return SUCCESS if operation completed - */ - status_t (*del_ip) (kernel_net_t *this, host_t *virtual_ip); - - /** - * Add a route. - * - * @param dst_net destination net - * @param prefixlen destination net prefix length - * @param gateway gateway for this route - * @param src_ip sourc ip of the route - * @param if_name name of the interface the route is bound to - * @return SUCCESS if operation completed - * ALREADY_DONE if the route already exists - */ - status_t (*add_route) (kernel_net_t *this, chunk_t dst_net, u_int8_t prefixlen, - host_t *gateway, host_t *src_ip, char *if_name); - - /** - * Delete a route. - * - * @param dst_net destination net - * @param prefixlen destination net prefix length - * @param gateway gateway for this route - * @param src_ip sourc ip of the route - * @param if_name name of the interface the route is bound to - * @return SUCCESS if operation completed - */ - status_t (*del_route) (kernel_net_t *this, chunk_t dst_net, u_int8_t prefixlen, - host_t *gateway, host_t *src_ip, char *if_name); - - /** - * Destroy the implementation. - */ - void (*destroy) (kernel_net_t *this); -}; - -#endif /** KERNEL_NET_H_ @}*/ diff --git a/src/libcharon/network/receiver.c b/src/libcharon/network/receiver.c index 63a8cab58..d8cebe192 100644 --- a/src/libcharon/network/receiver.c +++ b/src/libcharon/network/receiver.c @@ -146,7 +146,7 @@ static void send_notify(message_t *request, notify_type_t type, chunk_t data) ike_sa_id->switch_initiator(ike_sa_id); response->set_ike_sa_id(response, ike_sa_id); response->add_notify(response, FALSE, type, data); - if (response->generate(response, NULL, NULL, &packet) == SUCCESS) + if (response->generate(response, NULL, &packet) == SUCCESS) { charon->sender->send(charon->sender, packet); response->destroy(response); @@ -274,9 +274,17 @@ static job_requeue_t receive_packets(private_receiver_t *this) { packet_t *packet; message_t *message; + status_t status; /* read in a packet */ - if (charon->socket->receive(charon->socket, &packet) != SUCCESS) + status = charon->socket->receive(charon->socket, &packet); + if (status == NOT_SUPPORTED) + { + /* the processor destroys this job */ + this->job = NULL; + return JOB_REQUEUE_NONE; + } + else if (status != SUCCESS) { DBG2(DBG_NET, "receiving from socket failed!"); return JOB_REQUEUE_FAIR; @@ -353,22 +361,25 @@ static job_requeue_t receive_packets(private_receiver_t *this) { DBG1(DBG_NET, "using receive delay: %dms", this->receive_delay); - charon->scheduler->schedule_job_ms(charon->scheduler, + lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)process_message_job_create(message), this->receive_delay); return JOB_REQUEUE_DIRECT; } } } - charon->processor->queue_job(charon->processor, - (job_t*)process_message_job_create(message)); + lib->processor->queue_job(lib->processor, + (job_t*)process_message_job_create(message)); return JOB_REQUEUE_DIRECT; } METHOD(receiver_t, destroy, void, private_receiver_t *this) { - this->job->cancel(this->job); + if (this->job) + { + this->job->cancel(this->job); + } this->rng->destroy(this->rng); this->hasher->destroy(this->hasher); free(this); @@ -383,7 +394,9 @@ receiver_t *receiver_create() u_int32_t now = time_monotonic(NULL); INIT(this, - .public.destroy = _destroy, + .public = { + .destroy = _destroy, + }, .secret_switch = now, .secret_offset = random() % now, ); @@ -424,7 +437,7 @@ receiver_t *receiver_create() this->job = callback_job_create((callback_job_cb_t)receive_packets, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; } diff --git a/src/libcharon/network/sender.c b/src/libcharon/network/sender.c index bb6d50605..4177fb3e1 100644 --- a/src/libcharon/network/sender.c +++ b/src/libcharon/network/sender.c @@ -195,7 +195,7 @@ sender_t * sender_create() "charon.send_delay_response", TRUE), ); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; } diff --git a/src/libcharon/network/socket.h b/src/libcharon/network/socket.h index 5c5a4edfb..51b26920f 100644 --- a/src/libcharon/network/socket.h +++ b/src/libcharon/network/socket.h @@ -1,6 +1,7 @@ /* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger + * Copyright (C) 2006-2010 Tobias Brunner * Copyright (C) 2005-2010 Martin Willi + * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -30,6 +31,11 @@ typedef struct socket_t socket_t; #include <utils/enumerator.h> /** + * Constructor prototype for sockets. + */ +typedef socket_t *(*socket_constructor_t)(); + +/** * Socket interface definition. */ struct socket_t { @@ -42,8 +48,8 @@ struct socket_t { * * @param packet pinter gets address from allocated packet_t * @return - * - SUCCESS when packet successfully received - * - FAILED when unable to receive + * - SUCCESS when packet successfully received + * - FAILED when unable to receive */ status_t (*receive) (socket_t *this, packet_t **packet); @@ -55,10 +61,15 @@ struct socket_t { * * @param packet packet_t to send * @return - * - SUCCESS when packet successfully sent - * - FAILED when unable to send + * - SUCCESS when packet successfully sent + * - FAILED when unable to send */ status_t (*send) (socket_t *this, packet_t *packet); + + /** + * Destroy a socket implementation. + */ + void (*destroy) (socket_t *this); }; #endif /** SOCKET_H_ @}*/ diff --git a/src/libcharon/network/socket_manager.c b/src/libcharon/network/socket_manager.c index 0dbce4b1b..72a454301 100644 --- a/src/libcharon/network/socket_manager.c +++ b/src/libcharon/network/socket_manager.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2010 Tobias Brunner + * Hochschule fuer Technik Rapperswil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -33,11 +35,21 @@ struct private_socket_manager_t { socket_manager_t public; /** - * List of registered socket + * List of registered socket constructors */ linked_list_t *sockets; /** + * Instantiated socket implementation + */ + socket_t *socket; + + /** + * The constructor used to create the current socket + */ + socket_constructor_t create; + + /** * Lock for sockets list */ rwlock_t *lock; @@ -46,11 +58,9 @@ struct private_socket_manager_t { METHOD(socket_manager_t, receiver, status_t, private_socket_manager_t *this, packet_t **packet) { - socket_t *socket; status_t status; - this->lock->read_lock(this->lock); - if (this->sockets->get_first(this->sockets, (void**)&socket) != SUCCESS) + if (!this->socket) { DBG1(DBG_NET, "no socket implementation registered, receiving failed"); this->lock->unlock(this->lock); @@ -58,7 +68,7 @@ METHOD(socket_manager_t, receiver, status_t, } /* receive is blocking and the thread can be cancelled */ thread_cleanup_push((thread_cleanup_t)this->lock->unlock, this->lock); - status = socket->receive(socket, packet); + status = this->socket->receive(this->socket, packet); thread_cleanup_pop(TRUE); return status; } @@ -66,40 +76,67 @@ METHOD(socket_manager_t, receiver, status_t, METHOD(socket_manager_t, sender, status_t, private_socket_manager_t *this, packet_t *packet) { - socket_t *socket; status_t status; - this->lock->read_lock(this->lock); - if (this->sockets->get_first(this->sockets, (void**)&socket) != SUCCESS) + if (!this->socket) { DBG1(DBG_NET, "no socket implementation registered, sending failed"); this->lock->unlock(this->lock); return NOT_SUPPORTED; } - status = socket->send(socket, packet); + status = this->socket->send(this->socket, packet); this->lock->unlock(this->lock); return status; } +static void create_socket(private_socket_manager_t *this) +{ + socket_constructor_t create; + /* remove constructors in order to avoid trying to create broken ones + * multiple times */ + while (this->sockets->remove_first(this->sockets, + (void**)&create) == SUCCESS) + { + this->socket = create(); + if (this->socket) + { + this->create = create; + break; + } + } +} + METHOD(socket_manager_t, add_socket, void, - private_socket_manager_t *this, socket_t *socket) + private_socket_manager_t *this, socket_constructor_t create) { this->lock->write_lock(this->lock); - this->sockets->insert_last(this->sockets, socket); + this->sockets->insert_last(this->sockets, create); + if (!this->socket) + { + create_socket(this); + } this->lock->unlock(this->lock); } METHOD(socket_manager_t, remove_socket, void, - private_socket_manager_t *this, socket_t *socket) + private_socket_manager_t *this, socket_constructor_t create) { this->lock->write_lock(this->lock); - this->sockets->remove(this->sockets, socket, NULL); + this->sockets->remove(this->sockets, create, NULL); + if (this->create == create) + { + this->socket->destroy(this->socket); + this->socket = NULL; + this->create = NULL; + create_socket(this); + } this->lock->unlock(this->lock); } METHOD(socket_manager_t, destroy, void, private_socket_manager_t *this) { + DESTROY_IF(this->socket); this->sockets->destroy(this->sockets); this->lock->destroy(this->lock); free(this); diff --git a/src/libcharon/network/socket_manager.h b/src/libcharon/network/socket_manager.h index b33d5c71c..94185d21c 100644 --- a/src/libcharon/network/socket_manager.h +++ b/src/libcharon/network/socket_manager.h @@ -1,4 +1,6 @@ /* + * Copyright (C) 2010 Tobias Brunner + * Hochschule fuer Technik Rapperswil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -51,14 +53,18 @@ struct socket_manager_t { status_t (*send) (socket_manager_t *this, packet_t *packet); /** - * Register a socket implementation. + * Register a socket constructor. + * + * @param create constructor for the socket */ - void (*add_socket)(socket_manager_t *this, socket_t *socket); + void (*add_socket)(socket_manager_t *this, socket_constructor_t create); /** - * Unregister a registered socket implementation. + * Unregister a registered socket constructor. + * + * @param create constructor for the socket */ - void (*remove_socket)(socket_manager_t *this, socket_t *socket); + void (*remove_socket)(socket_manager_t *this, socket_constructor_t create); /** * Destroy a socket_manager_t. diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in index 4cb047929..426d1a689 100644 --- a/src/libcharon/plugins/addrblock/Makefile.in +++ b/src/libcharon/plugins/addrblock/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/addrblock/addrblock_plugin.c b/src/libcharon/plugins/addrblock/addrblock_plugin.c index 1c407035d..5fdb36c5c 100644 --- a/src/libcharon/plugins/addrblock/addrblock_plugin.c +++ b/src/libcharon/plugins/addrblock/addrblock_plugin.c @@ -61,7 +61,11 @@ plugin_t *addrblock_plugin_create() private_addrblock_plugin_t *this; INIT(this, - .public.plugin.destroy = _destroy, + .public = { + .plugin = { + .destroy = _destroy, + }, + }, .validator = addrblock_validator_create(), .narrower = addrblock_narrow_create(), ); diff --git a/src/libcharon/plugins/android/Makefile.in b/src/libcharon/plugins/android/Makefile.in index 6e4903ee1..d80868798 100644 --- a/src/libcharon/plugins/android/Makefile.in +++ b/src/libcharon/plugins/android/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/android/android_plugin.c b/src/libcharon/plugins/android/android_plugin.c index e2c8572ef..3d82d8f60 100644 --- a/src/libcharon/plugins/android/android_plugin.c +++ b/src/libcharon/plugins/android/android_plugin.c @@ -79,8 +79,10 @@ plugin_t *android_plugin_create() private_android_plugin_t *this; INIT(this, - .public.plugin = { - .destroy = _destroy, + .public = { + .plugin = { + .destroy = _destroy, + }, }, .logger = android_logger_create(), .handler = android_handler_create(), diff --git a/src/libcharon/plugins/android/android_service.c b/src/libcharon/plugins/android/android_service.c index 538c4a9a2..f9a8e1ea1 100644 --- a/src/libcharon/plugins/android/android_service.c +++ b/src/libcharon/plugins/android/android_service.c @@ -141,7 +141,7 @@ METHOD(listener_t, child_updown, bool, * callback, but from a different thread. we also delay it to avoid * a race condition during a regular shutdown */ job = callback_job_create(shutdown_callback, NULL, NULL, NULL); - charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, 1); + lib->scheduler->schedule_job(lib->scheduler, (job_t*)job, 1); return FALSE; } } @@ -378,7 +378,7 @@ android_service_t *android_service_create(android_creds_t *creds) charon->bus->add_listener(charon->bus, &this->public.listener); this->job = callback_job_create((callback_job_cb_t)initiate, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; } diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in index b34654fb7..e843c42e8 100644 --- a/src/libcharon/plugins/dhcp/Makefile.in +++ b/src/libcharon/plugins/dhcp/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -165,6 +166,8 @@ 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@ @@ -196,14 +199,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -243,7 +256,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/dhcp/dhcp_plugin.c b/src/libcharon/plugins/dhcp/dhcp_plugin.c index 829fd6356..fccc99ba5 100644 --- a/src/libcharon/plugins/dhcp/dhcp_plugin.c +++ b/src/libcharon/plugins/dhcp/dhcp_plugin.c @@ -62,7 +62,11 @@ plugin_t *dhcp_plugin_create() private_dhcp_plugin_t *this; INIT(this, - .public.plugin.destroy = _destroy, + .public = { + .plugin = { + .destroy = _destroy, + }, + }, .socket = dhcp_socket_create(), ); diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c index f61b3a60e..e1e83d648 100644 --- a/src/libcharon/plugins/dhcp/dhcp_socket.c +++ b/src/libcharon/plugins/dhcp/dhcp_socket.c @@ -31,6 +31,7 @@ #include <threading/condvar.h> #include <threading/thread.h> +#include <hydra.h> #include <daemon.h> #include <processing/jobs/callback_job.h> @@ -205,8 +206,8 @@ static int prepare_dhcp(private_dhcp_socket_t *this, else { /* act as relay agent */ - src = charon->kernel_interface->get_source_addr( - charon->kernel_interface, this->dst, NULL); + src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, + this->dst, NULL); if (src) { memcpy(&dhcp->gateway_address, src->get_address(src).ptr, @@ -462,8 +463,6 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen) offer = host_create_from_chunk(AF_INET, chunk_from_thing(dhcp->your_address), 0); - server = host_create_from_chunk(AF_INET, - chunk_from_thing(dhcp->server_address), DHCP_SERVER_PORT); this->mutex->lock(this->mutex); enumerator = this->discover->create_enumerator(this->discover); @@ -471,11 +470,8 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen) { if (transaction->get_id(transaction) == dhcp->transaction_id) { - DBG1(DBG_CFG, "received DHCP OFFER %H from %H", offer, server); this->discover->remove_at(this->discover, enumerator); this->request->insert_last(this->request, transaction); - transaction->set_address(transaction, offer->clone(offer)); - transaction->set_server(transaction, server->clone(server)); break; } } @@ -504,9 +500,22 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen) chunk_create((char*)&option->data[pos], 4)); } } + if (option->type == DHCP_SERVER_ID && option->len == 4) + { + server = host_create_from_chunk(AF_INET, + chunk_create(option->data, 4), DHCP_SERVER_PORT); + } optlen -= optsize; optpos += optsize; } + if (!server) + { + server = host_create_from_chunk(AF_INET, + chunk_from_thing(dhcp->server_address), DHCP_SERVER_PORT); + } + DBG1(DBG_CFG, "received DHCP OFFER %H from %H", offer, server); + transaction->set_address(transaction, offer->clone(offer)); + transaction->set_server(transaction, server->clone(server)); } this->mutex->unlock(this->mutex); this->condvar->broadcast(this->condvar); @@ -751,7 +760,7 @@ dhcp_socket_t *dhcp_socket_create() this->job = callback_job_create((callback_job_cb_t)receive_dhcp, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; } diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in index 14bf3f15d..c0750786d 100644 --- a/src/libcharon/plugins/eap_aka/Makefile.in +++ b/src/libcharon/plugins/eap_aka/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in index b41b59616..41f69546e 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in +++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -169,6 +170,8 @@ 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@ @@ -200,14 +203,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -222,24 +228,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -247,7 +260,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in index 57952f621..02d659197 100644 --- a/src/libcharon/plugins/eap_gtc/Makefile.in +++ b/src/libcharon/plugins/eap_gtc/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -166,6 +167,8 @@ 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@ @@ -197,14 +200,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -219,24 +225,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -244,7 +257,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in index d78957438..46011694a 100644 --- a/src/libcharon/plugins/eap_identity/Makefile.in +++ b/src/libcharon/plugins/eap_identity/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_identity/eap_identity.c b/src/libcharon/plugins/eap_identity/eap_identity.c index ab082a955..03066b2f8 100644 --- a/src/libcharon/plugins/eap_identity/eap_identity.c +++ b/src/libcharon/plugins/eap_identity/eap_identity.c @@ -59,11 +59,8 @@ struct eap_identity_header_t { u_int8_t data[]; } __attribute__((__packed__)); -/** - * Implementation of eap_method_t.process for the peer - */ -static status_t process_peer(private_eap_identity_t *this, - eap_payload_t *in, eap_payload_t **out) +METHOD(eap_method_t, process_peer, status_t, + private_eap_identity_t *this, eap_payload_t *in, eap_payload_t **out) { chunk_t id; eap_identity_header_t *hdr; @@ -74,7 +71,7 @@ static status_t process_peer(private_eap_identity_t *this, hdr = alloca(len); hdr->code = EAP_RESPONSE; - hdr->identifier = in->get_identifier(in); + hdr->identifier = in ? in->get_identifier(in) : 0; hdr->length = htons(len); hdr->type = EAP_IDENTITY; memcpy(hdr->data, id.ptr, id.len); @@ -83,20 +80,15 @@ static status_t process_peer(private_eap_identity_t *this, return SUCCESS; } -/** - * Implementation of eap_method_t.initiate for the peer - */ -static status_t initiate_peer(private_eap_identity_t *this, eap_payload_t **out) +METHOD(eap_method_t, initiate_peer, status_t, + private_eap_identity_t *this, eap_payload_t **out) { /* peer never initiates */ return FAILED; } -/** - * Implementation of eap_method_t.process for the server - */ -static status_t process_server(private_eap_identity_t *this, - eap_payload_t *in, eap_payload_t **out) +METHOD(eap_method_t, process_server, status_t, + private_eap_identity_t *this, eap_payload_t *in, eap_payload_t **out) { chunk_t data; @@ -108,10 +100,8 @@ static status_t process_server(private_eap_identity_t *this, return SUCCESS; } -/** - * Implementation of eap_method_t.initiate for the server - */ -static status_t initiate_server(private_eap_identity_t *this, eap_payload_t **out) +METHOD(eap_method_t, initiate_server, status_t, + private_eap_identity_t *this, eap_payload_t **out) { eap_identity_header_t hdr; @@ -125,19 +115,15 @@ static status_t initiate_server(private_eap_identity_t *this, eap_payload_t **ou return NEED_MORE; } -/** - * Implementation of eap_method_t.get_type. - */ -static eap_type_t get_type(private_eap_identity_t *this, u_int32_t *vendor) +METHOD(eap_method_t, get_type, eap_type_t, + private_eap_identity_t *this, u_int32_t *vendor) { *vendor = 0; return EAP_IDENTITY; } -/** - * Implementation of eap_method_t.get_msk. - */ -static status_t get_msk(private_eap_identity_t *this, chunk_t *msk) +METHOD(eap_method_t, get_msk, status_t, + private_eap_identity_t *this, chunk_t *msk) { if (this->identity.ptr) { @@ -147,56 +133,42 @@ static status_t get_msk(private_eap_identity_t *this, chunk_t *msk) return FAILED; } -/** - * Implementation of eap_method_t.is_mutual. - */ -static bool is_mutual(private_eap_identity_t *this) +METHOD(eap_method_t, is_mutual, bool, + private_eap_identity_t *this) { return FALSE; } -/** - * Implementation of eap_method_t.destroy. - */ -static void destroy(private_eap_identity_t *this) +METHOD(eap_method_t, destroy, void, + private_eap_identity_t *this) { this->peer->destroy(this->peer); free(this->identity.ptr); free(this); } -/** - * Generic constructor - */ -static private_eap_identity_t *eap_identity_create(identification_t *server, - identification_t *peer) -{ - private_eap_identity_t *this = malloc_thing(private_eap_identity_t); - - this->public.eap_method_interface.initiate = NULL; - this->public.eap_method_interface.process = NULL; - this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type; - this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual; - this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk; - this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy; - - this->peer = peer->clone(peer); - this->identity = chunk_empty; - - return this; -} - /* * Described in header. */ eap_identity_t *eap_identity_create_peer(identification_t *server, identification_t *peer) { - private_eap_identity_t *this = eap_identity_create(server, peer); - - /* public functions */ - this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer; - this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer; + private_eap_identity_t *this; + + INIT(this, + .public = { + .eap_method = { + .initiate = _initiate_peer, + .process = _process_peer, + .get_type = _get_type, + .is_mutual = _is_mutual, + .get_msk = _get_msk, + .destroy = _destroy, + }, + }, + .peer = peer->clone(peer), + .identity = chunk_empty, + ); return &this->public; } @@ -207,11 +179,22 @@ eap_identity_t *eap_identity_create_peer(identification_t *server, eap_identity_t *eap_identity_create_server(identification_t *server, identification_t *peer) { - private_eap_identity_t *this = eap_identity_create(server, peer); - - /* public functions */ - this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server; - this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server; + private_eap_identity_t *this; + + INIT(this, + .public = { + .eap_method = { + .initiate = _initiate_server, + .process = _process_server, + .get_type = _get_type, + .is_mutual = _is_mutual, + .get_msk = _get_msk, + .destroy = _destroy, + }, + }, + .peer = peer->clone(peer), + .identity = chunk_empty, + ); return &this->public; } diff --git a/src/libcharon/plugins/eap_identity/eap_identity.h b/src/libcharon/plugins/eap_identity/eap_identity.h index 7364a8bda..9a7f28574 100644 --- a/src/libcharon/plugins/eap_identity/eap_identity.h +++ b/src/libcharon/plugins/eap_identity/eap_identity.h @@ -33,7 +33,7 @@ struct eap_identity_t { /** * Implemented eap_method_t interface. */ - eap_method_t eap_method_interface; + eap_method_t eap_method; }; /** diff --git a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c index 082997154..079c27909 100644 --- a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c +++ b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c @@ -14,15 +14,12 @@ */ #include "eap_identity_plugin.h" - #include "eap_identity.h" #include <daemon.h> -/** - * Implementation of plugin_t.destroy - */ -static void destroy(eap_identity_plugin_t *this) +METHOD(plugin_t, destroy, void, + eap_identity_plugin_t *this) { charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_identity_create_server); @@ -36,9 +33,13 @@ static void destroy(eap_identity_plugin_t *this) */ plugin_t *eap_identity_plugin_create() { - eap_identity_plugin_t *this = malloc_thing(eap_identity_plugin_t); + eap_identity_plugin_t *this; - this->plugin.destroy = (void(*)(plugin_t*))destroy; + INIT(this, + .plugin = { + .destroy = _destroy, + }, + ); charon->eap->add_method(charon->eap, EAP_IDENTITY, 0, EAP_SERVER, (eap_constructor_t)eap_identity_create_server); diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in index 5bfc59fa4..2e307147f 100644 --- a/src/libcharon/plugins/eap_md5/Makefile.in +++ b/src/libcharon/plugins/eap_md5/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -166,6 +167,8 @@ 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@ @@ -197,14 +200,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -219,24 +225,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -244,7 +257,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_md5/eap_md5.c b/src/libcharon/plugins/eap_md5/eap_md5.c index 3554ae12e..f70754abb 100644 --- a/src/libcharon/plugins/eap_md5/eap_md5.c +++ b/src/libcharon/plugins/eap_md5/eap_md5.c @@ -47,7 +47,7 @@ struct private_eap_md5_t { chunk_t challenge; /** - * EAP message identififier + * EAP message identifier */ u_int8_t identifier; }; @@ -105,19 +105,15 @@ static status_t hash_challenge(private_eap_md5_t *this, chunk_t *response, return SUCCESS; } -/** - * Implementation of eap_method_t.initiate for the peer - */ -static status_t initiate_peer(private_eap_md5_t *this, eap_payload_t **out) +METHOD(eap_method_t, initiate_peer, status_t, + private_eap_md5_t *this, eap_payload_t **out) { /* peer never initiates */ return FAILED; } -/** - * Implementation of eap_method_t.initiate for the server - */ -static status_t initiate_server(private_eap_md5_t *this, eap_payload_t **out) +METHOD(eap_method_t, initiate_server, status_t, + private_eap_md5_t *this, eap_payload_t **out) { rng_t *rng; eap_md5_header_t *req; @@ -142,11 +138,8 @@ static status_t initiate_server(private_eap_md5_t *this, eap_payload_t **out) return NEED_MORE; } -/** - * Implementation of eap_method_t.process for the peer - */ -static status_t process_peer(private_eap_md5_t *this, - eap_payload_t *in, eap_payload_t **out) +METHOD(eap_method_t, process_peer, status_t, + private_eap_md5_t *this, eap_payload_t *in, eap_payload_t **out) { chunk_t response; chunk_t data; @@ -177,11 +170,8 @@ static status_t process_peer(private_eap_md5_t *this, return NEED_MORE; } -/** - * Implementation of eap_method_t.process for the server - */ -static status_t process_server(private_eap_md5_t *this, - eap_payload_t *in, eap_payload_t **out) +METHOD(eap_method_t, process_server, status_t, + private_eap_md5_t *this, eap_payload_t *in, eap_payload_t **out) { chunk_t response, expected; chunk_t data; @@ -209,35 +199,27 @@ static status_t process_server(private_eap_md5_t *this, return SUCCESS; } -/** - * Implementation of eap_method_t.get_type. - */ -static eap_type_t get_type(private_eap_md5_t *this, u_int32_t *vendor) +METHOD(eap_method_t, get_type, eap_type_t, + private_eap_md5_t *this, u_int32_t *vendor) { *vendor = 0; return EAP_MD5; } -/** - * Implementation of eap_method_t.get_msk. - */ -static status_t get_msk(private_eap_md5_t *this, chunk_t *msk) +METHOD(eap_method_t, get_msk, status_t, + private_eap_md5_t *this, chunk_t *msk) { return FAILED; } -/** - * Implementation of eap_method_t.is_mutual. - */ -static bool is_mutual(private_eap_md5_t *this) +METHOD(eap_method_t, is_mutual, bool, + private_eap_md5_t *this) { return FALSE; } -/** - * Implementation of eap_method_t.destroy. - */ -static void destroy(private_eap_md5_t *this) +METHOD(eap_method_t, destroy, void, + private_eap_md5_t *this) { this->peer->destroy(this->peer); this->server->destroy(this->server); @@ -245,39 +227,27 @@ static void destroy(private_eap_md5_t *this) free(this); } -/** - * Generic constructor - */ -static private_eap_md5_t *eap_md5_create_generic(identification_t *server, - identification_t *peer) -{ - private_eap_md5_t *this = malloc_thing(private_eap_md5_t); - - this->public.eap_method_interface.initiate = NULL; - this->public.eap_method_interface.process = NULL; - this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type; - this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual; - this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk; - this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy; - - /* private data */ - this->peer = peer->clone(peer); - this->server = server->clone(server); - this->challenge = chunk_empty; - this->identifier = 0; - - return this; -} - /* - * see header + * See header */ eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *peer) { - private_eap_md5_t *this = eap_md5_create_generic(server, peer); - - this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server; - this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server; + private_eap_md5_t *this; + + INIT(this, + .public = { + .eap_method = { + .initiate = _initiate_server, + .process = _process_server, + .get_type = _get_type, + .is_mutual = _is_mutual, + .get_msk = _get_msk, + .destroy = _destroy, + }, + }, + .peer = peer->clone(peer), + .server = server->clone(server), + ); /* generate a non-zero identifier */ do { @@ -288,14 +258,26 @@ eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *pee } /* - * see header + * See header */ eap_md5_t *eap_md5_create_peer(identification_t *server, identification_t *peer) { - private_eap_md5_t *this = eap_md5_create_generic(server, peer); - - this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer; - this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer; + private_eap_md5_t *this; + + INIT(this, + .public = { + .eap_method = { + .initiate = _initiate_peer, + .process = _process_peer, + .get_type = _get_type, + .is_mutual = _is_mutual, + .get_msk = _get_msk, + .destroy = _destroy, + }, + }, + .peer = peer->clone(peer), + .server = server->clone(server), + ); return &this->public; } diff --git a/src/libcharon/plugins/eap_md5/eap_md5.h b/src/libcharon/plugins/eap_md5/eap_md5.h index 3cff0dd79..c6687149a 100644 --- a/src/libcharon/plugins/eap_md5/eap_md5.h +++ b/src/libcharon/plugins/eap_md5/eap_md5.h @@ -33,7 +33,7 @@ struct eap_md5_t { /** * Implemented eap_method_t interface. */ - eap_method_t eap_method_interface; + eap_method_t eap_method; }; /** diff --git a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c index e716dc6e8..39a6f5731 100644 --- a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c +++ b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c @@ -14,15 +14,12 @@ */ #include "eap_md5_plugin.h" - #include "eap_md5.h" #include <daemon.h> -/** - * Implementation of plugin_t.destroy - */ -static void destroy(eap_md5_plugin_t *this) +METHOD(plugin_t, destroy, void, + eap_md5_plugin_t *this) { charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_md5_create_server); @@ -36,9 +33,13 @@ static void destroy(eap_md5_plugin_t *this) */ plugin_t *eap_md5_plugin_create() { - eap_md5_plugin_t *this = malloc_thing(eap_md5_plugin_t); + eap_md5_plugin_t *this; - this->plugin.destroy = (void(*)(plugin_t*))destroy; + INIT(this, + .plugin = { + .destroy = _destroy, + }, + ); charon->eap->add_method(charon->eap, EAP_MD5, 0, EAP_SERVER, (eap_constructor_t)eap_md5_create_server); diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in index d61cc9e5d..635cfe6ec 100644 --- a/src/libcharon/plugins/eap_mschapv2/Makefile.in +++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c index 3cd8d994c..4f39c8608 100644 --- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c +++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c @@ -818,7 +818,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, retryable; + int message_len, error = 0, retriable; chunk_t challenge = chunk_empty; data = in->get_data(in); @@ -847,7 +847,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this, else if (strneq(token, "R=", 2)) { token += 2; - retryable = atoi(token); + retriable = atoi(token); } else if (strneq(token, "C=", 2)) { @@ -880,17 +880,17 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this, mschapv2_error_names, error, sanitize(msg)); /** - * at this point, if the error is retryable, we MAY retry the authentication + * at this point, if the error is retriable, we MAY retry the authentication * or MAY send a Change Password packet. * - * if the error is not retryable (or if we do neither of the above), we + * if the error is not retriable (or if we do neither of the above), we * SHOULD send a Failure Response packet. * windows clients don't do that, and since windows server 2008 r2 behaves * pretty odd if we do send a Failure Response, we just don't send one * either. windows 7 actually sends a delete notify (which, according to the * logs, results in an error on windows server 2008 r2). * - * btw, windows server 2008 r2 does not send non-retryable errors for e.g. + * btw, windows server 2008 r2 does not send non-retriable errors for e.g. * a disabled account but returns the windows error code in a notify payload * of type 12345. */ diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in index bb372d13c..1d771d9a4 100644 --- a/src/libcharon/plugins/eap_radius/Makefile.in +++ b/src/libcharon/plugins/eap_radius/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -169,6 +170,8 @@ 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@ @@ -200,14 +203,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -222,24 +228,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -247,7 +260,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c index 65b868bc6..157034fe5 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius.c +++ b/src/libcharon/plugins/eap_radius/eap_radius.c @@ -20,6 +20,8 @@ #include <daemon.h> +#define TUNNEL_TYPE_ESP 9 + typedef struct private_eap_radius_t private_eap_radius_t; /** @@ -71,6 +73,11 @@ struct private_eap_radius_t { * Handle the Class attribute as group membership information? */ bool class_group; + + /** + * Handle the Filter-Id attribute as IPsec CHILD_SA name? + */ + bool filter_id; }; /** @@ -211,6 +218,62 @@ static void process_class(private_eap_radius_t *this, radius_message_t *msg) enumerator->destroy(enumerator); } +/** + * Handle the Filter-Id attribute as IPsec CHILD_SA name + */ +static void process_filter_id(private_eap_radius_t *this, radius_message_t *msg) +{ + enumerator_t *enumerator; + int type; + u_int8_t tunnel_tag; + u_int32_t tunnel_type; + chunk_t filter_id = chunk_empty, data; + bool is_esp_tunnel = FALSE; + + enumerator = msg->create_enumerator(msg); + while (enumerator->enumerate(enumerator, &type, &data)) + { + switch (type) + { + case RAT_TUNNEL_TYPE: + if (data.len != 4) + { + continue; + } + tunnel_tag = *data.ptr; + *data.ptr = 0x00; + 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); + break; + case RAT_FILTER_ID: + filter_id = data; + DBG1(DBG_IKE, "received RADIUS attribute Filter-Id: " + "'%.*s'", filter_id.len, filter_id.ptr); + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + if (is_esp_tunnel && filter_id.len) + { + identification_t *id; + ike_sa_t *ike_sa; + auth_cfg_t *auth; + + ike_sa = charon->bus->get_sa(charon->bus); + if (ike_sa) + { + auth = ike_sa->get_auth_cfg(ike_sa, FALSE); + id = identification_create_from_data(filter_id); + auth->add(auth, AUTH_RULE_GROUP, id); + } + } +} + METHOD(eap_method_t, process, status_t, private_eap_radius_t *this, eap_payload_t *in, eap_payload_t **out) { @@ -247,12 +310,17 @@ METHOD(eap_method_t, process, status_t, { process_class(this, response); } + if (this->filter_id) + { + process_filter_id(this, response); + } + DBG1(DBG_IKE, "RADIUS authentication of '%Y' successful", + this->peer); status = SUCCESS; break; case RMC_ACCESS_REJECT: default: - DBG1(DBG_CFG, "received %N from RADIUS server", - radius_message_code_names, response->get_code(response)); + DBG1(DBG_IKE, "RADIUS authentication of '%Y' failed", this->peer); status = FAILED; break; } @@ -313,13 +381,15 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer private_eap_radius_t *this; INIT(this, - .public.eap_method_interface = { - .initiate = _initiate, - .process = _process, - .get_type = _get_type, - .is_mutual = _is_mutual, - .get_msk = _get_msk, - .destroy = _destroy, + .public = { + .eap_method = { + .initiate = _initiate, + .process = _process, + .get_type = _get_type, + .is_mutual = _is_mutual, + .get_msk = _get_msk, + .destroy = _destroy, + }, }, /* initially EAP_RADIUS, but is set to the method selected by RADIUS */ .type = EAP_RADIUS, @@ -329,6 +399,9 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer "charon.plugins.eap-radius.id_prefix", ""), .class_group = lib->settings->get_bool(lib->settings, "charon.plugins.eap-radius.class_group", FALSE), + .filter_id = lib->settings->get_bool(lib->settings, + "charon.plugins.eap-radius.filter_id", FALSE), + ); this->client = radius_client_create(); if (!this->client) diff --git a/src/libcharon/plugins/eap_radius/eap_radius.h b/src/libcharon/plugins/eap_radius/eap_radius.h index 8eb9e8c2d..e98cb06e3 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius.h +++ b/src/libcharon/plugins/eap_radius/eap_radius.h @@ -33,7 +33,7 @@ struct eap_radius_t { /** * Implemented eap_method_t interface. */ - eap_method_t eap_method_interface; + eap_method_t eap_method; }; /** diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c index 91aae2f62..1c24d77d5 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c @@ -151,7 +151,11 @@ plugin_t *eap_radius_plugin_create() private_eap_radius_plugin_t *this; INIT(this, - .public.plugin.destroy = _destroy, + .public = { + .plugin = { + .destroy = _destroy, + }, + }, .servers = linked_list_create(), ); diff --git a/src/libcharon/plugins/eap_radius/radius_server.h b/src/libcharon/plugins/eap_radius/radius_server.h index b820cb583..ba4c94619 100644 --- a/src/libcharon/plugins/eap_radius/radius_server.h +++ b/src/libcharon/plugins/eap_radius/radius_server.h @@ -79,6 +79,7 @@ struct radius_server_t { * @param server 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 */ diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in index d0f44e925..d05930bbd 100644 --- a/src/libcharon/plugins/eap_sim/Makefile.in +++ b/src/libcharon/plugins/eap_sim/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in index 2aa0ac832..46a584265 100644 --- a/src/libcharon/plugins/eap_sim_file/Makefile.in +++ b/src/libcharon/plugins/eap_sim_file/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -169,6 +170,8 @@ 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@ @@ -200,14 +203,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -222,24 +228,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -247,7 +260,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in index 7d80f8019..2d8556a59 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -170,6 +171,8 @@ 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@ @@ -201,14 +204,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -223,24 +229,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -248,7 +261,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in index fc26f4497..e59015f82 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -169,6 +170,8 @@ 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@ @@ -200,14 +203,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -222,24 +228,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -247,7 +260,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in index f2e82df0a..3c66d2f36 100644 --- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ 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 0f5319792..1cc5352d8 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 @@ -85,8 +85,10 @@ plugin_t *eap_simaka_sql_plugin_create() "charon.plugins.eap-simaka-sql.remove_used", FALSE); INIT(this, - .public.plugin = { - .destroy = _destroy, + .public = { + .plugin = { + .destroy = _destroy, + }, }, .db = db, .provider = eap_simaka_sql_provider_create(db, remove_used), diff --git a/src/libcharon/plugins/eap_tls/Makefile.am b/src/libcharon/plugins/eap_tls/Makefile.am new file mode 100644 index 000000000..29ddd822b --- /dev/null +++ b/src/libcharon/plugins/eap_tls/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/libtls + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-eap-tls.la +else +plugin_LTLIBRARIES = libstrongswan-eap-tls.la +libstrongswan_eap_tls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +endif + +libstrongswan_eap_tls_la_SOURCES = \ + eap_tls_plugin.h eap_tls_plugin.c eap_tls.h eap_tls.c + +libstrongswan_eap_tls_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in new file mode 100644 index 000000000..e4b78faf8 --- /dev/null +++ b/src/libcharon/plugins/eap_tls/Makefile.in @@ -0,0 +1,605 @@ +# 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/eap_tls +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_eap_tls_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la +am_libstrongswan_eap_tls_la_OBJECTS = eap_tls_plugin.lo eap_tls.lo +libstrongswan_eap_tls_la_OBJECTS = \ + $(am_libstrongswan_eap_tls_la_OBJECTS) +libstrongswan_eap_tls_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_eap_tls_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_eap_tls_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_eap_tls_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_eap_tls_la_SOURCES) +DIST_SOURCES = $(libstrongswan_eap_tls_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@ +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@ +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@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ +ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ +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@ +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@ +srcdir = @srcdir@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +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/libtls + +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-tls.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-tls.la +@MONOLITHIC_FALSE@libstrongswan_eap_tls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +libstrongswan_eap_tls_la_SOURCES = \ + eap_tls_plugin.h eap_tls_plugin.c eap_tls.h eap_tls.c + +libstrongswan_eap_tls_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/eap_tls/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/eap_tls/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-eap-tls.la: $(libstrongswan_eap_tls_la_OBJECTS) $(libstrongswan_eap_tls_la_DEPENDENCIES) + $(libstrongswan_eap_tls_la_LINK) $(am_libstrongswan_eap_tls_la_rpath) $(libstrongswan_eap_tls_la_OBJECTS) $(libstrongswan_eap_tls_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_tls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_tls_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/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c new file mode 100644 index 000000000..efe72c437 --- /dev/null +++ b/src/libcharon/plugins/eap_tls/eap_tls.c @@ -0,0 +1,155 @@ +/* + * 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 "eap_tls.h" + +#include <tls_eap.h> + +#include <daemon.h> +#include <library.h> + +typedef struct private_eap_tls_t private_eap_tls_t; + +/** + * Private data of an eap_tls_t object. + */ +struct private_eap_tls_t { + + /** + * Public interface. + */ + eap_tls_t public; + + /** + * TLS stack, wrapped by EAP helper + */ + tls_eap_t *tls_eap; +}; + +/** Maximum number of EAP-TLS messages/fragments allowed */ +#define MAX_MESSAGE_COUNT 32 +/** Default size of a EAP-TLS fragment */ +#define MAX_FRAGMENT_LEN 1024 + +METHOD(eap_method_t, initiate, status_t, + private_eap_tls_t *this, eap_payload_t **out) +{ + chunk_t data; + + if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE) + { + *out = eap_payload_create_data(data); + free(data.ptr); + return NEED_MORE; + } + return FAILED; +} + +METHOD(eap_method_t, process, status_t, + private_eap_tls_t *this, eap_payload_t *in, eap_payload_t **out) +{ + status_t status; + chunk_t data; + + data = in->get_data(in); + status = this->tls_eap->process(this->tls_eap, data, &data); + if (status == NEED_MORE) + { + *out = eap_payload_create_data(data); + free(data.ptr); + } + return status; +} + +METHOD(eap_method_t, get_type, eap_type_t, + private_eap_tls_t *this, u_int32_t *vendor) +{ + *vendor = 0; + return EAP_TLS; +} + +METHOD(eap_method_t, get_msk, status_t, + private_eap_tls_t *this, chunk_t *msk) +{ + *msk = this->tls_eap->get_msk(this->tls_eap); + if (msk->len) + { + return SUCCESS; + } + return FAILED; +} + +METHOD(eap_method_t, is_mutual, bool, + private_eap_tls_t *this) +{ + return TRUE; +} + +METHOD(eap_method_t, destroy, void, + private_eap_tls_t *this) +{ + this->tls_eap->destroy(this->tls_eap); + free(this); +} + +/** + * Generic private constructor + */ +static eap_tls_t *eap_tls_create(identification_t *server, + identification_t *peer, bool is_server) +{ + private_eap_tls_t *this; + size_t frag_size; + int max_msg_count; + tls_t *tls; + + INIT(this, + .public = { + .eap_method = { + .initiate = _initiate, + .process = _process, + .get_type = _get_type, + .is_mutual = _is_mutual, + .get_msk = _get_msk, + .destroy = _destroy, + }, + }, + ); + + frag_size = lib->settings->get_int(lib->settings, + "charon.plugins.eap-tls.fragment_size", MAX_FRAGMENT_LEN); + max_msg_count = lib->settings->get_int(lib->settings, + "charon.plugins.eap-tls.max_message_count", MAX_MESSAGE_COUNT); + tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL); + this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count); + if (!this->tls_eap) + { + free(this); + return NULL; + } + return &this->public; +} + +eap_tls_t *eap_tls_create_server(identification_t *server, + identification_t *peer) +{ + return eap_tls_create(server, peer, TRUE); +} + +eap_tls_t *eap_tls_create_peer(identification_t *server, + identification_t *peer) +{ + return eap_tls_create(server, peer, FALSE); +} diff --git a/src/libcharon/plugins/eap_tls/eap_tls.h b/src/libcharon/plugins/eap_tls/eap_tls.h new file mode 100644 index 000000000..7e080230a --- /dev/null +++ b/src/libcharon/plugins/eap_tls/eap_tls.h @@ -0,0 +1,59 @@ +/* + * 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 eap_tls_i eap_tls + * @{ @ingroup eap_tls + */ + +#ifndef EAP_TLS_H_ +#define EAP_TLS_H_ + +typedef struct eap_tls_t eap_tls_t; + +#include <sa/authenticators/eap/eap_method.h> + +/** + * Implementation of eap_method_t using EAP-TLS. + */ +struct eap_tls_t { + + /** + * Implements eap_method_t interface. + */ + eap_method_t eap_method; +}; + +/** + * Creates the EAP method EAP-TLS acting as server. + * + * @param server ID of the EAP server + * @param peer ID of the EAP client + * @return eap_tls_t object + */ +eap_tls_t *eap_tls_create_server(identification_t *server, + identification_t *peer); + +/** + * Creates the EAP method EAP-TLS acting as peer. + * + * @param server ID of the EAP server + * @param peer ID of the EAP client + * @return eap_tls_t object + */ +eap_tls_t *eap_tls_create_peer(identification_t *server, + identification_t *peer); + +#endif /** EAP_TLS_H_ @}*/ diff --git a/src/libcharon/plugins/eap_tls/eap_tls_plugin.c b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c new file mode 100644 index 000000000..a7c040bf4 --- /dev/null +++ b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c @@ -0,0 +1,52 @@ +/* + * 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 "eap_tls_plugin.h" + +#include "eap_tls.h" + +#include <daemon.h> + + +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); +} + +/* + * see header file + */ +plugin_t *eap_tls_plugin_create() +{ + eap_tls_plugin_t *this; + + INIT(this, + .plugin = { + .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/kernel_netlink/kernel_netlink_plugin.h b/src/libcharon/plugins/eap_tls/eap_tls_plugin.h index 74c9ae24f..5ea719603 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h +++ b/src/libcharon/plugins/eap_tls/eap_tls_plugin.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2008 Tobias Brunner - * Hochschule fuer Technik Rapperswil + * 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 @@ -14,24 +14,24 @@ */ /** - * @defgroup kernel_netlink kernel_netlink + * @defgroup eap_tls eap_tls * @ingroup cplugins * - * @defgroup kernel_netlink_plugin kernel_netlink_plugin - * @{ @ingroup kernel_netlink + * @defgroup eap_tls_plugin eap_tls_plugin + * @{ @ingroup eap_tls */ -#ifndef KERNEL_NETLINK_PLUGIN_H_ -#define KERNEL_NETLINK_PLUGIN_H_ +#ifndef EAP_TLS_PLUGIN_H_ +#define EAP_TLS_PLUGIN_H_ #include <plugins/plugin.h> -typedef struct kernel_netlink_plugin_t kernel_netlink_plugin_t; +typedef struct eap_tls_plugin_t eap_tls_plugin_t; /** - * netlink kernel interface plugin + * EAP-TLS plugin */ -struct kernel_netlink_plugin_t { +struct eap_tls_plugin_t { /** * implements plugin interface @@ -39,4 +39,9 @@ struct kernel_netlink_plugin_t { plugin_t plugin; }; -#endif /** KERNEL_NETLINK_PLUGIN_H_ @}*/ +/** + * Create a eap_tls_plugin instance. + */ +plugin_t *eap_tls_plugin_create(); + +#endif /** EAP_TLS_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/eap_tnc/Makefile.am b/src/libcharon/plugins/eap_tnc/Makefile.am new file mode 100644 index 000000000..9c5a445c5 --- /dev/null +++ b/src/libcharon/plugins/eap_tnc/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/libtls + +AM_CFLAGS = -rdynamic + +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 +endif + +libstrongswan_eap_tnc_la_SOURCES = \ + eap_tnc_plugin.h eap_tnc_plugin.c eap_tnc.h eap_tnc.c + +libstrongswan_eap_tnc_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in new file mode 100644 index 000000000..fb7108a8a --- /dev/null +++ b/src/libcharon/plugins/eap_tnc/Makefile.in @@ -0,0 +1,605 @@ +# 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/eap_tnc +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_eap_tnc_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.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) +libstrongswan_eap_tnc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_eap_tnc_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_eap_tnc_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_eap_tnc_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_eap_tnc_la_SOURCES) +DIST_SOURCES = $(libstrongswan_eap_tnc_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@ +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@ +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@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ +ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ +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@ +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@ +srcdir = @srcdir@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +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/libtls + +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 +libstrongswan_eap_tnc_la_SOURCES = \ + eap_tnc_plugin.h eap_tnc_plugin.c eap_tnc.h eap_tnc.c + +libstrongswan_eap_tnc_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/eap_tnc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/eap_tnc/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-eap-tnc.la: $(libstrongswan_eap_tnc_la_OBJECTS) $(libstrongswan_eap_tnc_la_DEPENDENCIES) + $(libstrongswan_eap_tnc_la_LINK) $(am_libstrongswan_eap_tnc_la_rpath) $(libstrongswan_eap_tnc_la_OBJECTS) $(libstrongswan_eap_tnc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_tnc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_tnc_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/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c new file mode 100644 index 000000000..f0bff0e1f --- /dev/null +++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c @@ -0,0 +1,156 @@ +/* + * 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 "eap_tnc.h" + +#include <tls_eap.h> + +#include <daemon.h> +#include <library.h> + +typedef struct private_eap_tnc_t private_eap_tnc_t; + +/** + * Private data of an eap_tnc_t object. + */ +struct private_eap_tnc_t { + + /** + * Public authenticator_t interface. + */ + eap_tnc_t public; + + /** + * TLS stack, wrapped by EAP helper + */ + tls_eap_t *tls_eap; +}; + + +/** Maximum number of EAP-TNC messages/fragments allowed */ +#define MAX_MESSAGE_COUNT 10 +/** Default size of a EAP-TNC fragment */ +#define MAX_FRAGMENT_LEN 50000 + +METHOD(eap_method_t, initiate, status_t, + private_eap_tnc_t *this, eap_payload_t **out) +{ + chunk_t data; + + if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE) + { + *out = eap_payload_create_data(data); + free(data.ptr); + return NEED_MORE; + } + return FAILED; +} + +METHOD(eap_method_t, process, status_t, + private_eap_tnc_t *this, eap_payload_t *in, eap_payload_t **out) +{ + status_t status; + chunk_t data; + + data = in->get_data(in); + status = this->tls_eap->process(this->tls_eap, data, &data); + if (status == NEED_MORE) + { + *out = eap_payload_create_data(data); + free(data.ptr); + } + return status; +} + +METHOD(eap_method_t, get_type, eap_type_t, + private_eap_tnc_t *this, u_int32_t *vendor) +{ + *vendor = 0; + return EAP_TNC; +} + +METHOD(eap_method_t, get_msk, status_t, + private_eap_tnc_t *this, chunk_t *msk) +{ + *msk = this->tls_eap->get_msk(this->tls_eap); + if (msk->len) + { + return SUCCESS; + } + return FAILED; +} + +METHOD(eap_method_t, is_mutual, bool, + private_eap_tnc_t *this) +{ + return FALSE; +} + +METHOD(eap_method_t, destroy, void, + private_eap_tnc_t *this) +{ + this->tls_eap->destroy(this->tls_eap); + free(this); +} + +/** + * Generic private constructor + */ +static eap_tnc_t *eap_tnc_create(identification_t *server, + identification_t *peer, bool is_server) +{ + private_eap_tnc_t *this; + size_t frag_size; + int max_msg_count; + tnccs_t *tnccs; + + INIT(this, + .public = { + .eap_method = { + .initiate = _initiate, + .process = _process, + .get_type = _get_type, + .is_mutual = _is_mutual, + .get_msk = _get_msk, + .destroy = _destroy, + }, + }, + ); + + frag_size = lib->settings->get_int(lib->settings, + "charon.plugins.eap-tnc.fragment_size", MAX_FRAGMENT_LEN); + max_msg_count = lib->settings->get_int(lib->settings, + "charon.plugins.eap-tnc.max_message_count", MAX_MESSAGE_COUNT); + tnccs = charon->tnccs->create_instance(charon->tnccs, TNCCS_1_1, is_server); + this->tls_eap = tls_eap_create(EAP_TNC, (tls_t*)tnccs, frag_size, max_msg_count); + if (!this->tls_eap) + { + free(this); + return NULL; + } + return &this->public; +} + +eap_tnc_t *eap_tnc_create_server(identification_t *server, + identification_t *peer) +{ + return eap_tnc_create(server, peer, TRUE); +} + +eap_tnc_t *eap_tnc_create_peer(identification_t *server, + identification_t *peer) +{ + return eap_tnc_create(server, peer, FALSE); +} diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.h b/src/libcharon/plugins/eap_tnc/eap_tnc.h new file mode 100644 index 000000000..7e166fb60 --- /dev/null +++ b/src/libcharon/plugins/eap_tnc/eap_tnc.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * 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 eap_tnc_i eap_tnc + * @{ @ingroup eap_tnc + */ + +#ifndef EAP_TNC_H_ +#define EAP_TNC_H_ + +typedef struct eap_tnc_t eap_tnc_t; + +#include <sa/authenticators/eap/eap_method.h> + +/** + * Implementation of the eap_method_t interface using EAP-TNC. + */ +struct eap_tnc_t { + + /** + * Implemented eap_method_t interface. + */ + eap_method_t eap_method; +}; + +/** + * Creates the EAP method EAP-TNC acting as server. + * + * @param server ID of the EAP server + * @param peer ID of the EAP client + * @return eap_tnc_t object + */ +eap_tnc_t *eap_tnc_create_server(identification_t *server, identification_t *peer); + +/** + * Creates the EAP method EAP-TNC acting as peer. + * + * @param server ID of the EAP server + * @param peer ID of the EAP client + * @return eap_tnc_t object + */ +eap_tnc_t *eap_tnc_create_peer(identification_t *server, identification_t *peer); + +#endif /** EAP_TNC_H_ @}*/ diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c new file mode 100644 index 000000000..7430e4cac --- /dev/null +++ b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * 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 "eap_tnc_plugin.h" +#include "eap_tnc.h" + +#include <daemon.h> + +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); +} + +/* + * see header file + */ +plugin_t *eap_tnc_plugin_create() +{ + eap_tnc_plugin_t *this; + + INIT(this, + .plugin = { + .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/kernel_pfkey/kernel_pfkey_plugin.h b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.h index ecccc6303..97298eb5c 100644 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h +++ b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2010 Andreas Steffen * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,24 +14,24 @@ */ /** - * @defgroup kernel_pfkey kernel_pfkey + * @defgroup eap_tnc eap_tnc * @ingroup cplugins * - * @defgroup kernel_pfkey_plugin kernel_pfkey_plugin - * @{ @ingroup kernel_pfkey + * @defgroup eap_tnc_plugin eap_tnc_plugin + * @{ @ingroup eap_tnc */ -#ifndef KERNEL_PFKEY_PLUGIN_H_ -#define KERNEL_PFKEY_PLUGIN_H_ +#ifndef EAP_TNC_PLUGIN_H_ +#define EAP_TNC_PLUGIN_H_ #include <plugins/plugin.h> -typedef struct kernel_pfkey_plugin_t kernel_pfkey_plugin_t; +typedef struct eap_tnc_plugin_t eap_tnc_plugin_t; /** - * PF_KEY kernel interface plugin + * EAP-TNC plugin */ -struct kernel_pfkey_plugin_t { +struct eap_tnc_plugin_t { /** * implements plugin interface @@ -39,4 +39,4 @@ struct kernel_pfkey_plugin_t { plugin_t plugin; }; -#endif /** KERNEL_PFKEY_PLUGIN_H_ @}*/ +#endif /** EAP_TNC_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/eap_ttls/Makefile.am b/src/libcharon/plugins/eap_ttls/Makefile.am new file mode 100644 index 000000000..94ce5cc1e --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/Makefile.am @@ -0,0 +1,21 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-eap-ttls.la +else +plugin_LTLIBRARIES = libstrongswan-eap-ttls.la +libstrongswan_eap_ttls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +endif + +libstrongswan_eap_ttls_la_SOURCES = \ + eap_ttls_plugin.h eap_ttls_plugin.c \ + eap_ttls_avp.h eap_ttls_avp.c \ + eap_ttls.h eap_ttls.c \ + eap_ttls_peer.h eap_ttls_peer.c \ + eap_ttls_server.h eap_ttls_server.c + +libstrongswan_eap_ttls_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in new file mode 100644 index 000000000..2cdd7701d --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/Makefile.in @@ -0,0 +1,615 @@ +# 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/eap_ttls +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_eap_ttls_la_DEPENDENCIES = \ +@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la +am_libstrongswan_eap_ttls_la_OBJECTS = eap_ttls_plugin.lo \ + eap_ttls_avp.lo eap_ttls.lo eap_ttls_peer.lo \ + eap_ttls_server.lo +libstrongswan_eap_ttls_la_OBJECTS = \ + $(am_libstrongswan_eap_ttls_la_OBJECTS) +libstrongswan_eap_ttls_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_eap_ttls_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_eap_ttls_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_eap_ttls_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_eap_ttls_la_SOURCES) +DIST_SOURCES = $(libstrongswan_eap_ttls_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@ +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@ +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@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ +ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ +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@ +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@ +srcdir = @srcdir@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +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/libtls + +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-ttls.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-ttls.la +@MONOLITHIC_FALSE@libstrongswan_eap_ttls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la +libstrongswan_eap_ttls_la_SOURCES = \ + eap_ttls_plugin.h eap_ttls_plugin.c \ + eap_ttls_avp.h eap_ttls_avp.c \ + eap_ttls.h eap_ttls.c \ + eap_ttls_peer.h eap_ttls_peer.c \ + eap_ttls_server.h eap_ttls_server.c + +libstrongswan_eap_ttls_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/eap_ttls/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/eap_ttls/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-eap-ttls.la: $(libstrongswan_eap_ttls_la_OBJECTS) $(libstrongswan_eap_ttls_la_DEPENDENCIES) + $(libstrongswan_eap_ttls_la_LINK) $(am_libstrongswan_eap_ttls_la_rpath) $(libstrongswan_eap_ttls_la_OBJECTS) $(libstrongswan_eap_ttls_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls_avp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls_peer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls_server.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/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c new file mode 100644 index 000000000..a62af6ea4 --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2010 Martin Willi, revosec AG + * 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 "eap_ttls.h" +#include "eap_ttls_peer.h" +#include "eap_ttls_server.h" + +#include <tls_eap.h> + +#include <daemon.h> +#include <library.h> + +typedef struct private_eap_ttls_t private_eap_ttls_t; + +/** + * Private data of an eap_ttls_t object. + */ +struct private_eap_ttls_t { + + /** + * Public interface. + */ + eap_ttls_t public; + + /** + * TLS stack, wrapped by EAP helper + */ + tls_eap_t *tls_eap; +}; + +/** Maximum number of EAP-TTLS messages/fragments allowed */ +#define MAX_MESSAGE_COUNT 32 +/** Default size of a EAP-TTLS fragment */ +#define MAX_FRAGMENT_LEN 1024 + +METHOD(eap_method_t, initiate, status_t, + private_eap_ttls_t *this, eap_payload_t **out) +{ + chunk_t data; + + if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE) + { + *out = eap_payload_create_data(data); + free(data.ptr); + return NEED_MORE; + } + return FAILED; +} + +METHOD(eap_method_t, process, status_t, + private_eap_ttls_t *this, eap_payload_t *in, eap_payload_t **out) +{ + status_t status; + chunk_t data; + + data = in->get_data(in); + status = this->tls_eap->process(this->tls_eap, data, &data); + if (status == NEED_MORE) + { + *out = eap_payload_create_data(data); + free(data.ptr); + } + return status; +} + +METHOD(eap_method_t, get_type, eap_type_t, + private_eap_ttls_t *this, u_int32_t *vendor) +{ + *vendor = 0; + return EAP_TTLS; +} + +METHOD(eap_method_t, get_msk, status_t, + private_eap_ttls_t *this, chunk_t *msk) +{ + *msk = this->tls_eap->get_msk(this->tls_eap); + if (msk->len) + { + return SUCCESS; + } + return FAILED; +} + +METHOD(eap_method_t, is_mutual, bool, + private_eap_ttls_t *this) +{ + return TRUE; +} + +METHOD(eap_method_t, destroy, void, + private_eap_ttls_t *this) +{ + this->tls_eap->destroy(this->tls_eap); + free(this); +} + +/** + * Generic private constructor + */ +static eap_ttls_t *eap_ttls_create(identification_t *server, + identification_t *peer, bool is_server, + tls_application_t *application) +{ + private_eap_ttls_t *this; + size_t frag_size; + int max_msg_count; + tls_t *tls; + + INIT(this, + .public = { + .eap_method = { + .initiate = _initiate, + .process = _process, + .get_type = _get_type, + .is_mutual = _is_mutual, + .get_msk = _get_msk, + .destroy = _destroy, + }, + }, + ); + if (is_server && !lib->settings->get_bool(lib->settings, + "charon.plugins.eap-ttls.request_peer_auth", FALSE)) + { + peer = NULL; + } + frag_size = lib->settings->get_int(lib->settings, + "charon.plugins.eap-ttls.fragment_size", MAX_FRAGMENT_LEN); + max_msg_count = lib->settings->get_int(lib->settings, + "charon.plugins.eap-ttls.max_message_count", MAX_MESSAGE_COUNT); + tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application); + this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size, max_msg_count); + if (!this->tls_eap) + { + application->destroy(application); + free(this); + return NULL; + } + return &this->public; +} + +eap_ttls_t *eap_ttls_create_server(identification_t *server, + identification_t *peer) +{ + return eap_ttls_create(server, peer, TRUE, + &eap_ttls_server_create(server, peer)->application); +} + +eap_ttls_t *eap_ttls_create_peer(identification_t *server, + identification_t *peer) +{ + return eap_ttls_create(server, peer, FALSE, + &eap_ttls_peer_create(server, peer)->application); +} diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.h b/src/libcharon/plugins/eap_ttls/eap_ttls.h new file mode 100644 index 000000000..6e3bf2ceb --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 eap_ttls_i eap_ttls + * @{ @ingroup eap_ttls + */ + +#ifndef EAP_TTLS_H_ +#define EAP_TTLS_H_ + +typedef struct eap_ttls_t eap_ttls_t; + +#include <sa/authenticators/eap/eap_method.h> + +/** + * Implementation of eap_method_t using EAP-TTLS. + */ +struct eap_ttls_t { + + /** + * Implements eap_method_t interface. + */ + eap_method_t eap_method; +}; + +/** + * Creates the EAP method EAP-TTLS acting as server. + * + * @param server ID of the EAP server + * @param peer ID of the EAP client + * @return eap_ttls_t object + */ +eap_ttls_t *eap_ttls_create_server(identification_t *server, + identification_t *peer); + +/** + * Creates the EAP method EAP-TTLS acting as peer. + * + * @param server ID of the EAP server + * @param peer ID of the EAP client + * @return eap_ttls_t object + */ +eap_ttls_t *eap_ttls_create_peer(identification_t *server, + identification_t *peer); + +#endif /** EAP_TTLS_H_ @}*/ diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c new file mode 100644 index 000000000..0eb5e94be --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 "eap_ttls_avp.h" + +#include <debug.h> + +#define AVP_EAP_MESSAGE 79 +#define AVP_HEADER_LEN 8 + +typedef struct private_eap_ttls_avp_t private_eap_ttls_avp_t; + +/** + * Private data of an eap_ttls_avp_t object. + */ +struct private_eap_ttls_avp_t { + + /** + * Public eap_ttls_avp_t interface. + */ + eap_ttls_avp_t public; + + /** + * AVP input buffer + */ + chunk_t input; + + /** + * Position in input buffer + */ + size_t inpos; + + /** + * process header (TRUE) or body (FALSE) + */ + bool process_header; + + /** + * Size of AVP data + */ + size_t data_len; +}; + +METHOD(eap_ttls_avp_t, build, void, + private_eap_ttls_avp_t *this, tls_writer_t *writer, chunk_t data) +{ + char zero_padding[] = { 0x00, 0x00, 0x00 }; + chunk_t avp_padding; + u_int8_t avp_flags; + u_int32_t avp_len; + + avp_flags = 0x40; + avp_len = 8 + data.len; + avp_padding = chunk_create(zero_padding, (4 - data.len) % 4); + + writer->write_uint32(writer, AVP_EAP_MESSAGE); + writer->write_uint8(writer, avp_flags); + writer->write_uint24(writer, avp_len); + writer->write_data(writer, data); + writer->write_data(writer, avp_padding); +} + +METHOD(eap_ttls_avp_t, process, status_t, + private_eap_ttls_avp_t* this, tls_reader_t *reader, chunk_t *data) +{ + size_t len; + chunk_t buf; + + if (this->process_header) + { + tls_reader_t *header; + u_int32_t avp_code; + u_int8_t avp_flags; + u_int32_t avp_len; + bool success; + + len = min(reader->remaining(reader), AVP_HEADER_LEN - this->inpos); + if (!reader->read_data(reader, len, &buf)) + { + return FAILED; + } + if (this->input.len == 0) + { + /* start of a new AVP header */ + this->input = chunk_alloc(AVP_HEADER_LEN); + memcpy(this->input.ptr, buf.ptr, len); + this->inpos = len; + } + else + { + memcpy(this->input.ptr + this->inpos, buf.ptr, len); + this->inpos += len; + } + + if (this->inpos < AVP_HEADER_LEN) + { + return NEED_MORE; + } + + /* parse AVP header */ + header = tls_reader_create(this->input); + success = header->read_uint32(header, &avp_code) && + header->read_uint8(header, &avp_flags) && + header->read_uint24(header, &avp_len); + header->destroy(header); + chunk_free(&this->input); + this->inpos = 0; + + if (!success) + { + DBG1(DBG_IKE, "received invalid AVP header"); + return FAILED; + } + if (avp_code != AVP_EAP_MESSAGE) + { + DBG1(DBG_IKE, "expected AVP_EAP_MESSAGE but received %u", avp_code); + return FAILED; + } + this->process_header = FALSE; + this->data_len = avp_len - 8; + this->input = chunk_alloc(this->data_len + (4 - avp_len) % 4); + } + + /* process AVP data */ + len = min(reader->remaining(reader), this->input.len - this->inpos); + if (!reader->read_data(reader, len, &buf)) + { + return FAILED; + } + memcpy(this->input.ptr + this->inpos, buf.ptr, len); + this->inpos += len; + if (this->inpos < this->input.len) + { + return NEED_MORE; + } + + *data = this->input; + data->len = this->data_len; + + /* preparing for next AVP */ + this->input = chunk_empty; + this->inpos = 0; + this->process_header = TRUE; + + return SUCCESS; +} + +METHOD(eap_ttls_avp_t, destroy, void, + private_eap_ttls_avp_t *this) +{ + chunk_free(&this->input); + free(this); +} + +/** + * See header + */ +eap_ttls_avp_t *eap_ttls_avp_create(void) +{ + private_eap_ttls_avp_t *this; + + INIT(this, + .public= { + .process = _process, + .build = _build, + .destroy = _destroy, + }, + .input = chunk_empty, + .inpos = 0, + .process_header = TRUE, + .data_len = 0, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h new file mode 100644 index 000000000..cad1d9c56 --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 eap_ttls_avp eap_ttls_avp + * @{ @ingroup eap_ttls + */ + +#ifndef EAP_TTLS_AVP_H_ +#define EAP_TTLS_AVP_H_ + +typedef struct eap_ttls_avp_t eap_ttls_avp_t; + +#include <library.h> + +#include <tls_reader.h> +#include <tls_writer.h> + +/** + * EAP-TTLS Attribute-Value Pair (AVP) handler. + */ +struct eap_ttls_avp_t { + + /** + * Process received EAP-TTLS EAP Message AVP. + * + * @param reader TLS data buffer + * @param data received EAP Message + * @return + * - SUCCESS if AVP processing succeeded + * - 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, + chunk_t *data); + + /** + * Build EAP-TTLS EAP Message AVP to send out. + * + * @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); + + /** + * Destroy a eap_ttls_application_t. + */ + void (*destroy)(eap_ttls_avp_t *this); +}; + +/** + * Create an eap_ttls_avp instance. + */ +eap_ttls_avp_t *eap_ttls_avp_create(void); + +#endif /** EAP_TTLS_AVP_H_ @}*/ diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c new file mode 100644 index 000000000..10d08ca2a --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 "eap_ttls_peer.h" +#include "eap_ttls_avp.h" + +#include <debug.h> +#include <daemon.h> + +#include <sa/authenticators/eap/eap_method.h> + +typedef struct private_eap_ttls_peer_t private_eap_ttls_peer_t; + +/** + * Private data of an eap_ttls_peer_t object. + */ +struct private_eap_ttls_peer_t { + + /** + * Public eap_ttls_peer_t interface. + */ + eap_ttls_peer_t public; + + /** + * Server identity + */ + identification_t *server; + + /** + * Peer identity + */ + identification_t *peer; + + /** + * Current EAP-TTLS state + */ + bool start_phase2; + + /** + * Current phase 2 EAP method + */ + eap_method_t *method; + + /** + * Pending outbound EAP message + */ + eap_payload_t *out; + + /** + * AVP handler + */ + eap_ttls_avp_t *avp; +}; + +/** + * EAP packet format + */ +typedef struct __attribute__((packed)) { + u_int8_t code; + u_int8_t identifier; + u_int16_t length; + u_int8_t type; + u_int8_t data; +} eap_packet_t; + +#define MAX_RADIUS_ATTRIBUTE_SIZE 253 + +METHOD(tls_application_t, process, status_t, + private_eap_ttls_peer_t *this, tls_reader_t *reader) +{ + chunk_t avp_data = chunk_empty; + chunk_t eap_data = chunk_empty; + status_t status; + payload_t *payload; + eap_payload_t *in; + eap_packet_t *pkt; + eap_code_t code; + eap_type_t type, received_type; + u_int32_t vendor, received_vendor; + u_int16_t eap_len; + size_t eap_pos = 0; + bool concatenated = FALSE; + + do + { + status = this->avp->process(this->avp, reader, &avp_data); + switch (status) + { + case SUCCESS: + break; + case NEED_MORE: + DBG1(DBG_IKE, "need more AVP data"); + return NEED_MORE; + case FAILED: + default: + return FAILED; + } + + if (eap_data.len == 0) + { + if (avp_data.len < 4) + { + DBG1(DBG_IKE, "AVP size to small to contain EAP header"); + chunk_free(&avp_data); + return FAILED; + } + pkt = (eap_packet_t*)avp_data.ptr; + eap_len = untoh16(&pkt->length); + + if (eap_len <= avp_data.len) + { + /* standard: EAP packet contained in a single AVP */ + eap_data = avp_data; + break; + } + else if (avp_data.len == MAX_RADIUS_ATTRIBUTE_SIZE) + { + /* non-standard: EAP packet segmented into multiple AVPs */ + eap_data = chunk_alloc(eap_len); + concatenated = TRUE; + } + else + { + DBG1(DBG_IKE, "non-radius segmentation of EAP packet into AVPs"); + chunk_free(&avp_data); + return FAILED; + } + } + + if (avp_data.len > eap_data.len - eap_pos) + { + DBG1(DBG_IKE, "AVP size to large to fit into EAP packet"); + chunk_free(&avp_data); + chunk_free(&eap_data); + return FAILED; + } + memcpy(eap_data.ptr + eap_pos, avp_data.ptr, avp_data.len); + eap_pos += avp_data.len; + chunk_free(&avp_data); + } + while (eap_pos < eap_data.len); + + in = eap_payload_create_data(eap_data); + chunk_free(&eap_data); + payload = (payload_t*)in; + + if (payload->verify(payload) != SUCCESS) + { + in->destroy(in); + return FAILED; + } + code = in->get_code(in); + received_type = in->get_type(in, &received_vendor); + DBG1(DBG_IKE, "received tunneled EAP-TTLS AVP%s [EAP/%N/%N]", + concatenated ? "s" : "", + eap_code_short_names, code, + eap_type_short_names, received_type); + if (code != EAP_REQUEST) + { + DBG1(DBG_IKE, "%N expected", eap_code_names, EAP_REQUEST); + in->destroy(in); + return FAILED; + } + + if (this->method == NULL) + { + if (received_vendor) + { + DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d", + received_type, received_vendor); + } + else + { + DBG1(DBG_IKE, "server requested %N authentication", + eap_type_names, received_type); + } + this->method = charon->eap->create_instance(charon->eap, + received_type, received_vendor, + EAP_PEER, this->server, this->peer); + if (!this->method) + { + DBG1(DBG_IKE, "EAP method not supported"); + this->out = eap_payload_create_nak(in->get_identifier(in)); + in->destroy(in); + return NEED_MORE; + } + } + + type = this->method->get_type(this->method, &vendor); + + if (type != received_type || vendor != received_vendor) + { + DBG1(DBG_IKE, "received invalid EAP request"); + in->destroy(in); + return FAILED; + } + + status = this->method->process(this->method, in, &this->out); + in->destroy(in); + + switch (status) + { + case SUCCESS: + this->method->destroy(this->method); + this->method = NULL; + return NEED_MORE; + case NEED_MORE: + if (type != EAP_TNC) + { + this->method->destroy(this->method); + this->method = NULL; + } + return NEED_MORE; + case FAILED: + default: + if (vendor) + { + DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed", + type, vendor); + } + else + { + DBG1(DBG_IKE, "%N method failed", eap_type_names, type); + } + return FAILED; + } +} + +METHOD(tls_application_t, build, status_t, + private_eap_ttls_peer_t *this, tls_writer_t *writer) +{ + chunk_t data; + eap_code_t code; + eap_type_t type; + u_int32_t vendor; + + if (this->method == NULL && this->start_phase2) + { + /* generate an EAP Identity response */ + this->method = charon->eap->create_instance(charon->eap, EAP_IDENTITY, + 0, EAP_PEER, this->server, this->peer); + if (this->method == NULL) + { + DBG1(DBG_IKE, "EAP_IDENTITY method not available"); + return FAILED; + } + this->method->process(this->method, NULL, &this->out); + this->method->destroy(this->method); + this->method = NULL; + this->start_phase2 = FALSE; + } + + if (this->out) + { + code = this->out->get_code(this->out); + type = this->out->get_type(this->out, &vendor); + DBG1(DBG_IKE, "sending tunneled EAP-TTLS AVP [EAP/%N/%N]", + eap_code_short_names, code, eap_type_short_names, type); + + /* get the raw EAP message data */ + data = this->out->get_data(this->out); + this->avp->build(this->avp, writer, data); + + this->out->destroy(this->out); + this->out = NULL; + } + return INVALID_STATE; +} + +METHOD(tls_application_t, destroy, void, + private_eap_ttls_peer_t *this) +{ + this->server->destroy(this->server); + this->peer->destroy(this->peer); + DESTROY_IF(this->method); + DESTROY_IF(this->out); + this->avp->destroy(this->avp); + free(this); +} + +/** + * See header + */ +eap_ttls_peer_t *eap_ttls_peer_create(identification_t *server, + identification_t *peer) +{ + private_eap_ttls_peer_t *this; + + INIT(this, + .public = { + .application = { + .process = _process, + .build = _build, + .destroy = _destroy, + }, + }, + .server = server->clone(server), + .peer = peer->clone(peer), + .start_phase2 = TRUE, + .avp = eap_ttls_avp_create(), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.h b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.h new file mode 100644 index 000000000..31fc0d9db --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 eap_ttls_peer eap_ttls_peer + * @{ @ingroup eap_ttls + */ + +#ifndef EAP_TTLS_PEER_H_ +#define EAP_TTLS_PEER_H_ + +typedef struct eap_ttls_peer_t eap_ttls_peer_t; + +#include "tls_application.h" + +#include <library.h> + +/** + * TLS application data handler as peer. + */ +struct eap_ttls_peer_t { + + /** + * Implements the TLS application data handler. + */ + tls_application_t application; +}; + +/** + * Create an eap_ttls_peer instance. + */ +eap_ttls_peer_t *eap_ttls_peer_create(identification_t *server, + identification_t *peer); + +#endif /** EAP_TTLS_PEER_H_ @}*/ diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c new file mode 100644 index 000000000..48e759dcc --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 "eap_ttls_plugin.h" + +#include "eap_ttls.h" + +#include <daemon.h> + + +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); +} + +/* + * see header file + */ +plugin_t *eap_ttls_plugin_create() +{ + eap_ttls_plugin_t *this; + + INIT(this, + .plugin = { + .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_plugin.h b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.h new file mode 100644 index 000000000..2abc82931 --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 eap_ttls eap_ttls + * @ingroup cplugins + * + * @defgroup eap_ttls_plugin eap_ttls_plugin + * @{ @ingroup eap_ttls + */ + +#ifndef EAP_TTLS_PLUGIN_H_ +#define EAP_TTLS_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct eap_ttls_plugin_t eap_ttls_plugin_t; + +/** + * EAP-TTLS plugin + */ +struct eap_ttls_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +/** + * Create a eap_ttls_plugin instance. + */ +plugin_t *eap_ttls_plugin_create(); + +#endif /** EAP_TTLS_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_server.c b/src/libcharon/plugins/eap_ttls/eap_ttls_server.c new file mode 100644 index 000000000..835cd7306 --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_server.c @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 "eap_ttls_server.h" +#include "eap_ttls_avp.h" + +#include <debug.h> +#include <daemon.h> + +#include <sa/authenticators/eap/eap_method.h> + +typedef struct private_eap_ttls_server_t private_eap_ttls_server_t; + +/** + * Private data of an eap_ttls_server_t object. + */ +struct private_eap_ttls_server_t { + + /** + * Public eap_ttls_server_t interface. + */ + eap_ttls_server_t public; + + /** + * Server identity + */ + identification_t *server; + + /** + * Peer identity + */ + identification_t *peer; + + /** + * Current EAP-TTLS phase2 state + */ + bool start_phase2; + + /** + * Current EAP-TTLS phase2 TNC state + */ + bool start_phase2_tnc; + + /** + * Current phase 2 EAP method + */ + eap_method_t *method; + + /** + * Pending outbound EAP message + */ + eap_payload_t *out; + + /** + * AVP handler + */ + eap_ttls_avp_t *avp; +}; + +/** + * Start EAP client authentication protocol + */ +static status_t start_phase2_auth(private_eap_ttls_server_t *this) +{ + char *eap_type_str; + eap_type_t type; + + eap_type_str = lib->settings->get_str(lib->settings, + "charon.plugins.eap-ttls.phase2_method", "md5"); + type = eap_type_from_string(eap_type_str); + if (type == 0) + { + DBG1(DBG_IKE, "unrecognized phase2 method \"%s\"", eap_type_str); + return FAILED; + } + DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, type); + this->method = charon->eap->create_instance(charon->eap, type, 0, + EAP_SERVER, this->server, this->peer); + if (this->method == NULL) + { + DBG1(DBG_IKE, "%N method not available", eap_type_names, type); + return FAILED; + } + if (this->method->initiate(this->method, &this->out) == NEED_MORE) + { + return NEED_MORE; + } + else + { + DBG1(DBG_IKE, "%N method failed", eap_type_names, type); + return FAILED; + } +} + +/** + * If configured, start EAP-TNC protocol + */ +static status_t start_phase2_tnc(private_eap_ttls_server_t *this) +{ + if (this->start_phase2_tnc && lib->settings->get_bool(lib->settings, + "charon.plugins.eap-ttls.phase2_tnc", FALSE)) + { + DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, EAP_TNC); + this->method = charon->eap->create_instance(charon->eap, EAP_TNC, + 0, EAP_SERVER, this->server, this->peer); + if (this->method == NULL) + { + DBG1(DBG_IKE, "%N method not available", eap_type_names, EAP_TNC); + return FAILED; + } + this->start_phase2_tnc = FALSE; + if (this->method->initiate(this->method, &this->out) == NEED_MORE) + { + return NEED_MORE; + } + else + { + DBG1(DBG_IKE, "%N method failed", eap_type_names, EAP_TNC); + return FAILED; + } + } + return SUCCESS; +} + +METHOD(tls_application_t, process, status_t, + private_eap_ttls_server_t *this, tls_reader_t *reader) +{ + chunk_t data = chunk_empty; + status_t status; + payload_t *payload; + eap_payload_t *in; + eap_code_t code; + eap_type_t type = EAP_NAK, received_type; + u_int32_t vendor, received_vendor; + + status = this->avp->process(this->avp, reader, &data); + switch (status) + { + case SUCCESS: + break; + case NEED_MORE: + return NEED_MORE; + case FAILED: + default: + return FAILED; + } + in = eap_payload_create_data(data); + chunk_free(&data); + payload = (payload_t*)in; + + if (payload->verify(payload) != SUCCESS) + { + in->destroy(in); + return FAILED; + } + code = in->get_code(in); + received_type = in->get_type(in, &received_vendor); + DBG1(DBG_IKE, "received tunneled EAP-TTLS AVP [EAP/%N/%N]", + eap_code_short_names, code, + eap_type_short_names, received_type); + if (code != EAP_RESPONSE) + { + DBG1(DBG_IKE, "%N expected", eap_code_names, EAP_RESPONSE); + in->destroy(in); + return FAILED; + } + + if (this->method) + { + type = this->method->get_type(this->method, &vendor); + + if (type != received_type || vendor != received_vendor) + { + if (received_vendor == 0 && received_type == EAP_NAK) + { + DBG1(DBG_IKE, "peer does not support %N", eap_type_names, type); + } + else + { + DBG1(DBG_IKE, "received invalid EAP response"); + } + in->destroy(in); + return FAILED; + } + } + + if (!received_vendor && received_type == EAP_IDENTITY) + { + chunk_t eap_id; + + if (this->method == NULL) + { + /* Received an EAP Identity response without a matching request */ + this->method = charon->eap->create_instance(charon->eap, + EAP_IDENTITY, 0, EAP_SERVER, + this->server, this->peer); + if (this->method == NULL) + { + DBG1(DBG_IKE, "%N method not available", + eap_type_names, EAP_IDENTITY); + return FAILED; + } + } + + if (this->method->process(this->method, in, &this->out) != SUCCESS) + { + + DBG1(DBG_IKE, "%N method failed", eap_type_names, EAP_IDENTITY); + return FAILED; + } + + if (this->method->get_msk(this->method, &eap_id) == SUCCESS) + { + this->peer->destroy(this->peer); + this->peer = identification_create_from_data(eap_id); + DBG1(DBG_IKE, "received EAP identity '%Y'", this->peer); + } + + in->destroy(in); + this->method->destroy(this->method); + this->method = NULL; + + /* Start Phase 2 of EAP-TTLS authentication */ + if (lib->settings->get_bool(lib->settings, + "charon.plugins.eap-ttls.request_peer_auth", FALSE)) + { + return start_phase2_tnc(this); + } + else + { + return start_phase2_auth(this); + } + } + + if (this->method == 0) + { + DBG1(DBG_IKE, "no %N phase2 method installed", eap_type_names, EAP_TTLS); + in->destroy(in); + return FAILED; + } + + status = this->method->process(this->method, in, &this->out); + in->destroy(in); + + switch (status) + { + case SUCCESS: + DBG1(DBG_IKE, "%N phase2 authentication of '%Y' with %N successful", + eap_type_names, EAP_TTLS, this->peer, + eap_type_names, type); + this->method->destroy(this->method); + this->method = NULL; + + /* continue phase2 with EAP-TNC? */ + return start_phase2_tnc(this); + case NEED_MORE: + break; + case FAILED: + default: + if (vendor) + { + DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed", + type, vendor); + } + else + { + DBG1(DBG_IKE, "%N method failed", eap_type_names, type); + } + return FAILED; + } + return status; +} + +METHOD(tls_application_t, build, status_t, + private_eap_ttls_server_t *this, tls_writer_t *writer) +{ + chunk_t data; + eap_code_t code; + eap_type_t type; + u_int32_t vendor; + + if (this->method == NULL && this->start_phase2 && + lib->settings->get_bool(lib->settings, + "charon.plugins.eap-ttls.phase2_piggyback", FALSE)) + { + /* generate an EAP Identity request which will be piggybacked right + * onto the TLS Finished message thus initiating EAP-TTLS phase2 + */ + this->method = charon->eap->create_instance(charon->eap, EAP_IDENTITY, + 0, EAP_SERVER, this->server, this->peer); + if (this->method == NULL) + { + DBG1(DBG_IKE, "%N method not available", + eap_type_names, EAP_IDENTITY); + return FAILED; + } + this->method->initiate(this->method, &this->out); + this->start_phase2 = FALSE; + } + + if (this->out) + { + code = this->out->get_code(this->out); + type = this->out->get_type(this->out, &vendor); + DBG1(DBG_IKE, "sending tunneled EAP-TTLS AVP [EAP/%N/%N]", + eap_code_short_names, code, eap_type_short_names, type); + + /* get the raw EAP message data */ + data = this->out->get_data(this->out); + this->avp->build(this->avp, writer, data); + + this->out->destroy(this->out); + this->out = NULL; + } + return INVALID_STATE; +} + +METHOD(tls_application_t, destroy, void, + private_eap_ttls_server_t *this) +{ + this->server->destroy(this->server); + this->peer->destroy(this->peer); + DESTROY_IF(this->method); + DESTROY_IF(this->out); + this->avp->destroy(this->avp); + free(this); +} + +/** + * See header + */ +eap_ttls_server_t *eap_ttls_server_create(identification_t *server, + identification_t *peer) +{ + private_eap_ttls_server_t *this; + + INIT(this, + .public = { + .application = { + .process = _process, + .build = _build, + .destroy = _destroy, + }, + }, + .server = server->clone(server), + .peer = peer->clone(peer), + .start_phase2 = TRUE, + .start_phase2_tnc = TRUE, + .avp = eap_ttls_avp_create(), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_server.h b/src/libcharon/plugins/eap_ttls/eap_ttls_server.h new file mode 100644 index 000000000..a66a813ec --- /dev/null +++ b/src/libcharon/plugins/eap_ttls/eap_ttls_server.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010 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 eap_ttls_server eap_ttls_server + * @{ @ingroup eap_ttls + */ + +#ifndef EAP_TTLS_SERVER_H_ +#define EAP_TTLS_SERVER_H_ + +typedef struct eap_ttls_server_t eap_ttls_server_t; + +#include "tls_application.h" + +#include <library.h> + +/** + * TLS application data handler as server. + */ +struct eap_ttls_server_t { + + /** + * Implements the TLS application data handler. + */ + tls_application_t application; +}; + +/** + * Create an eap_ttls_server instance. + */ +eap_ttls_server_t *eap_ttls_server_create(identification_t *server, + identification_t *peer); + +#endif /** EAP_TTLS_SERVER_H_ @}*/ diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in index 47952b99e..bfd50d6da 100644 --- a/src/libcharon/plugins/farp/Makefile.in +++ b/src/libcharon/plugins/farp/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -165,6 +166,8 @@ 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@ @@ -196,14 +199,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -243,7 +256,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/farp/farp_plugin.c b/src/libcharon/plugins/farp/farp_plugin.c index 01c2a39c8..d83bc1fd2 100644 --- a/src/libcharon/plugins/farp/farp_plugin.c +++ b/src/libcharon/plugins/farp/farp_plugin.c @@ -60,7 +60,11 @@ plugin_t *farp_plugin_create() private_farp_plugin_t *this; INIT(this, - .public.plugin.destroy = _destroy, + .public = { + .plugin = { + .destroy = _destroy, + }, + }, .listener = farp_listener_create(), ); diff --git a/src/libcharon/plugins/farp/farp_spoofer.c b/src/libcharon/plugins/farp/farp_spoofer.c index 20bb44fd3..a904a6538 100644 --- a/src/libcharon/plugins/farp/farp_spoofer.c +++ b/src/libcharon/plugins/farp/farp_spoofer.c @@ -191,7 +191,7 @@ farp_spoofer_t *farp_spoofer_create(farp_listener_t *listener) this->job = callback_job_create((callback_job_cb_t)receive_arp, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; } diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in index 5ca9b464b..3600eb7c6 100644 --- a/src/libcharon/plugins/ha/Makefile.in +++ b/src/libcharon/plugins/ha/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -167,6 +168,8 @@ 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@ @@ -198,14 +201,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -220,24 +226,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -245,7 +258,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c index 1ebc33ca4..9ff3fd5ff 100644 --- a/src/libcharon/plugins/ha/ha_cache.c +++ b/src/libcharon/plugins/ha/ha_cache.c @@ -354,7 +354,7 @@ ha_cache_t *ha_cache_create(ha_kernel_t *kernel, ha_socket_t *socket, if (sync) { /* request a resync as soon as we are up */ - charon->scheduler->schedule_job(charon->scheduler, (job_t*) + lib->scheduler->schedule_job(lib->scheduler, (job_t*) callback_job_create((callback_job_cb_t)request_resync, this, NULL, NULL), 1); } diff --git a/src/libcharon/plugins/ha/ha_ctl.c b/src/libcharon/plugins/ha/ha_ctl.c index e188a8484..980c0551a 100644 --- a/src/libcharon/plugins/ha/ha_ctl.c +++ b/src/libcharon/plugins/ha/ha_ctl.c @@ -114,6 +114,7 @@ METHOD(ha_ctl_t, destroy, void, ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache) { private_ha_ctl_t *this; + mode_t old; INIT(this, .public = { @@ -125,16 +126,23 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache) if (access(HA_FIFO, R_OK|W_OK) != 0) { - if (mkfifo(HA_FIFO, 600) != 0) + old = umask(~(S_IRWXU | S_IRWXG)); + if (mkfifo(HA_FIFO, S_IRUSR | S_IWUSR) != 0) { DBG1(DBG_CFG, "creating HA FIFO %s failed: %s", HA_FIFO, strerror(errno)); } + umask(old); + } + if (chown(HA_FIFO, charon->uid, charon->gid) != 0) + { + DBG1(DBG_CFG, "changing HA FIFO permissions failed: %s", + strerror(errno)); } this->job = callback_job_create((callback_job_cb_t)dispatch_fifo, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + 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 3bc426ea0..b46a221bd 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -136,7 +136,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message diffie_hellman_t dh = { .get_shared_secret = get_shared_secret, .destroy = (void*)&secret }; - proposal = proposal_create(PROTO_IKE); + proposal = proposal_create(PROTO_IKE, 0); keymat = ike_sa->get_keymat(ike_sa); if (integ) { @@ -549,7 +549,7 @@ static void process_child_add(private_ha_dispatcher_t *this, child_sa->set_protocol(child_sa, PROTO_ESP); child_sa->set_ipcomp(child_sa, ipcomp); - proposal = proposal_create(PROTO_ESP); + proposal = proposal_create(PROTO_ESP, 0); if (integ) { proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, integ, 0); @@ -869,7 +869,7 @@ ha_dispatcher_t *ha_dispatcher_create(ha_socket_t *socket, ); this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; } diff --git a/src/libcharon/plugins/ha/ha_kernel.c b/src/libcharon/plugins/ha/ha_kernel.c index 10a63453a..56bdbf454 100644 --- a/src/libcharon/plugins/ha/ha_kernel.c +++ b/src/libcharon/plugins/ha/ha_kernel.c @@ -216,6 +216,11 @@ static void disable_all(private_ha_kernel_t *this) enumerator = enumerator_create_directory(CLUSTERIP_DIR); while (enumerator->enumerate(enumerator, NULL, &file, NULL)) { + if (chown(file, charon->uid, charon->gid) != 0) + { + DBG1(DBG_CFG, "changing ClusterIP permissions failed: %s", + strerror(errno)); + } active = get_active(this, file); for (i = 1; i <= this->count; i++) { diff --git a/src/libcharon/plugins/ha/ha_plugin.c b/src/libcharon/plugins/ha/ha_plugin.c index e722b4f3a..581294e60 100644 --- a/src/libcharon/plugins/ha/ha_plugin.c +++ b/src/libcharon/plugins/ha/ha_plugin.c @@ -142,7 +142,11 @@ plugin_t *ha_plugin_create() } INIT(this, - .public.plugin.destroy = _destroy, + .public = { + .plugin = { + .destroy = _destroy, + }, + }, ); if (secret) diff --git a/src/libcharon/plugins/ha/ha_segments.c b/src/libcharon/plugins/ha/ha_segments.c index be2d7e428..19e0f692e 100644 --- a/src/libcharon/plugins/ha/ha_segments.c +++ b/src/libcharon/plugins/ha/ha_segments.c @@ -283,7 +283,7 @@ static void start_watchdog(private_ha_segments_t *this) { this->job = callback_job_create((callback_job_cb_t)watchdog, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); } METHOD(ha_segments_t, handle_status, void, @@ -345,7 +345,7 @@ static job_requeue_t send_status(private_ha_segments_t *this) message->destroy(message); /* schedule next invocation */ - charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*) + lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*) callback_job_create((callback_job_cb_t) send_status, this, NULL, NULL), this->heartbeat_delay); @@ -382,7 +382,9 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel, INIT(this, .public = { - .listener.alert = _alert_hook, + .listener = { + .alert = _alert_hook, + }, .activate = _activate, .deactivate = _deactivate, .handle_status = _handle_status, diff --git a/src/libcharon/plugins/ha/ha_socket.c b/src/libcharon/plugins/ha/ha_socket.c index 21e6eb6d5..614c70ed3 100644 --- a/src/libcharon/plugins/ha/ha_socket.c +++ b/src/libcharon/plugins/ha/ha_socket.c @@ -107,7 +107,7 @@ METHOD(ha_socket_t, push, void, job = callback_job_create((callback_job_cb_t)send_message, data, (void*)job_data_destroy, NULL); - charon->processor->queue_job(charon->processor, (job_t*)job); + lib->processor->queue_job(lib->processor, (job_t*)job); return; } DBG1(DBG_CFG, "pushing HA message failed: %s", strerror(errno)); diff --git a/src/libcharon/plugins/kernel_klips/Makefile.am b/src/libcharon/plugins/kernel_klips/Makefile.am deleted file mode 100644 index 540bbe106..000000000 --- a/src/libcharon/plugins/kernel_klips/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ - -INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon - -AM_CFLAGS = -rdynamic - -if MONOLITHIC -noinst_LTLIBRARIES = libstrongswan-kernel-klips.la -else -plugin_LTLIBRARIES = libstrongswan-kernel-klips.la -endif - -libstrongswan_kernel_klips_la_SOURCES = \ - kernel_klips_plugin.h kernel_klips_plugin.c \ - kernel_klips_ipsec.h kernel_klips_ipsec.c pfkeyv2.h - -libstrongswan_kernel_klips_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c deleted file mode 100644 index 6b5aeb342..000000000 --- a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c +++ /dev/null @@ -1,2660 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <stdint.h> -#include "pfkeyv2.h" -#include <linux/udp.h> -#include <net/if.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <errno.h> - -#include "kernel_klips_ipsec.h" - -#include <daemon.h> -#include <threading/thread.h> -#include <threading/mutex.h> -#include <processing/jobs/callback_job.h> -#include <processing/jobs/acquire_job.h> -#include <processing/jobs/rekey_child_sa_job.h> -#include <processing/jobs/delete_child_sa_job.h> -#include <processing/jobs/update_sa_job.h> - -/** default timeout for generated SPIs (in seconds) */ -#define SPI_TIMEOUT 30 - -/** buffer size for PF_KEY messages */ -#define PFKEY_BUFFER_SIZE 2048 - -/** PF_KEY messages are 64 bit aligned */ -#define PFKEY_ALIGNMENT 8 -/** aligns len to 64 bits */ -#define PFKEY_ALIGN(len) (((len) + PFKEY_ALIGNMENT - 1) & ~(PFKEY_ALIGNMENT - 1)) -/** calculates the properly padded length in 64 bit chunks */ -#define PFKEY_LEN(len) ((PFKEY_ALIGN(len) / PFKEY_ALIGNMENT)) -/** calculates user mode length i.e. in bytes */ -#define PFKEY_USER_LEN(len) ((len) * PFKEY_ALIGNMENT) - -/** given a PF_KEY message header and an extension this updates the length in the header */ -#define PFKEY_EXT_ADD(msg, ext) ((msg)->sadb_msg_len += ((struct sadb_ext*)ext)->sadb_ext_len) -/** given a PF_KEY message header this returns a pointer to the next extension */ -#define PFKEY_EXT_ADD_NEXT(msg) ((struct sadb_ext*)(((char*)(msg)) + PFKEY_USER_LEN((msg)->sadb_msg_len))) -/** copy an extension and append it to a PF_KEY message */ -#define PFKEY_EXT_COPY(msg, ext) (PFKEY_EXT_ADD(msg, memcpy(PFKEY_EXT_ADD_NEXT(msg), ext, PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len)))) -/** given a PF_KEY extension this returns a pointer to the next extension */ -#define PFKEY_EXT_NEXT(ext) ((struct sadb_ext*)(((char*)(ext)) + PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len))) -/** given a PF_KEY extension this returns a pointer to the next extension also updates len (len in 64 bit words) */ -#define PFKEY_EXT_NEXT_LEN(ext,len) ((len) -= (ext)->sadb_ext_len, PFKEY_EXT_NEXT(ext)) -/** true if ext has a valid length and len is large enough to contain ext (assuming len in 64 bit words) */ -#define PFKEY_EXT_OK(ext,len) ((len) >= PFKEY_LEN(sizeof(struct sadb_ext)) && \ - (ext)->sadb_ext_len >= PFKEY_LEN(sizeof(struct sadb_ext)) && \ - (ext)->sadb_ext_len <= (len)) - -/** special SPI values used for policies in KLIPS */ -#define SPI_PASS 256 -#define SPI_DROP 257 -#define SPI_REJECT 258 -#define SPI_HOLD 259 -#define SPI_TRAP 260 -#define SPI_TRAPSUBNET 261 - -/** the prefix of the name of KLIPS ipsec devices */ -#define IPSEC_DEV_PREFIX "ipsec" -/** this is the default number of ipsec devices */ -#define DEFAULT_IPSEC_DEV_COUNT 4 -/** TRUE if the given name matches an ipsec device */ -#define IS_IPSEC_DEV(name) (strneq((name), IPSEC_DEV_PREFIX, sizeof(IPSEC_DEV_PREFIX) - 1)) - -/** the following stuff is from ipsec_tunnel.h */ -struct ipsectunnelconf -{ - __u32 cf_cmd; - union - { - char cfu_name[12]; - } cf_u; -#define cf_name cf_u.cfu_name -}; - -#define IPSEC_SET_DEV (SIOCDEVPRIVATE) -#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1) -#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2) - -typedef struct private_kernel_klips_ipsec_t private_kernel_klips_ipsec_t; - -/** - * Private variables and functions of kernel_klips class. - */ -struct private_kernel_klips_ipsec_t -{ - /** - * Public part of the kernel_klips_t object. - */ - kernel_klips_ipsec_t public; - - /** - * mutex to lock access to various lists - */ - mutex_t *mutex; - - /** - * List of installed policies (policy_entry_t) - */ - linked_list_t *policies; - - /** - * List of allocated SPIs without installed SA (sa_entry_t) - */ - linked_list_t *allocated_spis; - - /** - * List of installed SAs (sa_entry_t) - */ - linked_list_t *installed_sas; - - /** - * whether to install routes along policies - */ - bool install_routes; - - /** - * List of ipsec devices (ipsec_dev_t) - */ - linked_list_t *ipsec_devices; - - /** - * job receiving PF_KEY events - */ - callback_job_t *job; - - /** - * mutex to lock access to the PF_KEY socket - */ - mutex_t *mutex_pfkey; - - /** - * PF_KEY socket to communicate with the kernel - */ - int socket; - - /** - * PF_KEY socket to receive acquire and expire events - */ - int socket_events; - - /** - * sequence number for messages sent to the kernel - */ - int seq; - -}; - - -typedef struct ipsec_dev_t ipsec_dev_t; - -/** - * ipsec device - */ -struct ipsec_dev_t { - /** name of the virtual ipsec interface */ - char name[IFNAMSIZ]; - - /** name of the physical interface */ - char phys_name[IFNAMSIZ]; - - /** by how many CHILD_SA's this ipsec device is used */ - u_int refcount; -}; - -/** - * compare the given name with the virtual device name - */ -static inline bool ipsec_dev_match_byname(ipsec_dev_t *current, char *name) -{ - return name && streq(current->name, name); -} - -/** - * compare the given name with the physical device name - */ -static inline bool ipsec_dev_match_byphys(ipsec_dev_t *current, char *name) -{ - return name && streq(current->phys_name, name); -} - -/** - * matches free ipsec devices - */ -static inline bool ipsec_dev_match_free(ipsec_dev_t *current) -{ - return current->refcount == 0; -} - -/** - * tries to find an ipsec_dev_t object by name - */ -static status_t find_ipsec_dev(private_kernel_klips_ipsec_t *this, char *name, - ipsec_dev_t **dev) -{ - linked_list_match_t match = (linked_list_match_t)(IS_IPSEC_DEV(name) ? - ipsec_dev_match_byname : ipsec_dev_match_byphys); - return this->ipsec_devices->find_first(this->ipsec_devices, match, - (void**)dev, name); -} - -/** - * attach an ipsec device to a physical interface - */ -static status_t attach_ipsec_dev(char* name, char *phys_name) -{ - int sock; - struct ifreq req; - struct ipsectunnelconf *itc = (struct ipsectunnelconf*)&req.ifr_data; - short phys_flags; - int mtu; - - DBG2(DBG_KNL, "attaching virtual interface %s to %s", name, phys_name); - - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) <= 0) - { - return FAILED; - } - - strncpy(req.ifr_name, phys_name, IFNAMSIZ); - if (ioctl(sock, SIOCGIFFLAGS, &req) < 0) - { - close(sock); - return FAILED; - } - phys_flags = req.ifr_flags; - - strncpy(req.ifr_name, name, IFNAMSIZ); - if (ioctl(sock, SIOCGIFFLAGS, &req) < 0) - { - close(sock); - return FAILED; - } - - if (req.ifr_flags & IFF_UP) - { - /* if it's already up, it is already attached, detach it first */ - ioctl(sock, IPSEC_DEL_DEV, &req); - } - - /* attach it */ - strncpy(req.ifr_name, name, IFNAMSIZ); - strncpy(itc->cf_name, phys_name, sizeof(itc->cf_name)); - ioctl(sock, IPSEC_SET_DEV, &req); - - /* copy address from physical to virtual */ - strncpy(req.ifr_name, phys_name, IFNAMSIZ); - if (ioctl(sock, SIOCGIFADDR, &req) == 0) - { - strncpy(req.ifr_name, name, IFNAMSIZ); - ioctl(sock, SIOCSIFADDR, &req); - } - - /* copy net mask from physical to virtual */ - strncpy(req.ifr_name, phys_name, IFNAMSIZ); - if (ioctl(sock, SIOCGIFNETMASK, &req) == 0) - { - strncpy(req.ifr_name, name, IFNAMSIZ); - ioctl(sock, SIOCSIFNETMASK, &req); - } - - /* copy other flags and addresses */ - strncpy(req.ifr_name, name, IFNAMSIZ); - if (ioctl(sock, SIOCGIFFLAGS, &req) == 0) - { - if (phys_flags & IFF_POINTOPOINT) - { - req.ifr_flags |= IFF_POINTOPOINT; - req.ifr_flags &= ~IFF_BROADCAST; - ioctl(sock, SIOCSIFFLAGS, &req); - - strncpy(req.ifr_name, phys_name, IFNAMSIZ); - if (ioctl(sock, SIOCGIFDSTADDR, &req) == 0) - { - strncpy(req.ifr_name, name, IFNAMSIZ); - ioctl(sock, SIOCSIFDSTADDR, &req); - } - } - else if (phys_flags & IFF_BROADCAST) - { - req.ifr_flags &= ~IFF_POINTOPOINT; - req.ifr_flags |= IFF_BROADCAST; - ioctl(sock, SIOCSIFFLAGS, &req); - - strncpy(req.ifr_name, phys_name, IFNAMSIZ); - if (ioctl(sock, SIOCGIFBRDADDR, &req)==0) - { - strncpy(req.ifr_name, name, IFNAMSIZ); - ioctl(sock, SIOCSIFBRDADDR, &req); - } - } - else - { - req.ifr_flags &= ~IFF_POINTOPOINT; - req.ifr_flags &= ~IFF_BROADCAST; - ioctl(sock, SIOCSIFFLAGS, &req); - } - } - - mtu = lib->settings->get_int(lib->settings, - "charon.plugins.kernel-klips.ipsec_dev_mtu", 0); - if (mtu <= 0) - { - /* guess MTU as physical MTU - ESP overhead [- NAT-T overhead] - * ESP overhead : 73 bytes - * NAT-T overhead : 8 bytes ==> 81 bytes - * - * assuming tunnel mode with AES encryption and integrity - * outer IP header : 20 bytes - * (NAT-T UDP header: 8 bytes) - * ESP header : 8 bytes - * IV : 16 bytes - * padding : 15 bytes (worst-case) - * pad len / NH : 2 bytes - * auth data : 12 bytes - */ - strncpy(req.ifr_name, phys_name, IFNAMSIZ); - ioctl(sock, SIOCGIFMTU, &req); - mtu = req.ifr_mtu - 81; - } - - /* set MTU */ - strncpy(req.ifr_name, name, IFNAMSIZ); - req.ifr_mtu = mtu; - ioctl(sock, SIOCSIFMTU, &req); - - /* bring ipsec device UP */ - if (ioctl(sock, SIOCGIFFLAGS, &req) == 0) - { - req.ifr_flags |= IFF_UP; - ioctl(sock, SIOCSIFFLAGS, &req); - } - - close(sock); - return SUCCESS; -} - -/** - * detach an ipsec device from a physical interface - */ -static status_t detach_ipsec_dev(char* name, char *phys_name) -{ - int sock; - struct ifreq req; - - DBG2(DBG_KNL, "detaching virtual interface %s from %s", name, - strlen(phys_name) ? phys_name : "any physical interface"); - - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) <= 0) - { - return FAILED; - } - - strncpy(req.ifr_name, name, IFNAMSIZ); - if (ioctl(sock, SIOCGIFFLAGS, &req) < 0) - { - close(sock); - return FAILED; - } - - /* shutting interface down */ - if (req.ifr_flags & IFF_UP) - { - req.ifr_flags &= ~IFF_UP; - ioctl(sock, SIOCSIFFLAGS, &req); - } - - /* unset address */ - memset(&req.ifr_addr, 0, sizeof(req.ifr_addr)); - req.ifr_addr.sa_family = AF_INET; - ioctl(sock, SIOCSIFADDR, &req); - - /* detach interface */ - ioctl(sock, IPSEC_DEL_DEV, &req); - - close(sock); - return SUCCESS; -} - -/** - * destroy an ipsec_dev_t object - */ -static void ipsec_dev_destroy(ipsec_dev_t *this) -{ - detach_ipsec_dev(this->name, this->phys_name); - free(this); -} - - -typedef struct route_entry_t route_entry_t; - -/** - * installed routing entry - */ -struct route_entry_t { - /** Name of the interface the route is bound to */ - char *if_name; - - /** Source ip of the route */ - host_t *src_ip; - - /** Gateway for this route */ - host_t *gateway; - - /** Destination net */ - chunk_t dst_net; - - /** Destination net prefixlen */ - u_int8_t prefixlen; -}; - -/** - * destroy an route_entry_t object - */ -static void route_entry_destroy(route_entry_t *this) -{ - free(this->if_name); - this->src_ip->destroy(this->src_ip); - this->gateway->destroy(this->gateway); - chunk_free(&this->dst_net); - free(this); -} - -typedef struct policy_entry_t policy_entry_t; - -/** - * installed kernel policy. - */ -struct policy_entry_t { - - /** reqid of this policy, if setup as trap */ - u_int32_t reqid; - - /** direction of this policy: in, out, forward */ - u_int8_t direction; - - /** parameters of installed policy */ - struct { - /** subnet and port */ - host_t *net; - /** subnet mask */ - u_int8_t mask; - /** protocol */ - u_int8_t proto; - } src, dst; - - /** associated route installed for this policy */ - route_entry_t *route; - - /** by how many CHILD_SA's this policy is actively used */ - u_int activecount; - - /** by how many CHILD_SA's this policy is trapped */ - u_int trapcount; -}; - -/** - * convert a numerical netmask to a host_t - */ -static host_t *mask2host(int family, u_int8_t mask) -{ - static const u_char bitmask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; - chunk_t chunk = chunk_alloca(family == AF_INET ? 4 : 16); - int bytes = mask / 8, bits = mask % 8; - memset(chunk.ptr, 0xFF, bytes); - memset(chunk.ptr + bytes, 0, chunk.len - bytes); - if (bits) - { - chunk.ptr[bytes] = bitmask[bits]; - } - return host_create_from_chunk(family, chunk, 0); -} - -/** - * check if a host is in a subnet (host with netmask in bits) - */ -static bool is_host_in_net(host_t *host, host_t *net, u_int8_t mask) -{ - static const u_char bitmask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; - chunk_t host_chunk, net_chunk; - int bytes = mask / 8, bits = mask % 8; - - host_chunk = host->get_address(host); - net_chunk = net->get_address(net); - - if (host_chunk.len != net_chunk.len) - { - return FALSE; - } - - if (memeq(host_chunk.ptr, net_chunk.ptr, bytes)) - { - return (bits == 0) || - (host_chunk.ptr[bytes] & bitmask[bits]) == - (net_chunk.ptr[bytes] & bitmask[bits]); - } - - return FALSE; -} - -/** - * create a policy_entry_t object - */ -static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t dir) -{ - policy_entry_t *policy = malloc_thing(policy_entry_t); - policy->reqid = 0; - policy->direction = dir; - policy->route = NULL; - policy->activecount = 0; - policy->trapcount = 0; - - src_ts->to_subnet(src_ts, &policy->src.net, &policy->src.mask); - dst_ts->to_subnet(dst_ts, &policy->dst.net, &policy->dst.mask); - - /* src or dest proto may be "any" (0), use more restrictive one */ - policy->src.proto = max(src_ts->get_protocol(src_ts), dst_ts->get_protocol(dst_ts)); - policy->src.proto = policy->src.proto ? policy->src.proto : 0; - policy->dst.proto = policy->src.proto; - - return policy; -} - -/** - * destroy a policy_entry_t object - */ -static void policy_entry_destroy(policy_entry_t *this) -{ - DESTROY_IF(this->src.net); - DESTROY_IF(this->dst.net); - if (this->route) - { - route_entry_destroy(this->route); - } - free(this); -} - -/** - * compares two policy_entry_t - */ -static inline bool policy_entry_equals(policy_entry_t *current, policy_entry_t *policy) -{ - return current->direction == policy->direction && - current->src.proto == policy->src.proto && - current->dst.proto == policy->dst.proto && - current->src.mask == policy->src.mask && - current->dst.mask == policy->dst.mask && - current->src.net->equals(current->src.net, policy->src.net) && - current->dst.net->equals(current->dst.net, policy->dst.net); -} - -static inline bool policy_entry_match_byaddrs(policy_entry_t *current, host_t *src, - host_t *dst) -{ - return is_host_in_net(src, current->src.net, current->src.mask) && - is_host_in_net(dst, current->dst.net, current->dst.mask); -} - -typedef struct sa_entry_t sa_entry_t; - -/** - * used for two things: - * - allocated SPIs that have not yet resulted in an installed SA - * - installed inbound SAs with enabled UDP encapsulation - */ -struct sa_entry_t { - - /** protocol of this SA */ - protocol_id_t protocol; - - /** reqid of this SA */ - u_int32_t reqid; - - /** SPI of this SA */ - u_int32_t spi; - - /** src address of this SA */ - host_t *src; - - /** dst address of this SA */ - host_t *dst; - - /** TRUE if this SA uses UDP encapsulation */ - bool encap; - - /** TRUE if this SA is inbound */ - bool inbound; -}; - -/** - * create an sa_entry_t object - */ -static sa_entry_t *create_sa_entry(protocol_id_t protocol, u_int32_t spi, - u_int32_t reqid, host_t *src, host_t *dst, - bool encap, bool inbound) -{ - sa_entry_t *sa = malloc_thing(sa_entry_t); - sa->protocol = protocol; - sa->reqid = reqid; - sa->spi = spi; - sa->src = src ? src->clone(src) : NULL; - sa->dst = dst ? dst->clone(dst) : NULL; - sa->encap = encap; - sa->inbound = inbound; - return sa; -} - -/** - * destroy an sa_entry_t object - */ -static void sa_entry_destroy(sa_entry_t *this) -{ - DESTROY_IF(this->src); - DESTROY_IF(this->dst); - free(this); -} - -/** - * match an sa_entry_t for an inbound SA that uses UDP encapsulation by spi and src (remote) address - */ -static inline bool sa_entry_match_encapbysrc(sa_entry_t *current, u_int32_t *spi, - host_t *src) -{ - return current->encap && current->inbound && - current->spi == *spi && src->ip_equals(src, current->src); -} - -/** - * match an sa_entry_t by protocol, spi and dst address (as the kernel does it) - */ -static inline bool sa_entry_match_bydst(sa_entry_t *current, protocol_id_t *protocol, - u_int32_t *spi, host_t *dst) -{ - return current->protocol == *protocol && current->spi == *spi && dst->ip_equals(dst, current->dst); -} - -/** - * match an sa_entry_t by protocol, reqid and spi - */ -static inline bool sa_entry_match_byid(sa_entry_t *current, protocol_id_t *protocol, - u_int32_t *spi, u_int32_t *reqid) -{ - return current->protocol == *protocol && current->spi == *spi && current->reqid == *reqid; -} - -typedef struct pfkey_msg_t pfkey_msg_t; - -struct pfkey_msg_t -{ - /** - * PF_KEY message base - */ - struct sadb_msg *msg; - - - /** - * PF_KEY message extensions - */ - union { - struct sadb_ext *ext[SADB_EXT_MAX + 1]; - struct { - struct sadb_ext *reserved; /* SADB_EXT_RESERVED */ - struct sadb_sa *sa; /* SADB_EXT_SA */ - struct sadb_lifetime *lft_current; /* SADB_EXT_LIFETIME_CURRENT */ - struct sadb_lifetime *lft_hard; /* SADB_EXT_LIFETIME_HARD */ - struct sadb_lifetime *lft_soft; /* SADB_EXT_LIFETIME_SOFT */ - struct sadb_address *src; /* SADB_EXT_ADDRESS_SRC */ - struct sadb_address *dst; /* SADB_EXT_ADDRESS_DST */ - struct sadb_address *proxy; /* SADB_EXT_ADDRESS_PROXY */ - struct sadb_key *key_auth; /* SADB_EXT_KEY_AUTH */ - struct sadb_key *key_encr; /* SADB_EXT_KEY_ENCRYPT */ - struct sadb_ident *id_src; /* SADB_EXT_IDENTITY_SRC */ - struct sadb_ident *id_dst; /* SADB_EXT_IDENTITY_DST */ - struct sadb_sens *sensitivity; /* SADB_EXT_SENSITIVITY */ - struct sadb_prop *proposal; /* SADB_EXT_PROPOSAL */ - struct sadb_supported *supported_auth; /* SADB_EXT_SUPPORTED_AUTH */ - struct sadb_supported *supported_encr; /* SADB_EXT_SUPPORTED_ENCRYPT */ - struct sadb_spirange *spirange; /* SADB_EXT_SPIRANGE */ - struct sadb_x_kmprivate *x_kmprivate; /* SADB_X_EXT_KMPRIVATE */ - struct sadb_ext *x_policy; /* SADB_X_EXT_SATYPE2 */ - struct sadb_ext *x_sa2; /* SADB_X_EXT_SA2 */ - struct sadb_address *x_dst2; /* SADB_X_EXT_ADDRESS_DST2 */ - struct sadb_address *x_src_flow; /* SADB_X_EXT_ADDRESS_SRC_FLOW */ - struct sadb_address *x_dst_flow; /* SADB_X_EXT_ADDRESS_DST_FLOW */ - struct sadb_address *x_src_mask; /* SADB_X_EXT_ADDRESS_SRC_MASK */ - struct sadb_address *x_dst_mask; /* SADB_X_EXT_ADDRESS_DST_MASK */ - struct sadb_x_debug *x_debug; /* SADB_X_EXT_DEBUG */ - struct sadb_protocol *x_protocol; /* SADB_X_EXT_PROTOCOL */ - struct sadb_x_nat_t_type *x_natt_type; /* SADB_X_EXT_NAT_T_TYPE */ - struct sadb_x_nat_t_port *x_natt_sport; /* SADB_X_EXT_NAT_T_SPORT */ - struct sadb_x_nat_t_port *x_natt_dport; /* SADB_X_EXT_NAT_T_DPORT */ - struct sadb_address *x_natt_oa; /* SADB_X_EXT_NAT_T_OA */ - } __attribute__((__packed__)); - }; -}; - -/** - * convert a IKEv2 specific protocol identifier to the PF_KEY sa type - */ -static u_int8_t proto_ike2satype(protocol_id_t proto) -{ - switch (proto) - { - case PROTO_ESP: - return SADB_SATYPE_ESP; - case PROTO_AH: - return SADB_SATYPE_AH; - case IPPROTO_COMP: - return SADB_X_SATYPE_COMP; - default: - return proto; - } -} - -/** - * convert a PF_KEY sa type to a IKEv2 specific protocol identifier - */ -static protocol_id_t proto_satype2ike(u_int8_t proto) -{ - switch (proto) - { - case SADB_SATYPE_ESP: - return PROTO_ESP; - case SADB_SATYPE_AH: - return PROTO_AH; - case SADB_X_SATYPE_COMP: - return IPPROTO_COMP; - default: - return proto; - } -} - -typedef struct kernel_algorithm_t kernel_algorithm_t; - -/** - * Mapping of IKEv2 algorithms to PF_KEY algorithms - */ -struct kernel_algorithm_t { - /** - * Identifier specified in IKEv2 - */ - int ikev2; - - /** - * Identifier as defined in pfkeyv2.h - */ - int kernel; -}; - -#define END_OF_LIST -1 - -/** - * Algorithms for encryption - */ -static kernel_algorithm_t encryption_algs[] = { -/* {ENCR_DES_IV64, 0 }, */ - {ENCR_DES, SADB_EALG_DESCBC }, - {ENCR_3DES, SADB_EALG_3DESCBC }, -/* {ENCR_RC5, 0 }, */ -/* {ENCR_IDEA, 0 }, */ -/* {ENCR_CAST, 0 }, */ - {ENCR_BLOWFISH, SADB_EALG_BFCBC }, -/* {ENCR_3IDEA, 0 }, */ -/* {ENCR_DES_IV32, 0 }, */ - {ENCR_NULL, SADB_EALG_NULL }, - {ENCR_AES_CBC, SADB_EALG_AESCBC }, -/* {ENCR_AES_CTR, 0 }, */ -/* {ENCR_AES_CCM_ICV8, 0 }, */ -/* {ENCR_AES_CCM_ICV12, 0 }, */ -/* {ENCR_AES_CCM_ICV16, 0 }, */ -/* {ENCR_AES_GCM_ICV8, 0 }, */ -/* {ENCR_AES_GCM_ICV12, 0 }, */ -/* {ENCR_AES_GCM_ICV16, 0 }, */ - {END_OF_LIST, 0 }, -}; - -/** - * Algorithms for integrity protection - */ -static kernel_algorithm_t integrity_algs[] = { - {AUTH_HMAC_MD5_96, SADB_AALG_MD5HMAC }, - {AUTH_HMAC_SHA1_96, SADB_AALG_SHA1HMAC }, - {AUTH_HMAC_SHA2_256_128, SADB_AALG_SHA256_HMAC }, - {AUTH_HMAC_SHA2_384_192, SADB_AALG_SHA384_HMAC }, - {AUTH_HMAC_SHA2_512_256, SADB_AALG_SHA512_HMAC }, -/* {AUTH_DES_MAC, 0, }, */ -/* {AUTH_KPDK_MD5, 0, }, */ -/* {AUTH_AES_XCBC_96, 0, }, */ - {END_OF_LIST, 0, }, -}; - -#if 0 -/** - * Algorithms for IPComp, unused yet - */ -static kernel_algorithm_t compression_algs[] = { -/* {IPCOMP_OUI, 0 }, */ - {IPCOMP_DEFLATE, SADB_X_CALG_DEFLATE }, - {IPCOMP_LZS, SADB_X_CALG_LZS }, -/* {IPCOMP_LZJH, 0 }, */ - {END_OF_LIST, 0 }, -}; -#endif - -/** - * Look up a kernel algorithm ID and its key size - */ -static int lookup_algorithm(kernel_algorithm_t *list, int ikev2) -{ - while (list->ikev2 != END_OF_LIST) - { - if (ikev2 == list->ikev2) - { - return list->kernel; - } - list++; - } - return 0; -} - -/** - * add a host behind a sadb_address extension - */ -static void host2ext(host_t *host, struct sadb_address *ext) -{ - sockaddr_t *host_addr = host->get_sockaddr(host); - socklen_t *len = host->get_sockaddr_len(host); - memcpy((char*)(ext + 1), host_addr, *len); - ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + *len); -} - -/** - * add a host to the given sadb_msg - */ -static void add_addr_ext(struct sadb_msg *msg, host_t *host, u_int16_t type) -{ - struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg); - addr->sadb_address_exttype = type; - host2ext(host, addr); - PFKEY_EXT_ADD(msg, addr); -} - -/** - * adds an empty address extension to the given sadb_msg - */ -static void add_anyaddr_ext(struct sadb_msg *msg, int family, u_int8_t type) -{ - socklen_t len = (family == AF_INET) ? sizeof(struct sockaddr_in) : - sizeof(struct sockaddr_in6); - struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg); - addr->sadb_address_exttype = type; - sockaddr_t *saddr = (sockaddr_t*)(addr + 1); - saddr->sa_family = family; - addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len); - PFKEY_EXT_ADD(msg, addr); -} - -/** - * add udp encap extensions to a sadb_msg - */ -static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst, - bool ports_only) -{ - struct sadb_x_nat_t_type* nat_type; - struct sadb_x_nat_t_port* nat_port; - - if (!ports_only) - { - nat_type = (struct sadb_x_nat_t_type*)PFKEY_EXT_ADD_NEXT(msg); - nat_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; - nat_type->sadb_x_nat_t_type_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_type)); - nat_type->sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP; - PFKEY_EXT_ADD(msg, nat_type); - } - - nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg); - nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT; - nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port)); - nat_port->sadb_x_nat_t_port_port = src->get_port(src); - PFKEY_EXT_ADD(msg, nat_port); - - nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg); - nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT; - nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port)); - nat_port->sadb_x_nat_t_port_port = dst->get_port(dst); - PFKEY_EXT_ADD(msg, nat_port); -} - -/** - * build an SADB_X_ADDFLOW msg - */ -static void build_addflow(struct sadb_msg *msg, u_int8_t satype, u_int32_t spi, - host_t *src, host_t *dst, host_t *src_net, u_int8_t src_mask, - host_t *dst_net, u_int8_t dst_mask, u_int8_t protocol, bool replace) -{ - struct sadb_sa *sa; - struct sadb_protocol *proto; - host_t *host; - - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_X_ADDFLOW; - msg->sadb_msg_satype = satype; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_spi = spi; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_flags = replace ? SADB_X_SAFLAGS_REPLACEFLOW : 0; - PFKEY_EXT_ADD(msg, sa); - - if (!src) - { - add_anyaddr_ext(msg, src_net->get_family(src_net), SADB_EXT_ADDRESS_SRC); - } - else - { - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC); - } - - if (!dst) - { - add_anyaddr_ext(msg, dst_net->get_family(dst_net), SADB_EXT_ADDRESS_DST); - } - else - { - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST); - } - - add_addr_ext(msg, src_net, SADB_X_EXT_ADDRESS_SRC_FLOW); - add_addr_ext(msg, dst_net, SADB_X_EXT_ADDRESS_DST_FLOW); - - host = mask2host(src_net->get_family(src_net), src_mask); - add_addr_ext(msg, host, SADB_X_EXT_ADDRESS_SRC_MASK); - host->destroy(host); - - host = mask2host(dst_net->get_family(dst_net), dst_mask); - add_addr_ext(msg, host, SADB_X_EXT_ADDRESS_DST_MASK); - host->destroy(host); - - proto = (struct sadb_protocol*)PFKEY_EXT_ADD_NEXT(msg); - proto->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; - proto->sadb_protocol_len = PFKEY_LEN(sizeof(struct sadb_protocol)); - proto->sadb_protocol_proto = protocol; - PFKEY_EXT_ADD(msg, proto); -} - -/** - * build an SADB_X_DELFLOW msg - */ -static void build_delflow(struct sadb_msg *msg, u_int8_t satype, - host_t *src_net, u_int8_t src_mask, host_t *dst_net, u_int8_t dst_mask, - u_int8_t protocol) -{ - struct sadb_protocol *proto; - host_t *host; - - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_X_DELFLOW; - msg->sadb_msg_satype = satype; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - add_addr_ext(msg, src_net, SADB_X_EXT_ADDRESS_SRC_FLOW); - add_addr_ext(msg, dst_net, SADB_X_EXT_ADDRESS_DST_FLOW); - - host = mask2host(src_net->get_family(src_net), - src_mask); - add_addr_ext(msg, host, SADB_X_EXT_ADDRESS_SRC_MASK); - host->destroy(host); - - host = mask2host(dst_net->get_family(dst_net), - dst_mask); - add_addr_ext(msg, host, SADB_X_EXT_ADDRESS_DST_MASK); - host->destroy(host); - - proto = (struct sadb_protocol*)PFKEY_EXT_ADD_NEXT(msg); - proto->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; - proto->sadb_protocol_len = PFKEY_LEN(sizeof(struct sadb_protocol)); - proto->sadb_protocol_proto = protocol; - PFKEY_EXT_ADD(msg, proto); -} - -/** - * Parses a pfkey message received from the kernel - */ -static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out) -{ - struct sadb_ext* ext; - size_t len; - - memset(out, 0, sizeof(pfkey_msg_t)); - out->msg = msg; - - len = msg->sadb_msg_len; - len -= PFKEY_LEN(sizeof(struct sadb_msg)); - - ext = (struct sadb_ext*)(((char*)msg) + sizeof(struct sadb_msg)); - - while (len >= PFKEY_LEN(sizeof(struct sadb_ext))) - { - if (ext->sadb_ext_len < PFKEY_LEN(sizeof(struct sadb_ext)) || - ext->sadb_ext_len > len) - { - DBG1(DBG_KNL, "length of PF_KEY extension (%d) is invalid", ext->sadb_ext_type); - break; - } - - if ((ext->sadb_ext_type > SADB_EXT_MAX) || (!ext->sadb_ext_type)) - { - DBG1(DBG_KNL, "type of PF_KEY extension (%d) is invalid", ext->sadb_ext_type); - break; - } - - if (out->ext[ext->sadb_ext_type]) - { - DBG1(DBG_KNL, "duplicate PF_KEY extension of type (%d)", ext->sadb_ext_type); - break; - } - - out->ext[ext->sadb_ext_type] = ext; - ext = PFKEY_EXT_NEXT_LEN(ext, len); - } - - if (len) - { - DBG1(DBG_KNL, "PF_KEY message length is invalid"); - return FAILED; - } - - return SUCCESS; -} - -/** - * Send a message to a specific PF_KEY socket and handle the response. - */ -static status_t pfkey_send_socket(private_kernel_klips_ipsec_t *this, int socket, - struct sadb_msg *in, struct sadb_msg **out, size_t *out_len) -{ - unsigned char buf[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg; - int in_len, len; - - this->mutex_pfkey->lock(this->mutex_pfkey); - - in->sadb_msg_seq = ++this->seq; - in->sadb_msg_pid = getpid(); - - in_len = PFKEY_USER_LEN(in->sadb_msg_len); - - while (TRUE) - { - len = send(socket, in, in_len, 0); - - if (len != in_len) - { - switch (errno) - { - case EINTR: - /* interrupted, try again */ - continue; - case EINVAL: - case EEXIST: - case ESRCH: - /* we should also get a response for these from KLIPS */ - break; - default: - this->mutex_pfkey->unlock(this->mutex_pfkey); - DBG1(DBG_KNL, "error sending to PF_KEY socket: %s (%d)", - strerror(errno), errno); - return FAILED; - } - } - break; - } - - while (TRUE) - { - msg = (struct sadb_msg*)buf; - - len = recv(socket, buf, sizeof(buf), 0); - - if (len < 0) - { - if (errno == EINTR) - { - DBG1(DBG_KNL, "got interrupted"); - /* interrupted, try again */ - continue; - } - this->mutex_pfkey->unlock(this->mutex_pfkey); - DBG1(DBG_KNL, "error reading from PF_KEY socket: %s", strerror(errno)); - return FAILED; - } - if (len < sizeof(struct sadb_msg) || - msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg))) - { - this->mutex_pfkey->unlock(this->mutex_pfkey); - DBG1(DBG_KNL, "received corrupted PF_KEY message"); - return FAILED; - } - if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT) - { - this->mutex_pfkey->unlock(this->mutex_pfkey); - DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message"); - return FAILED; - } - if (msg->sadb_msg_pid != in->sadb_msg_pid) - { - DBG2(DBG_KNL, "received PF_KEY message is not intended for us"); - continue; - } - if (msg->sadb_msg_seq != this->seq) - { - DBG1(DBG_KNL, "received PF_KEY message with invalid sequence number," - " was %d expected %d", msg->sadb_msg_seq, this->seq); - if (msg->sadb_msg_seq < this->seq) - { - continue; - } - this->mutex_pfkey->unlock(this->mutex_pfkey); - return FAILED; - } - if (msg->sadb_msg_type != in->sadb_msg_type) - { - DBG2(DBG_KNL, "received PF_KEY message of wrong type," - " was %d expected %d, ignoring", - msg->sadb_msg_type, in->sadb_msg_type); - } - break; - } - - *out_len = len; - *out = (struct sadb_msg*)malloc(len); - memcpy(*out, buf, len); - - this->mutex_pfkey->unlock(this->mutex_pfkey); - - return SUCCESS; -} - -/** - * Send a message to the default PF_KEY socket. - */ -static status_t pfkey_send(private_kernel_klips_ipsec_t *this, - struct sadb_msg *in, struct sadb_msg **out, size_t *out_len) -{ - return pfkey_send_socket(this, this->socket, in, out, out_len); -} - -/** - * Send a message to the default PF_KEY socket and handle the response. - */ -static status_t pfkey_send_ack(private_kernel_klips_ipsec_t *this, struct sadb_msg *in) -{ - struct sadb_msg *out; - size_t len; - - if (pfkey_send(this, in, &out, &len) != SUCCESS) - { - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "PF_KEY error: %s (%d)", - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - return SUCCESS; -} - -/** - * Add an eroute to KLIPS - */ -static status_t add_eroute(private_kernel_klips_ipsec_t *this, u_int8_t satype, - u_int32_t spi, host_t *src, host_t *dst, host_t *src_net, u_int8_t src_mask, - host_t *dst_net, u_int8_t dst_mask, u_int8_t protocol, bool replace) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg = (struct sadb_msg*)request; - - memset(&request, 0, sizeof(request)); - - build_addflow(msg, satype, spi, src, dst, src_net, src_mask, - dst_net, dst_mask, protocol, replace); - - return pfkey_send_ack(this, msg); -} - -/** - * Delete an eroute fom KLIPS - */ -static status_t del_eroute(private_kernel_klips_ipsec_t *this, u_int8_t satype, - host_t *src_net, u_int8_t src_mask, host_t *dst_net, u_int8_t dst_mask, - u_int8_t protocol) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg = (struct sadb_msg*)request; - - memset(&request, 0, sizeof(request)); - - build_delflow(msg, satype, src_net, src_mask, dst_net, dst_mask, protocol); - - return pfkey_send_ack(this, msg); -} - -/** - * Process a SADB_ACQUIRE message from the kernel - */ -static void process_acquire(private_kernel_klips_ipsec_t *this, struct sadb_msg* msg) -{ - pfkey_msg_t response; - host_t *src, *dst; - u_int32_t reqid; - u_int8_t proto; - policy_entry_t *policy; - job_t *job; - - switch (msg->sadb_msg_satype) - { - case SADB_SATYPE_UNSPEC: - case SADB_SATYPE_ESP: - case SADB_SATYPE_AH: - break; - default: - /* acquire for AH/ESP only */ - return; - } - - if (parse_pfkey_message(msg, &response) != SUCCESS) - { - DBG1(DBG_KNL, "parsing SADB_ACQUIRE from kernel failed"); - return; - } - - /* KLIPS provides us only with the source and destination address, - * and the transport protocol of the packet that triggered the policy. - * we use this information to find a matching policy in our cache. - * because KLIPS installs a narrow %hold eroute covering only this information, - * we replace both the %trap and this %hold eroutes with a broader %hold - * eroute covering the whole policy */ - src = host_create_from_sockaddr((sockaddr_t*)(response.src + 1)); - dst = host_create_from_sockaddr((sockaddr_t*)(response.dst + 1)); - proto = response.src->sadb_address_proto; - if (!src || !dst || src->get_family(src) != dst->get_family(dst)) - { - DBG1(DBG_KNL, "received an SADB_ACQUIRE with invalid hosts"); - return; - } - - DBG2(DBG_KNL, "received an SADB_ACQUIRE for %H == %H : %d", src, dst, proto); - this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_match_byaddrs, - (void**)&policy, src, dst) != SUCCESS) - { - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "received an SADB_ACQUIRE, but found no matching policy"); - return; - } - if ((reqid = policy->reqid) == 0) - { - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "received an SADB_ACQUIRE, but policy is not routed anymore"); - return; - } - - /* add a broad %hold eroute that replaces the %trap eroute */ - add_eroute(this, SADB_X_SATYPE_INT, htonl(SPI_HOLD), NULL, NULL, - policy->src.net, policy->src.mask, policy->dst.net, policy->dst.mask, - policy->src.proto, TRUE); - - /* remove the narrow %hold eroute installed by KLIPS */ - del_eroute(this, SADB_X_SATYPE_INT, src, 32, dst, 32, proto); - - this->mutex->unlock(this->mutex); - - DBG2(DBG_KNL, "received an SADB_ACQUIRE"); - DBG1(DBG_KNL, "creating acquire job for CHILD_SA with reqid {%d}", reqid); - job = (job_t*)acquire_job_create(reqid, NULL, NULL); - charon->processor->queue_job(charon->processor, job); -} - -/** - * Process a SADB_X_NAT_T_NEW_MAPPING message from the kernel - */ -static void process_mapping(private_kernel_klips_ipsec_t *this, struct sadb_msg* msg) -{ - pfkey_msg_t response; - u_int32_t spi, reqid; - host_t *old_src, *new_src; - job_t *job; - - DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING"); - - if (parse_pfkey_message(msg, &response) != SUCCESS) - { - DBG1(DBG_KNL, "parsing SADB_X_NAT_T_NEW_MAPPING from kernel failed"); - return; - } - - spi = response.sa->sadb_sa_spi; - - if (proto_satype2ike(msg->sadb_msg_satype) == PROTO_ESP) - { - sa_entry_t *sa; - sockaddr_t *addr = (sockaddr_t*)(response.src + 1); - old_src = host_create_from_sockaddr(addr); - - this->mutex->lock(this->mutex); - if (!old_src || this->installed_sas->find_first(this->installed_sas, - (linked_list_match_t)sa_entry_match_encapbysrc, - (void**)&sa, &spi, old_src) != SUCCESS) - { - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING, but found no matching SA"); - return; - } - reqid = sa->reqid; - this->mutex->unlock(this->mutex); - - addr = (sockaddr_t*)(response.dst + 1); - switch (addr->sa_family) - { - case AF_INET: - { - struct sockaddr_in *sin = (struct sockaddr_in*)addr; - sin->sin_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port); - } - case AF_INET6: - { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)addr; - sin6->sin6_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port); - } - default: - break; - } - new_src = host_create_from_sockaddr(addr); - if (new_src) - { - DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and" - " reqid {%d} changed, queuing update job", ntohl(spi), reqid); - job = (job_t*)update_sa_job_create(reqid, new_src); - charon->processor->queue_job(charon->processor, job); - } - } -} - -/** - * Receives events from kernel - */ -static job_requeue_t receive_events(private_kernel_klips_ipsec_t *this) -{ - unsigned char buf[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg = (struct sadb_msg*)buf; - int len; - bool oldstate; - - oldstate = thread_cancelability(TRUE); - len = recv(this->socket_events, buf, sizeof(buf), 0); - thread_cancelability(oldstate); - - if (len < 0) - { - switch (errno) - { - case EINTR: - /* interrupted, try again */ - return JOB_REQUEUE_DIRECT; - case EAGAIN: - /* no data ready, select again */ - return JOB_REQUEUE_DIRECT; - default: - DBG1(DBG_KNL, "unable to receive from PF_KEY event socket"); - sleep(1); - return JOB_REQUEUE_FAIR; - } - } - - if (len < sizeof(struct sadb_msg) || - msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg))) - { - DBG2(DBG_KNL, "received corrupted PF_KEY message"); - return JOB_REQUEUE_DIRECT; - } - if (msg->sadb_msg_pid != 0) - { /* not from kernel. not interested, try another one */ - return JOB_REQUEUE_DIRECT; - } - if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT) - { - DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message"); - return JOB_REQUEUE_DIRECT; - } - - switch (msg->sadb_msg_type) - { - case SADB_ACQUIRE: - process_acquire(this, msg); - break; - case SADB_EXPIRE: - /* SADB_EXPIRE events in KLIPS are only triggered by traffic (even for - * the time based limits). So if there is no traffic for a longer - * period than configured as hard limit, we wouldn't be able to rekey - * the SA and just receive the hard expire and thus delete the SA. - * To avoid this behavior and to make charon behave as with the other - * kernel plugins, we implement the expiration of SAs ourselves. */ - break; - case SADB_X_NAT_T_NEW_MAPPING: - process_mapping(this, msg); - break; - default: - break; - } - - return JOB_REQUEUE_DIRECT; -} - -typedef enum { - /** an SPI has expired */ - EXPIRE_TYPE_SPI, - /** a CHILD_SA has to be rekeyed */ - EXPIRE_TYPE_SOFT, - /** a CHILD_SA has to be deleted */ - EXPIRE_TYPE_HARD -} expire_type_t; - -typedef struct sa_expire_t sa_expire_t; - -struct sa_expire_t { - /** kernel interface */ - private_kernel_klips_ipsec_t *this; - /** the SPI of the expiring SA */ - u_int32_t spi; - /** the protocol of the expiring SA */ - protocol_id_t protocol; - /** the reqid of the expiring SA*/ - u_int32_t reqid; - /** what type of expire this is */ - expire_type_t type; -}; - -/** - * Called when an SA expires - */ -static job_requeue_t sa_expires(sa_expire_t *expire) -{ - private_kernel_klips_ipsec_t *this = expire->this; - protocol_id_t protocol = expire->protocol; - u_int32_t spi = expire->spi, reqid = expire->reqid; - bool hard = expire->type != EXPIRE_TYPE_SOFT; - sa_entry_t *cached_sa; - linked_list_t *list; - job_t *job; - - /* for an expired SPI we first check whether the CHILD_SA got installed - * in the meantime, for expired SAs we check whether they are still installed */ - list = expire->type == EXPIRE_TYPE_SPI ? this->allocated_spis : this->installed_sas; - - this->mutex->lock(this->mutex); - if (list->find_first(list, (linked_list_match_t)sa_entry_match_byid, - (void**)&cached_sa, &protocol, &spi, &reqid) != SUCCESS) - { - /* we found no entry: - * - for SPIs, a CHILD_SA has been installed - * - for SAs, the CHILD_SA has already been deleted */ - this->mutex->unlock(this->mutex); - return JOB_REQUEUE_NONE; - } - else - { - list->remove(list, cached_sa, NULL); - sa_entry_destroy(cached_sa); - } - this->mutex->unlock(this->mutex); - - DBG2(DBG_KNL, "%N CHILD_SA with SPI %.8x and reqid {%d} expired", - protocol_id_names, protocol, ntohl(spi), reqid); - - DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%d}", - hard ? "delete" : "rekey", protocol_id_names, - protocol, ntohl(spi), reqid); - if (hard) - { - job = (job_t*)delete_child_sa_job_create(reqid, protocol, spi); - } - else - { - job = (job_t*)rekey_child_sa_job_create(reqid, protocol, spi); - } - charon->processor->queue_job(charon->processor, job); - return JOB_REQUEUE_NONE; -} - -/** - * Schedule an expire job for an SA. Time is in seconds. - */ -static void schedule_expire(private_kernel_klips_ipsec_t *this, - protocol_id_t protocol, u_int32_t spi, - u_int32_t reqid, expire_type_t type, u_int32_t time) -{ - callback_job_t *job; - sa_expire_t *expire = malloc_thing(sa_expire_t); - expire->this = this; - expire->protocol = protocol; - expire->spi = spi; - expire->reqid = reqid; - expire->type = type; - job = callback_job_create((callback_job_cb_t)sa_expires, expire, free, NULL); - charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, time); -} - -METHOD(kernel_ipsec_t, get_spi, status_t, - private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, - protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi) -{ - /* we cannot use SADB_GETSPI because KLIPS does not allow us to set the - * NAT-T type in an SADB_UPDATE which we would have to use to update the - * implicitly created SA. - */ - rng_t *rng; - u_int32_t spi_gen; - - rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); - if (!rng) - { - DBG1(DBG_KNL, "allocating SPI failed: no RNG"); - return FAILED; - } - rng->get_bytes(rng, sizeof(spi_gen), (void*)&spi_gen); - rng->destroy(rng); - - /* charon's SPIs lie within the range from 0xc0000000 to 0xcFFFFFFF */ - spi_gen = 0xc0000000 | (spi_gen & 0x0FFFFFFF); - - DBG2(DBG_KNL, "allocated SPI %.8x for %N SA between %#H..%#H", - spi_gen, protocol_id_names, protocol, src, dst); - - *spi = htonl(spi_gen); - - this->mutex->lock(this->mutex); - this->allocated_spis->insert_last(this->allocated_spis, - create_sa_entry(protocol, *spi, reqid, NULL, NULL, FALSE, TRUE)); - this->mutex->unlock(this->mutex); - schedule_expire(this, protocol, *spi, reqid, EXPIRE_TYPE_SPI, SPI_TIMEOUT); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, get_cpi, status_t, - private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) -{ - return FAILED; -} - -/** - * Add a pseudo IPIP SA for tunnel mode with KLIPS. - */ -static status_t add_ipip_sa(private_kernel_klips_ipsec_t *this, - host_t *src, host_t *dst, u_int32_t spi, u_int32_t reqid) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - size_t len; - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "adding pseudo IPIP SA with SPI %.8x and reqid {%d}", ntohl(spi), reqid); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_ADD; - msg->sadb_msg_satype = SADB_X_SATYPE_IPIP; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - sa->sadb_sa_state = SADB_SASTATE_MATURE; - PFKEY_EXT_ADD(msg, sa); - - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to add pseudo IPIP SA with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to add pseudo IPIP SA with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - - free(out); - return SUCCESS; -} - -/** - * group the IPIP SA required for tunnel mode with the outer SA - */ -static status_t group_ipip_sa(private_kernel_klips_ipsec_t *this, - host_t *src, host_t *dst, u_int32_t spi, - protocol_id_t protocol, u_int32_t reqid) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - struct sadb_x_satype *satype; - size_t len; - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "grouping SAs with SPI %.8x and reqid {%d}", ntohl(spi), reqid); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_X_GRPSA; - msg->sadb_msg_satype = SADB_X_SATYPE_IPIP; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - sa->sadb_sa_state = SADB_SASTATE_MATURE; - PFKEY_EXT_ADD(msg, sa); - - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST); - - satype = (struct sadb_x_satype*)PFKEY_EXT_ADD_NEXT(msg); - satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2; - satype->sadb_x_satype_len = PFKEY_LEN(sizeof(struct sadb_x_satype)); - satype->sadb_x_satype_satype = proto_ike2satype(protocol); - PFKEY_EXT_ADD(msg, satype); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_X_EXT_SA2; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - sa->sadb_sa_state = SADB_SASTATE_MATURE; - PFKEY_EXT_ADD(msg, sa); - - add_addr_ext(msg, dst, SADB_X_EXT_ADDRESS_DST2); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to group SAs with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to group SAs with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, add_sa, status_t, - private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi, - protocol_id_t protocol, u_int32_t reqid, mark_t mark, - 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 inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - struct sadb_key *key; - size_t len; - - if (inbound) - { - /* for inbound SAs we allocated an SPI via get_spi, so we first check - * whether that SPI has already expired (race condition) */ - sa_entry_t *alloc_spi; - this->mutex->lock(this->mutex); - if (this->allocated_spis->find_first(this->allocated_spis, - (linked_list_match_t)sa_entry_match_byid, (void**)&alloc_spi, - &protocol, &spi, &reqid) != SUCCESS) - { - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "allocated SPI %.8x has already expired", ntohl(spi)); - return FAILED; - } - else - { - this->allocated_spis->remove(this->allocated_spis, alloc_spi, NULL); - sa_entry_destroy(alloc_spi); - } - this->mutex->unlock(this->mutex); - } - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%d}", ntohl(spi), reqid); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_ADD; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - sa->sadb_sa_state = SADB_SASTATE_MATURE; - sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32; - sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg); - sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg); - PFKEY_EXT_ADD(msg, sa); - - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST); - - if (enc_alg != ENCR_UNDEFINED) - { - if (!sa->sadb_sa_encrypt) - { - DBG1(DBG_KNL, "algorithm %N not supported by kernel!", - encryption_algorithm_names, enc_alg); - return FAILED; - } - DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", - encryption_algorithm_names, enc_alg, enc_key.len * 8); - - key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg); - key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; - key->sadb_key_bits = enc_key.len * 8; - key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + enc_key.len); - memcpy(key + 1, enc_key.ptr, enc_key.len); - - PFKEY_EXT_ADD(msg, key); - } - - if (int_alg != AUTH_UNDEFINED) - { - if (!sa->sadb_sa_auth) - { - DBG1(DBG_KNL, "algorithm %N not supported by kernel!", - integrity_algorithm_names, int_alg); - return FAILED; - } - DBG2(DBG_KNL, " using integrity algorithm %N with key size %d", - integrity_algorithm_names, int_alg, int_key.len * 8); - - key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg); - key->sadb_key_exttype = SADB_EXT_KEY_AUTH; - key->sadb_key_bits = int_key.len * 8; - key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + int_key.len); - memcpy(key + 1, int_key.ptr, int_key.len); - - PFKEY_EXT_ADD(msg, key); - } - - if (ipcomp != IPCOMP_NONE) - { - /*TODO*/ - } - - if (encap) - { - add_encap_ext(msg, src, dst, FALSE); - } - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - - /* for tunnel mode SAs we have to install an additional IPIP SA and - * group the two SAs together */ - if (mode == MODE_TUNNEL) - { - if (add_ipip_sa(this, src, dst, spi, reqid) != SUCCESS || - group_ipip_sa(this, src, dst, spi, protocol, reqid) != SUCCESS) - { - DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi)); - return FAILED; - } - } - - this->mutex->lock(this->mutex); - /* we cache this SA for two reasons: - * - in case an SADB_X_NAT_T_MAPPING_NEW event occurs (we need to find the reqid then) - * - to decide if an expired SA is still installed */ - this->installed_sas->insert_last(this->installed_sas, - create_sa_entry(protocol, spi, reqid, src, dst, encap, inbound)); - this->mutex->unlock(this->mutex); - - /* Although KLIPS supports SADB_EXT_LIFETIME_SOFT/HARD, we handle the lifetime - * of SAs manually in the plugin. Refer to the comments in receive_events() - * for details. */ - if (lifetime->time.rekey) - { - schedule_expire(this, protocol, spi, reqid, EXPIRE_TYPE_SOFT, lifetime->time.rekey); - } - - if (lifetime->time.life) - { - schedule_expire(this, protocol, spi, reqid, EXPIRE_TYPE_HARD, lifetime->time.life); - } - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, update_sa, status_t, - private_kernel_klips_ipsec_t *this, u_int32_t spi, protocol_id_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) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - size_t len; - - /* we can't update the SA if any of the ip addresses have changed. - * that's because we can't use SADB_UPDATE and by deleting and readding the - * SA the sequence numbers would get lost */ - if (!src->ip_equals(src, new_src) || - !dst->ip_equals(dst, new_dst)) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: address changes" - " are not supported", ntohl(spi)); - return NOT_SUPPORTED; - } - - /* because KLIPS does not allow us to change the NAT-T type in an SADB_UPDATE, - * we can't update the SA if the encap flag has changed since installing it */ - if (encap != new_encap) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: change of UDP" - " encapsulation is not supported", ntohl(spi)); - return NOT_SUPPORTED; - } - - DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H", - ntohl(spi), src, dst, new_src, new_dst); - - memset(&request, 0, sizeof(request)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_UPDATE; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - sa->sadb_sa_encrypt = SADB_EALG_AESCBC; /* ignored */ - sa->sadb_sa_auth = SADB_AALG_SHA1HMAC; /* ignored */ - sa->sadb_sa_state = SADB_SASTATE_MATURE; - PFKEY_EXT_ADD(msg, sa); - - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST); - - add_encap_ext(msg, new_src, new_dst, TRUE); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, query_sa, status_t, - private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes) -{ - return NOT_SUPPORTED; /* TODO */ -} - -METHOD(kernel_ipsec_t, del_sa, status_t, - private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - sa_entry_t *cached_sa; - size_t len; - - memset(&request, 0, sizeof(request)); - - /* all grouped SAs are automatically deleted by KLIPS as soon as - * one of them is deleted, therefore we delete only the main one */ - DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi)); - - this->mutex->lock(this->mutex); - /* this should not fail, but we don't care if it does, let the kernel decide - * whether this SA exists or not */ - if (this->installed_sas->find_first(this->installed_sas, - (linked_list_match_t)sa_entry_match_bydst, (void**)&cached_sa, - &protocol, &spi, dst) == SUCCESS) - { - this->installed_sas->remove(this->installed_sas, cached_sa, NULL); - sa_entry_destroy(cached_sa); - } - this->mutex->unlock(this->mutex); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_DELETE; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - PFKEY_EXT_ADD(msg, sa); - - /* the kernel wants an SADB_EXT_ADDRESS_SRC to be present even though - * it is not used for anything. */ - add_anyaddr_ext(msg, dst->get_family(dst), SADB_EXT_ADDRESS_SRC); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - - DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi)); - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, add_policy, status_t, - private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts, - policy_dir_t direction, u_int32_t spi, protocol_id_t protocol, - u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp, - u_int16_t cpi, bool routed) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - policy_entry_t *policy, *found = NULL; - u_int8_t satype; - size_t len; - - if (direction == POLICY_FWD) - { - /* no forward policies for KLIPS */ - return SUCCESS; - } - - /* tunnel mode policies direct the packets into the pseudo IPIP SA */ - satype = (mode == MODE_TUNNEL) ? SADB_X_SATYPE_IPIP : - proto_ike2satype(protocol); - - /* create a policy */ - policy = create_policy_entry(src_ts, dst_ts, direction); - - /* find a matching policy */ - this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, (void**)&found, policy) == SUCCESS) - { - /* use existing policy */ - DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing" - " refcount", src_ts, dst_ts, - policy_dir_names, direction); - policy_entry_destroy(policy); - policy = found; - } - else - { - /* apply the new one, if we have no such policy */ - this->policies->insert_last(this->policies, policy); - } - - if (routed) - { - /* we install this as a %trap eroute in the kernel, later to be - * triggered by packets matching the policy (-> ACQUIRE). */ - spi = htonl(SPI_TRAP); - satype = SADB_X_SATYPE_INT; - - /* the reqid is always set to the latest child SA that trapped this - * policy. we will need this reqid upon receiving an acquire. */ - policy->reqid = reqid; - - /* increase the trap counter */ - policy->trapcount++; - - if (policy->activecount) - { - /* we do not replace the current policy in the kernel while a - * policy is actively used */ - this->mutex->unlock(this->mutex); - return SUCCESS; - } - } - else - { - /* increase the reference counter */ - policy->activecount++; - } - - DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - - memset(&request, 0, sizeof(request)); - - msg = (struct sadb_msg*)request; - - /* FIXME: SADB_X_SAFLAGS_INFLOW may be required, if we add an inbound policy for an IPIP SA */ - build_addflow(msg, satype, spi, routed ? NULL : src, routed ? NULL : dst, - policy->src.net, policy->src.mask, policy->dst.net, policy->dst.mask, - policy->src.proto, found != NULL); - - this->mutex->unlock(this->mutex); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to add policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to add policy %R === %R %N: %s (%d)", src_ts, dst_ts, - policy_dir_names, direction, - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - - this->mutex->lock(this->mutex); - - /* we try to find the policy again and install the route if needed */ - if (this->policies->find_last(this->policies, NULL, (void**)&policy) != SUCCESS) - { - this->mutex->unlock(this->mutex); - DBG2(DBG_KNL, "the policy %R === %R %N is already gone, ignoring", - src_ts, dst_ts, policy_dir_names, direction); - return SUCCESS; - } - - /* KLIPS requires a special route that directs traffic that matches this - * policy to one of the virtual ipsec interfaces. The virtual interface - * has to be attached to the physical one the traffic runs over. - * This is a special case of the source route we install in other kernel - * interfaces. - * In the following cases we do NOT install a source route (but just a - * regular route): - * - we are not in tunnel mode - * - we are using IPv6 (does not work correctly yet!) - * - routing is disabled via strongswan.conf - */ - if (policy->route == NULL && direction == POLICY_OUT) - { - char *iface; - ipsec_dev_t *dev; - route_entry_t *route = malloc_thing(route_entry_t); - route->src_ip = NULL; - - if (mode != MODE_TRANSPORT && src->get_family(src) != AF_INET6 && - this->install_routes) - { - charon->kernel_interface->get_address_by_ts(charon->kernel_interface, - src_ts, &route->src_ip); - } - - if (!route->src_ip) - { - route->src_ip = host_create_any(src->get_family(src)); - } - - /* find the virtual interface */ - iface = charon->kernel_interface->get_interface(charon->kernel_interface, - src); - if (find_ipsec_dev(this, iface, &dev) == SUCCESS) - { - /* above, we got either the name of a virtual or a physical - * interface. for both cases it means we already have the devices - * properly attached (assuming that we are exclusively attaching - * ipsec devices). */ - dev->refcount++; - } - else - { - /* there is no record of a mapping with the returned interface. - * thus, we attach the first free virtual interface we find to - * it. As above we assume we are the only client fiddling with - * ipsec devices. */ - if (this->ipsec_devices->find_first(this->ipsec_devices, - (linked_list_match_t)ipsec_dev_match_free, - (void**)&dev) == SUCCESS) - { - if (attach_ipsec_dev(dev->name, iface) == SUCCESS) - { - strncpy(dev->phys_name, iface, IFNAMSIZ); - dev->refcount = 1; - } - else - { - DBG1(DBG_KNL, "failed to attach virtual interface %s" - " to %s", dev->name, iface); - this->mutex->unlock(this->mutex); - free(iface); - return FAILED; - } - } - else - { - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "failed to attach a virtual interface to %s: no" - " virtual interfaces left", iface); - free(iface); - return FAILED; - } - } - free(iface); - route->if_name = strdup(dev->name); - - /* get the nexthop to dst */ - route->gateway = charon->kernel_interface->get_nexthop( - charon->kernel_interface, dst); - route->dst_net = chunk_clone(policy->dst.net->get_address(policy->dst.net)); - route->prefixlen = policy->dst.mask; - - switch (charon->kernel_interface->add_route(charon->kernel_interface, - route->dst_net, route->prefixlen, route->gateway, - route->src_ip, route->if_name)) - { - default: - DBG1(DBG_KNL, "unable to install route for policy %R === %R", - src_ts, dst_ts); - /* FALL */ - case ALREADY_DONE: - /* route exists, do not uninstall */ - route_entry_destroy(route); - break; - case SUCCESS: - /* cache the installed route */ - policy->route = route; - break; - } - } - - this->mutex->unlock(this->mutex); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, query_policy, status_t, - private_kernel_klips_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) -{ - #define IDLE_PREFIX "idle=" - static const char *path_eroute = "/proc/net/ipsec_eroute"; - static const char *path_spi = "/proc/net/ipsec_spi"; - FILE *file; - char line[1024], src[INET6_ADDRSTRLEN + 9], dst[INET6_ADDRSTRLEN + 9]; - char *said = NULL, *pos; - policy_entry_t *policy, *found = NULL; - status_t status = FAILED; - - if (direction == POLICY_FWD) - { - /* we do not install forward policies */ - return FAILED; - } - - DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - - /* create a policy */ - policy = create_policy_entry(src_ts, dst_ts, direction); - - /* find a matching policy */ - this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, (void**)&found, policy) != SUCCESS) - { - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", src_ts, - dst_ts, policy_dir_names, direction); - policy_entry_destroy(policy); - return NOT_FOUND; - } - policy_entry_destroy(policy); - policy = found; - - /* src and dst selectors in KLIPS are of the form NET_ADDR/NETBITS:PROTO */ - snprintf(src, sizeof(src), "%H/%d:%d", policy->src.net, policy->src.mask, - policy->src.proto); - src[sizeof(src) - 1] = '\0'; - snprintf(dst, sizeof(dst), "%H/%d:%d", policy->dst.net, policy->dst.mask, - policy->dst.proto); - dst[sizeof(dst) - 1] = '\0'; - - this->mutex->unlock(this->mutex); - - /* we try to find the matching eroute first */ - file = fopen(path_eroute, "r"); - if (file == NULL) - { - DBG1(DBG_KNL, "unable to query policy %R === %R %N: %s (%d)", src_ts, - dst_ts, policy_dir_names, direction, strerror(errno), errno); - return FAILED; - } - - /* read line by line where each line looks like: - * packets src -> dst => said */ - while (fgets(line, sizeof(line), file)) - { - enumerator_t *enumerator; - char *token; - int i = 0; - - enumerator = enumerator_create_token(line, " \t", " \t\n"); - while (enumerator->enumerate(enumerator, &token)) - { - switch (i++) - { - case 0: /* packets */ - continue; - case 1: /* src */ - if (streq(token, src)) - { - continue; - } - break; - case 2: /* -> */ - continue; - case 3: /* dst */ - if (streq(token, dst)) - { - continue; - } - break; - case 4: /* => */ - continue; - case 5: /* said */ - said = strdup(token); - break; - } - break; - } - enumerator->destroy(enumerator); - - if (i == 5) - { - /* eroute matched */ - break; - } - } - fclose(file); - - if (said == NULL) - { - DBG1(DBG_KNL, "unable to query policy %R === %R %N: found no matching" - " eroute", src_ts, dst_ts, policy_dir_names, direction); - return FAILED; - } - - /* compared with the one in the spi entry the SA ID from the eroute entry - * has an additional ":PROTO" appended, which we need to cut off */ - pos = strrchr(said, ':'); - *pos = '\0'; - - /* now we try to find the matching spi entry */ - file = fopen(path_spi, "r"); - if (file == NULL) - { - DBG1(DBG_KNL, "unable to query policy %R === %R %N: %s (%d)", src_ts, - dst_ts, policy_dir_names, direction, strerror(errno), errno); - return FAILED; - } - - while (fgets(line, sizeof(line), file)) - { - if (strneq(line, said, strlen(said))) - { - /* fine we found the correct line, now find the idle time */ - u_int32_t idle_time; - pos = strstr(line, IDLE_PREFIX); - if (pos == NULL) - { - /* no idle time, i.e. this SA has not been used yet */ - break; - } - if (sscanf(pos, IDLE_PREFIX"%u", &idle_time) <= 0) - { - /* idle time not valid */ - break; - } - - *use_time = time_monotonic(NULL) - idle_time; - status = SUCCESS; - break; - } - } - fclose(file); - free(said); - - return status; -} - -METHOD(kernel_ipsec_t, del_policy, status_t, - private_kernel_klips_ipsec_t *this, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, - bool unrouted) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg = (struct sadb_msg*)request, *out; - policy_entry_t *policy, *found = NULL; - route_entry_t *route; - size_t len; - - if (direction == POLICY_FWD) - { - /* no forward policies for KLIPS */ - return SUCCESS; - } - - DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - - /* create a policy */ - policy = create_policy_entry(src_ts, dst_ts, direction); - - /* find a matching policy */ - this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, (void**)&found, policy) != SUCCESS) - { - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts, - dst_ts, policy_dir_names, direction); - policy_entry_destroy(policy); - return NOT_FOUND; - } - policy_entry_destroy(policy); - - /* decrease appropriate counter */ - unrouted ? found->trapcount-- : found->activecount--; - - if (found->trapcount == 0) - { - /* if this policy is finally unrouted, we reset the reqid because it - * may still be actively used and there might be a pending acquire for - * this policy. */ - found->reqid = 0; - } - - if (found->activecount > 0) - { - /* is still used by SAs, keep in kernel */ - this->mutex->unlock(this->mutex); - DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed"); - return SUCCESS; - } - else if (found->activecount == 0 && found->trapcount > 0) - { - /* for a policy that is not used actively anymore, but is still trapped - * by another child SA we replace the current eroute with a %trap eroute */ - DBG2(DBG_KNL, "policy still routed by another CHILD_SA, not removed"); - memset(&request, 0, sizeof(request)); - build_addflow(msg, SADB_X_SATYPE_INT, htonl(SPI_TRAP), NULL, NULL, - found->src.net, found->src.mask, found->dst.net, - found->dst.mask, found->src.proto, TRUE); - this->mutex->unlock(this->mutex); - return pfkey_send_ack(this, msg); - } - - /* remove if last reference */ - this->policies->remove(this->policies, found, NULL); - policy = found; - - this->mutex->unlock(this->mutex); - - memset(&request, 0, sizeof(request)); - - build_delflow(msg, 0, policy->src.net, policy->src.mask, policy->dst.net, - policy->dst.mask, policy->src.proto); - - route = policy->route; - policy->route = NULL; - policy_entry_destroy(policy); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to delete policy %R === %R %N: %s (%d)", src_ts, - dst_ts, policy_dir_names, direction, - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - - if (route) - { - ipsec_dev_t *dev; - - if (charon->kernel_interface->del_route(charon->kernel_interface, - route->dst_net, route->prefixlen, route->gateway, - route->src_ip, route->if_name) != SUCCESS) - { - DBG1(DBG_KNL, "error uninstalling route installed with" - " policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - } - - /* we have to detach the ipsec interface from the physical one over which - * this SA ran (if it is not used by any other) */ - this->mutex->lock(this->mutex); - - if (find_ipsec_dev(this, route->if_name, &dev) == SUCCESS) - { - /* fine, we found a matching device object, let's check if we have - * to detach it. */ - if (--dev->refcount == 0) - { - if (detach_ipsec_dev(dev->name, dev->phys_name) != SUCCESS) - { - DBG1(DBG_KNL, "failed to detach virtual interface %s" - " from %s", dev->name, dev->phys_name); - } - dev->phys_name[0] = '\0'; - } - } - - this->mutex->unlock(this->mutex); - - route_entry_destroy(route); - } - - return SUCCESS; -} - -/** - * Initialize the list of ipsec devices - */ -static void init_ipsec_devices(private_kernel_klips_ipsec_t *this) -{ - int i, count = lib->settings->get_int(lib->settings, - "charon.plugins.kernel-klips.ipsec_dev_count", - DEFAULT_IPSEC_DEV_COUNT); - - for (i = 0; i < count; ++i) - { - ipsec_dev_t *dev = malloc_thing(ipsec_dev_t); - snprintf(dev->name, IFNAMSIZ, IPSEC_DEV_PREFIX"%d", i); - dev->name[IFNAMSIZ - 1] = '\0'; - dev->phys_name[0] = '\0'; - dev->refcount = 0; - this->ipsec_devices->insert_last(this->ipsec_devices, dev); - - /* detach any previously attached ipsec device */ - detach_ipsec_dev(dev->name, dev->phys_name); - } -} - -/** - * Register a socket for AQUIRE/EXPIRE messages - */ -static status_t register_pfkey_socket(private_kernel_klips_ipsec_t *this, u_int8_t satype) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - size_t len; - - memset(&request, 0, sizeof(request)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_REGISTER; - msg->sadb_msg_satype = satype; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - if (pfkey_send_socket(this, this->socket_events, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to register PF_KEY socket"); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to register PF_KEY socket: %s (%d)", - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, bypass_socket, bool, - private_kernel_klips_ipsec_t *this, int fd, int family) -{ - /* KLIPS does not need a bypass policy for IKE */ - return TRUE; -} - -METHOD(kernel_ipsec_t, destroy, void, - private_kernel_klips_ipsec_t *this) -{ - if (this->job) - { - this->job->cancel(this->job); - } - if (this->socket > 0) - { - close(this->socket); - } - if (this->socket_events > 0) - { - close(this->socket_events); - } - this->mutex_pfkey->destroy(this->mutex_pfkey); - this->mutex->destroy(this->mutex); - this->ipsec_devices->destroy_function(this->ipsec_devices, (void*)ipsec_dev_destroy); - this->installed_sas->destroy_function(this->installed_sas, (void*)sa_entry_destroy); - this->allocated_spis->destroy_function(this->allocated_spis, (void*)sa_entry_destroy); - this->policies->destroy_function(this->policies, (void*)policy_entry_destroy); - free(this); -} - -/* - * Described in header. - */ -kernel_klips_ipsec_t *kernel_klips_ipsec_create() -{ - private_kernel_klips_ipsec_t *this; - - INIT(this, - .public.interface = { - .get_spi = _get_spi, - .get_cpi = _get_cpi, - .add_sa = _add_sa, - .update_sa = _update_sa, - .query_sa = _query_sa, - .del_sa = _del_sa, - .add_policy = _add_policy, - .query_policy = _query_policy, - .del_policy = _del_policy, - .bypass_socket = _bypass_socket, - .destroy = _destroy, - }, - .policies = linked_list_create(), - .allocated_spis = linked_list_create(), - .installed_sas = linked_list_create(), - .ipsec_devices = linked_list_create(), - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT), - .install_routes = lib->settings->get_bool(lib->settings, - "charon.install_routes", TRUE), - ); - - /* initialize ipsec devices */ - init_ipsec_devices(this); - - /* create a PF_KEY socket to communicate with the kernel */ - this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); - if (this->socket <= 0) - { - DBG1(DBG_KNL, "unable to create PF_KEY socket"); - destroy(this); - return NULL; - } - - /* create a PF_KEY socket for ACQUIRE & EXPIRE */ - this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); - if (this->socket_events <= 0) - { - DBG1(DBG_KNL, "unable to create PF_KEY event socket"); - destroy(this); - return NULL; - } - - /* register the event socket */ - if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS || - register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS) - { - DBG1(DBG_KNL, "unable to register PF_KEY event socket"); - destroy(this); - return NULL; - } - - this->job = callback_job_create((callback_job_cb_t)receive_events, - this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); - - return &this->public; -} - diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.h b/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.h deleted file mode 100644 index 306ec0ada..000000000 --- a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 kernel_klips_ipsec_i kernel_klips_ipsec - * @{ @ingroup kernel_klips - */ - -#ifndef KERNEL_KLIPS_IPSEC_H_ -#define KERNEL_KLIPS_IPSEC_H_ - -#include <kernel/kernel_ipsec.h> - -typedef struct kernel_klips_ipsec_t kernel_klips_ipsec_t; - -/** - * Implementation of the kernel ipsec interface using PF_KEY. - */ -struct kernel_klips_ipsec_t { - - /** - * Implements kernel_ipsec_t interface - */ - kernel_ipsec_t interface; -}; - -/** - * Create a PF_KEY kernel ipsec interface instance. - * - * @return kernel_klips_ipsec_t instance - */ -kernel_klips_ipsec_t *kernel_klips_ipsec_create(); - -#endif /** KERNEL_KLIPS_IPSEC_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.c b/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.c deleted file mode 100644 index fa5e9eb29..000000000 --- a/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 "kernel_klips_plugin.h" - -#include "kernel_klips_ipsec.h" - -#include <daemon.h> - -typedef struct private_kernel_klips_plugin_t private_kernel_klips_plugin_t; - -/** - * private data of kernel PF_KEY plugin - */ -struct private_kernel_klips_plugin_t { - /** - * implements plugin interface - */ - kernel_klips_plugin_t public; -}; - -/** - * Implementation of plugin_t.destroy - */ -static void destroy(private_kernel_klips_plugin_t *this) -{ - charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_klips_ipsec_create); - free(this); -} - -/* - * see header file - */ -plugin_t *kernel_klips_plugin_create() -{ - private_kernel_klips_plugin_t *this = malloc_thing(private_kernel_klips_plugin_t); - - this->public.plugin.destroy = (void(*)(plugin_t*))destroy; - - charon->kernel_interface->add_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_klips_ipsec_create); - - return &this->public.plugin; -} diff --git a/src/libcharon/plugins/kernel_klips/pfkeyv2.h b/src/libcharon/plugins/kernel_klips/pfkeyv2.h deleted file mode 100644 index 20d1c298d..000000000 --- a/src/libcharon/plugins/kernel_klips/pfkeyv2.h +++ /dev/null @@ -1,322 +0,0 @@ -/* -RFC 2367 PF_KEY Key Management API July 1998 - - -Appendix D: Sample Header File - -This file defines structures and symbols for the PF_KEY Version 2 -key management interface. It was written at the U.S. Naval Research -Laboratory. This file is in the public domain. The authors ask that -you leave this credit intact on any copies of this file. -*/ -#ifndef __PFKEY_V2_H -#define __PFKEY_V2_H 1 - -#define PF_KEY_V2 2 -#define PFKEYV2_REVISION 199806L - -#define SADB_RESERVED 0 -#define SADB_GETSPI 1 -#define SADB_UPDATE 2 -#define SADB_ADD 3 -#define SADB_DELETE 4 -#define SADB_GET 5 -#define SADB_ACQUIRE 6 -#define SADB_REGISTER 7 -#define SADB_EXPIRE 8 -#define SADB_FLUSH 9 -#define SADB_DUMP 10 -#define SADB_X_PROMISC 11 -#define SADB_X_PCHANGE 12 -#define SADB_X_GRPSA 13 -#define SADB_X_ADDFLOW 14 -#define SADB_X_DELFLOW 15 -#define SADB_X_DEBUG 16 -#define SADB_X_NAT_T_NEW_MAPPING 17 -#define SADB_MAX 17 - -struct sadb_msg { - uint8_t sadb_msg_version; - uint8_t sadb_msg_type; - uint8_t sadb_msg_errno; - uint8_t sadb_msg_satype; - uint16_t sadb_msg_len; - uint16_t sadb_msg_reserved; - uint32_t sadb_msg_seq; - uint32_t sadb_msg_pid; -}; - -struct sadb_ext { - uint16_t sadb_ext_len; - uint16_t sadb_ext_type; -}; - -struct sadb_sa { - uint16_t sadb_sa_len; - uint16_t sadb_sa_exttype; - uint32_t sadb_sa_spi; - uint8_t sadb_sa_replay; - uint8_t sadb_sa_state; - uint8_t sadb_sa_auth; - uint8_t sadb_sa_encrypt; - uint32_t sadb_sa_flags; -}; - -struct sadb_lifetime { - uint16_t sadb_lifetime_len; - uint16_t sadb_lifetime_exttype; - uint32_t sadb_lifetime_allocations; - uint64_t sadb_lifetime_bytes; - uint64_t sadb_lifetime_addtime; - uint64_t sadb_lifetime_usetime; - uint32_t sadb_x_lifetime_packets; - uint32_t sadb_x_lifetime_reserved; -}; - -struct sadb_address { - uint16_t sadb_address_len; - uint16_t sadb_address_exttype; - uint8_t sadb_address_proto; - uint8_t sadb_address_prefixlen; - uint16_t sadb_address_reserved; -}; - -struct sadb_key { - uint16_t sadb_key_len; - uint16_t sadb_key_exttype; - uint16_t sadb_key_bits; - uint16_t sadb_key_reserved; -}; - -struct sadb_ident { - uint16_t sadb_ident_len; - uint16_t sadb_ident_exttype; - uint16_t sadb_ident_type; - uint16_t sadb_ident_reserved; - uint64_t sadb_ident_id; -}; - -struct sadb_sens { - uint16_t sadb_sens_len; - uint16_t sadb_sens_exttype; - uint32_t sadb_sens_dpd; - uint8_t sadb_sens_sens_level; - uint8_t sadb_sens_sens_len; - uint8_t sadb_sens_integ_level; - uint8_t sadb_sens_integ_len; - uint32_t sadb_sens_reserved; -}; - -struct sadb_prop { - uint16_t sadb_prop_len; - uint16_t sadb_prop_exttype; - uint8_t sadb_prop_replay; - uint8_t sadb_prop_reserved[3]; -}; - -struct sadb_comb { - uint8_t sadb_comb_auth; - uint8_t sadb_comb_encrypt; - uint16_t sadb_comb_flags; - uint16_t sadb_comb_auth_minbits; - uint16_t sadb_comb_auth_maxbits; - uint16_t sadb_comb_encrypt_minbits; - uint16_t sadb_comb_encrypt_maxbits; - uint32_t sadb_comb_reserved; - uint32_t sadb_comb_soft_allocations; - uint32_t sadb_comb_hard_allocations; - uint64_t sadb_comb_soft_bytes; - uint64_t sadb_comb_hard_bytes; - uint64_t sadb_comb_soft_addtime; - uint64_t sadb_comb_hard_addtime; - uint64_t sadb_comb_soft_usetime; - uint64_t sadb_comb_hard_usetime; - uint32_t sadb_x_comb_soft_packets; - uint32_t sadb_x_comb_hard_packets; -}; - -struct sadb_supported { - uint16_t sadb_supported_len; - uint16_t sadb_supported_exttype; - uint32_t sadb_supported_reserved; -}; - -struct sadb_alg { - uint8_t sadb_alg_id; - uint8_t sadb_alg_ivlen; - uint16_t sadb_alg_minbits; - uint16_t sadb_alg_maxbits; - uint16_t sadb_alg_reserved; -}; - -struct sadb_spirange { - uint16_t sadb_spirange_len; - uint16_t sadb_spirange_exttype; - uint32_t sadb_spirange_min; - uint32_t sadb_spirange_max; - uint32_t sadb_spirange_reserved; -}; - -struct sadb_x_kmprivate { - uint16_t sadb_x_kmprivate_len; - uint16_t sadb_x_kmprivate_exttype; - uint32_t sadb_x_kmprivate_reserved; -}; - -struct sadb_x_satype { - uint16_t sadb_x_satype_len; - uint16_t sadb_x_satype_exttype; - uint8_t sadb_x_satype_satype; - uint8_t sadb_x_satype_reserved[3]; -}; - -struct sadb_x_debug { - uint16_t sadb_x_debug_len; - uint16_t sadb_x_debug_exttype; - uint32_t sadb_x_debug_tunnel; - uint32_t sadb_x_debug_netlink; - uint32_t sadb_x_debug_xform; - uint32_t sadb_x_debug_eroute; - uint32_t sadb_x_debug_spi; - uint32_t sadb_x_debug_radij; - uint32_t sadb_x_debug_esp; - uint32_t sadb_x_debug_ah; - uint32_t sadb_x_debug_rcv; - uint32_t sadb_x_debug_pfkey; - uint32_t sadb_x_debug_ipcomp; - uint32_t sadb_x_debug_verbose; - uint8_t sadb_x_debug_reserved[4]; -}; - -struct sadb_x_nat_t_type { - uint16_t sadb_x_nat_t_type_len; - uint16_t sadb_x_nat_t_type_exttype; - uint8_t sadb_x_nat_t_type_type; - uint8_t sadb_x_nat_t_type_reserved[3]; -}; -struct sadb_x_nat_t_port { - uint16_t sadb_x_nat_t_port_len; - uint16_t sadb_x_nat_t_port_exttype; - uint16_t sadb_x_nat_t_port_port; - uint16_t sadb_x_nat_t_port_reserved; -}; - -/* - * A protocol structure for passing through the transport level - * protocol. It contains more fields than are actually used/needed - * but it is this way to be compatible with the structure used in - * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h) - */ -struct sadb_protocol { - uint16_t sadb_protocol_len; - uint16_t sadb_protocol_exttype; - uint8_t sadb_protocol_proto; - uint8_t sadb_protocol_direction; - uint8_t sadb_protocol_flags; - uint8_t sadb_protocol_reserved2; -}; - -#define SADB_EXT_RESERVED 0 -#define SADB_EXT_SA 1 -#define SADB_EXT_LIFETIME_CURRENT 2 -#define SADB_EXT_LIFETIME_HARD 3 -#define SADB_EXT_LIFETIME_SOFT 4 -#define SADB_EXT_ADDRESS_SRC 5 -#define SADB_EXT_ADDRESS_DST 6 -#define SADB_EXT_ADDRESS_PROXY 7 -#define SADB_EXT_KEY_AUTH 8 -#define SADB_EXT_KEY_ENCRYPT 9 -#define SADB_EXT_IDENTITY_SRC 10 -#define SADB_EXT_IDENTITY_DST 11 -#define SADB_EXT_SENSITIVITY 12 -#define SADB_EXT_PROPOSAL 13 -#define SADB_EXT_SUPPORTED_AUTH 14 -#define SADB_EXT_SUPPORTED_ENCRYPT 15 -#define SADB_EXT_SPIRANGE 16 -#define SADB_X_EXT_KMPRIVATE 17 -#define SADB_X_EXT_SATYPE2 18 -#define SADB_X_EXT_SA2 19 -#define SADB_X_EXT_ADDRESS_DST2 20 -#define SADB_X_EXT_ADDRESS_SRC_FLOW 21 -#define SADB_X_EXT_ADDRESS_DST_FLOW 22 -#define SADB_X_EXT_ADDRESS_SRC_MASK 23 -#define SADB_X_EXT_ADDRESS_DST_MASK 24 -#define SADB_X_EXT_DEBUG 25 -#define SADB_X_EXT_PROTOCOL 26 -#define SADB_X_EXT_NAT_T_TYPE 27 -#define SADB_X_EXT_NAT_T_SPORT 28 -#define SADB_X_EXT_NAT_T_DPORT 29 -#define SADB_X_EXT_NAT_T_OA 30 -#define SADB_EXT_MAX 30 - -/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */ -#define SADB_X_EXT_ADDRESS_DELFLOW \ - ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \ - | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \ - | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \ - | (1<<SADB_X_EXT_ADDRESS_DST_MASK)) - -#define SADB_SATYPE_UNSPEC 0 -#define SADB_SATYPE_AH 2 -#define SADB_SATYPE_ESP 3 -#define SADB_SATYPE_RSVP 5 -#define SADB_SATYPE_OSPFV2 6 -#define SADB_SATYPE_RIPV2 7 -#define SADB_SATYPE_MIP 8 -#define SADB_X_SATYPE_IPIP 9 -#define SADB_X_SATYPE_COMP 10 -#define SADB_X_SATYPE_INT 11 -#define SADB_SATYPE_MAX 11 - -#define SADB_SASTATE_LARVAL 0 -#define SADB_SASTATE_MATURE 1 -#define SADB_SASTATE_DYING 2 -#define SADB_SASTATE_DEAD 3 -#define SADB_SASTATE_MAX 3 - -#define SADB_SAFLAGS_PFS 1 -#define SADB_X_SAFLAGS_REPLACEFLOW 2 -#define SADB_X_SAFLAGS_CLEARFLOW 4 -#define SADB_X_SAFLAGS_INFLOW 8 - -#define SADB_AALG_NONE 0 -#define SADB_AALG_MD5HMAC 2 -#define SADB_AALG_SHA1HMAC 3 -#define SADB_AALG_SHA256_HMAC 5 -#define SADB_AALG_SHA384_HMAC 6 -#define SADB_AALG_SHA512_HMAC 7 -#define SADB_AALG_RIPEMD160HMAC 8 -#define SADB_AALG_MAX 15 - -#define SADB_EALG_NONE 0 -#define SADB_EALG_DESCBC 2 -#define SADB_EALG_3DESCBC 3 -#define SADB_EALG_BFCBC 7 -#define SADB_EALG_NULL 11 -#define SADB_EALG_AESCBC 12 -#define SADB_EALG_MAX 255 - -#define SADB_X_CALG_NONE 0 -#define SADB_X_CALG_OUI 1 -#define SADB_X_CALG_DEFLATE 2 -#define SADB_X_CALG_LZS 3 -#define SADB_X_CALG_V42BIS 4 -#define SADB_X_CALG_MAX 4 - -#define SADB_X_TALG_NONE 0 -#define SADB_X_TALG_IPv4_in_IPv4 1 -#define SADB_X_TALG_IPv6_in_IPv4 2 -#define SADB_X_TALG_IPv4_in_IPv6 3 -#define SADB_X_TALG_IPv6_in_IPv6 4 -#define SADB_X_TALG_MAX 4 - - -#define SADB_IDENTTYPE_RESERVED 0 -#define SADB_IDENTTYPE_PREFIX 1 -#define SADB_IDENTTYPE_FQDN 2 -#define SADB_IDENTTYPE_USERFQDN 3 -#define SADB_X_IDENTTYPE_CONNECTION 4 -#define SADB_IDENTTYPE_MAX 4 - -#define SADB_KEY_FLAGS_MAX 0 -#endif /* __PFKEY_V2_H */ diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.am b/src/libcharon/plugins/kernel_netlink/Makefile.am deleted file mode 100644 index 2bb00ec0d..000000000 --- a/src/libcharon/plugins/kernel_netlink/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ - -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon - -AM_CFLAGS = -rdynamic \ --DROUTING_TABLE=${routing_table} \ --DROUTING_TABLE_PRIO=${routing_table_prio} - -if MONOLITHIC -noinst_LTLIBRARIES = libstrongswan-kernel-netlink.la -else -plugin_LTLIBRARIES = libstrongswan-kernel-netlink.la -endif - -libstrongswan_kernel_netlink_la_SOURCES = \ - kernel_netlink_plugin.h kernel_netlink_plugin.c \ - kernel_netlink_ipsec.h kernel_netlink_ipsec.c kernel_netlink_net.h kernel_netlink_net.c \ - kernel_netlink_shared.h kernel_netlink_shared.c - -libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c deleted file mode 100644 index 019ec93f8..000000000 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ /dev/null @@ -1,2265 +0,0 @@ -/* - * Copyright (C) 2006-2009 Tobias Brunner - * Copyright (C) 2005-2009 Martin Willi - * Copyright (C) 2008 Andreas Steffen - * Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser - * Copyright (C) 2006 Daniel Roethlisberger - * Copyright (C) 2005 Jan Hutter - * 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 <sys/types.h> -#include <sys/socket.h> -#include <stdint.h> -#include <linux/ipsec.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <linux/xfrm.h> -#include <linux/udp.h> -#include <unistd.h> -#include <time.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> - -#include "kernel_netlink_ipsec.h" -#include "kernel_netlink_shared.h" - -#include <daemon.h> -#include <threading/thread.h> -#include <threading/mutex.h> -#include <utils/hashtable.h> -#include <processing/jobs/callback_job.h> -#include <processing/jobs/acquire_job.h> -#include <processing/jobs/migrate_job.h> -#include <processing/jobs/rekey_child_sa_job.h> -#include <processing/jobs/delete_child_sa_job.h> -#include <processing/jobs/update_sa_job.h> - -/** required for Linux 2.6.26 kernel and later */ -#ifndef XFRM_STATE_AF_UNSPEC -#define XFRM_STATE_AF_UNSPEC 32 -#endif - -/** from linux/in.h */ -#ifndef IP_XFRM_POLICY -#define IP_XFRM_POLICY 17 -#endif - -/* missing on uclibc */ -#ifndef IPV6_XFRM_POLICY -#define IPV6_XFRM_POLICY 34 -#endif /*IPV6_XFRM_POLICY*/ - -/** default priority of installed policies */ -#define PRIO_LOW 3000 -#define PRIO_HIGH 2000 - -/** - * map the limit for bytes and packets to XFRM_INF per default - */ -#define XFRM_LIMIT(x) ((x) == 0 ? XFRM_INF : (x)) - -/** - * Create ORable bitfield of XFRM NL groups - */ -#define XFRMNLGRP(x) (1<<(XFRMNLGRP_##x-1)) - -/** - * returns a pointer to the first rtattr following the nlmsghdr *nlh and the - * 'usual' netlink data x like 'struct xfrm_usersa_info' - */ -#define XFRM_RTA(nlh, x) ((struct rtattr*)(NLMSG_DATA(nlh) + NLMSG_ALIGN(sizeof(x)))) -/** - * returns a pointer to the next rtattr following rta. - * !!! do not use this to parse messages. use RTA_NEXT and RTA_OK instead !!! - */ -#define XFRM_RTA_NEXT(rta) ((struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len))) -/** - * returns the total size of attached rta data - * (after 'usual' netlink data x like 'struct xfrm_usersa_info') - */ -#define XFRM_PAYLOAD(nlh, x) NLMSG_PAYLOAD(nlh, sizeof(x)) - -typedef struct kernel_algorithm_t kernel_algorithm_t; - -/** - * Mapping of IKEv2 kernel identifier to linux crypto API names - */ -struct kernel_algorithm_t { - /** - * Identifier specified in IKEv2 - */ - int ikev2; - - /** - * Name of the algorithm in linux crypto API - */ - char *name; -}; - -ENUM(xfrm_msg_names, XFRM_MSG_NEWSA, XFRM_MSG_MAPPING, - "XFRM_MSG_NEWSA", - "XFRM_MSG_DELSA", - "XFRM_MSG_GETSA", - "XFRM_MSG_NEWPOLICY", - "XFRM_MSG_DELPOLICY", - "XFRM_MSG_GETPOLICY", - "XFRM_MSG_ALLOCSPI", - "XFRM_MSG_ACQUIRE", - "XFRM_MSG_EXPIRE", - "XFRM_MSG_UPDPOLICY", - "XFRM_MSG_UPDSA", - "XFRM_MSG_POLEXPIRE", - "XFRM_MSG_FLUSHSA", - "XFRM_MSG_FLUSHPOLICY", - "XFRM_MSG_NEWAE", - "XFRM_MSG_GETAE", - "XFRM_MSG_REPORT", - "XFRM_MSG_MIGRATE", - "XFRM_MSG_NEWSADINFO", - "XFRM_MSG_GETSADINFO", - "XFRM_MSG_NEWSPDINFO", - "XFRM_MSG_GETSPDINFO", - "XFRM_MSG_MAPPING" -); - -ENUM(xfrm_attr_type_names, XFRMA_UNSPEC, XFRMA_KMADDRESS, - "XFRMA_UNSPEC", - "XFRMA_ALG_AUTH", - "XFRMA_ALG_CRYPT", - "XFRMA_ALG_COMP", - "XFRMA_ENCAP", - "XFRMA_TMPL", - "XFRMA_SA", - "XFRMA_POLICY", - "XFRMA_SEC_CTX", - "XFRMA_LTIME_VAL", - "XFRMA_REPLAY_VAL", - "XFRMA_REPLAY_THRESH", - "XFRMA_ETIMER_THRESH", - "XFRMA_SRCADDR", - "XFRMA_COADDR", - "XFRMA_LASTUSED", - "XFRMA_POLICY_TYPE", - "XFRMA_MIGRATE", - "XFRMA_ALG_AEAD", - "XFRMA_KMADDRESS" -); - -#define END_OF_LIST -1 - -/** - * Algorithms for encryption - */ -static kernel_algorithm_t encryption_algs[] = { -/* {ENCR_DES_IV64, "***" }, */ - {ENCR_DES, "des" }, - {ENCR_3DES, "des3_ede" }, -/* {ENCR_RC5, "***" }, */ -/* {ENCR_IDEA, "***" }, */ - {ENCR_CAST, "cast128" }, - {ENCR_BLOWFISH, "blowfish" }, -/* {ENCR_3IDEA, "***" }, */ -/* {ENCR_DES_IV32, "***" }, */ - {ENCR_NULL, "cipher_null" }, - {ENCR_AES_CBC, "aes" }, - {ENCR_AES_CTR, "rfc3686(ctr(aes))" }, - {ENCR_AES_CCM_ICV8, "rfc4309(ccm(aes))" }, - {ENCR_AES_CCM_ICV12, "rfc4309(ccm(aes))" }, - {ENCR_AES_CCM_ICV16, "rfc4309(ccm(aes))" }, - {ENCR_AES_GCM_ICV8, "rfc4106(gcm(aes))" }, - {ENCR_AES_GCM_ICV12, "rfc4106(gcm(aes))" }, - {ENCR_AES_GCM_ICV16, "rfc4106(gcm(aes))" }, - {ENCR_NULL_AUTH_AES_GMAC, "rfc4543(gcm(aes))" }, - {ENCR_CAMELLIA_CBC, "cbc(camellia)" }, -/* {ENCR_CAMELLIA_CTR, "***" }, */ -/* {ENCR_CAMELLIA_CCM_ICV8, "***" }, */ -/* {ENCR_CAMELLIA_CCM_ICV12, "***" }, */ -/* {ENCR_CAMELLIA_CCM_ICV16, "***" }, */ - {END_OF_LIST, NULL } -}; - -/** - * Algorithms for integrity protection - */ -static kernel_algorithm_t integrity_algs[] = { - {AUTH_HMAC_MD5_96, "md5" }, - {AUTH_HMAC_SHA1_96, "sha1" }, - {AUTH_HMAC_SHA2_256_96, "sha256" }, - {AUTH_HMAC_SHA2_256_128, "hmac(sha256)" }, - {AUTH_HMAC_SHA2_384_192, "hmac(sha384)" }, - {AUTH_HMAC_SHA2_512_256, "hmac(sha512)" }, -/* {AUTH_DES_MAC, "***" }, */ -/* {AUTH_KPDK_MD5, "***" }, */ - {AUTH_AES_XCBC_96, "xcbc(aes)" }, - {END_OF_LIST, NULL } -}; - -/** - * Algorithms for IPComp - */ -static kernel_algorithm_t compression_algs[] = { -/* {IPCOMP_OUI, "***" }, */ - {IPCOMP_DEFLATE, "deflate" }, - {IPCOMP_LZS, "lzs" }, - {IPCOMP_LZJH, "lzjh" }, - {END_OF_LIST, NULL } -}; - -/** - * Look up a kernel algorithm name and its key size - */ -static char* lookup_algorithm(kernel_algorithm_t *list, int ikev2) -{ - while (list->ikev2 != END_OF_LIST) - { - if (list->ikev2 == ikev2) - { - return list->name; - } - list++; - } - return NULL; -} - -typedef struct route_entry_t route_entry_t; - -/** - * installed routing entry - */ -struct route_entry_t { - /** Name of the interface the route is bound to */ - char *if_name; - - /** Source ip of the route */ - host_t *src_ip; - - /** gateway for this route */ - host_t *gateway; - - /** Destination net */ - chunk_t dst_net; - - /** Destination net prefixlen */ - u_int8_t prefixlen; -}; - -/** - * destroy an route_entry_t object - */ -static void route_entry_destroy(route_entry_t *this) -{ - free(this->if_name); - this->src_ip->destroy(this->src_ip); - DESTROY_IF(this->gateway); - chunk_free(&this->dst_net); - free(this); -} - -typedef struct policy_entry_t policy_entry_t; - -/** - * installed kernel policy. - */ -struct policy_entry_t { - - /** direction of this policy: in, out, forward */ - u_int8_t direction; - - /** parameters of installed policy */ - struct xfrm_selector sel; - - /** optional mark */ - u_int32_t mark; - - /** associated route installed for this policy */ - route_entry_t *route; - - /** by how many CHILD_SA's this policy is used */ - u_int refcount; -}; - -/** - * Hash function for policy_entry_t objects - */ -static u_int policy_hash(policy_entry_t *key) -{ - chunk_t chunk = chunk_create((void*)&key->sel, - sizeof(struct xfrm_selector) + sizeof(u_int32_t)); - return chunk_hash(chunk); -} - -/** - * Equality function for policy_entry_t objects - */ -static bool policy_equals(policy_entry_t *key, policy_entry_t *other_key) -{ - return memeq(&key->sel, &other_key->sel, - sizeof(struct xfrm_selector) + sizeof(u_int32_t)) && - key->direction == other_key->direction; -} - -typedef struct private_kernel_netlink_ipsec_t private_kernel_netlink_ipsec_t; - -/** - * Private variables and functions of kernel_netlink class. - */ -struct private_kernel_netlink_ipsec_t { - /** - * Public part of the kernel_netlink_t object. - */ - kernel_netlink_ipsec_t public; - - /** - * mutex to lock access to various lists - */ - mutex_t *mutex; - - /** - * Hash table of installed policies (policy_entry_t) - */ - hashtable_t *policies; - - /** - * job receiving netlink events - */ - callback_job_t *job; - - /** - * Netlink xfrm socket (IPsec) - */ - netlink_socket_t *socket_xfrm; - - /** - * netlink xfrm socket to receive acquire and expire events - */ - int socket_xfrm_events; - - /** - * whether to install routes along policies - */ - bool install_routes; -}; - -/** - * convert a IKEv2 specific protocol identifier to the kernel one - */ -static u_int8_t proto_ike2kernel(protocol_id_t proto) -{ - switch (proto) - { - case PROTO_ESP: - return IPPROTO_ESP; - case PROTO_AH: - return IPPROTO_AH; - default: - return proto; - } -} - -/** - * reverse of ike2kernel - */ -static protocol_id_t proto_kernel2ike(u_int8_t proto) -{ - switch (proto) - { - case IPPROTO_ESP: - return PROTO_ESP; - case IPPROTO_AH: - return PROTO_AH; - default: - return proto; - } -} - -/** - * convert the general ipsec mode to the one defined in xfrm.h - */ -static u_int8_t mode2kernel(ipsec_mode_t mode) -{ - switch (mode) - { - case MODE_TRANSPORT: - return XFRM_MODE_TRANSPORT; - case MODE_TUNNEL: - return XFRM_MODE_TUNNEL; - case MODE_BEET: - return XFRM_MODE_BEET; - default: - return mode; - } -} - -/** - * convert a host_t to a struct xfrm_address - */ -static void host2xfrm(host_t *host, xfrm_address_t *xfrm) -{ - chunk_t chunk = host->get_address(host); - memcpy(xfrm, chunk.ptr, min(chunk.len, sizeof(xfrm_address_t))); -} - -/** - * convert a struct xfrm_address to a host_t - */ -static host_t* xfrm2host(int family, xfrm_address_t *xfrm, u_int16_t port) -{ - chunk_t chunk; - - switch (family) - { - case AF_INET: - chunk = chunk_create((u_char*)&xfrm->a4, sizeof(xfrm->a4)); - break; - case AF_INET6: - chunk = chunk_create((u_char*)&xfrm->a6, sizeof(xfrm->a6)); - break; - default: - return NULL; - } - return host_create_from_chunk(family, chunk, ntohs(port)); -} - -/** - * convert a traffic selector address range to subnet and its mask. - */ -static void ts2subnet(traffic_selector_t* ts, - xfrm_address_t *net, u_int8_t *mask) -{ - host_t *net_host; - chunk_t net_chunk; - - ts->to_subnet(ts, &net_host, mask); - net_chunk = net_host->get_address(net_host); - memcpy(net, net_chunk.ptr, net_chunk.len); - net_host->destroy(net_host); -} - -/** - * convert a traffic selector port range to port/portmask - */ -static void ts2ports(traffic_selector_t* ts, - u_int16_t *port, u_int16_t *mask) -{ - /* linux does not seem to accept complex portmasks. Only - * any or a specific port is allowed. We set to any, if we have - * a port range, or to a specific, if we have one port only. - */ - u_int16_t from, to; - - from = ts->get_from_port(ts); - to = ts->get_to_port(ts); - - if (from == to) - { - *port = htons(from); - *mask = ~0; - } - else - { - *port = 0; - *mask = 0; - } -} - -/** - * convert a pair of traffic_selectors to a xfrm_selector - */ -static struct xfrm_selector ts2selector(traffic_selector_t *src, - traffic_selector_t *dst) -{ - struct xfrm_selector sel; - - memset(&sel, 0, sizeof(sel)); - sel.family = (src->get_type(src) == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6; - /* src or dest proto may be "any" (0), use more restrictive one */ - sel.proto = max(src->get_protocol(src), dst->get_protocol(dst)); - ts2subnet(dst, &sel.daddr, &sel.prefixlen_d); - ts2subnet(src, &sel.saddr, &sel.prefixlen_s); - ts2ports(dst, &sel.dport, &sel.dport_mask); - ts2ports(src, &sel.sport, &sel.sport_mask); - sel.ifindex = 0; - sel.user = 0; - - return sel; -} - -/** - * convert a xfrm_selector to a src|dst traffic_selector - */ -static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src) -{ - u_char *addr; - u_int8_t prefixlen; - u_int16_t port = 0; - host_t *host = NULL; - - if (src) - { - addr = (u_char*)&sel->saddr; - prefixlen = sel->prefixlen_s; - if (sel->sport_mask) - { - port = htons(sel->sport); - } - } - else - { - addr = (u_char*)&sel->daddr; - prefixlen = sel->prefixlen_d; - if (sel->dport_mask) - { - port = htons(sel->dport); - } - } - - /* The Linux 2.6 kernel does not set the selector's family field, - * so as a kludge we additionally test the prefix length. - */ - if (sel->family == AF_INET || sel->prefixlen_s == 32) - { - host = host_create_from_chunk(AF_INET, chunk_create(addr, 4), 0); - } - else if (sel->family == AF_INET6 || sel->prefixlen_s == 128) - { - host = host_create_from_chunk(AF_INET6, chunk_create(addr, 16), 0); - } - - if (host) - { - return traffic_selector_create_from_subnet(host, prefixlen, - sel->proto, port); - } - return NULL; -} - -/** - * process a XFRM_MSG_ACQUIRE from kernel - */ -static void process_acquire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr) -{ - u_int32_t reqid = 0; - int proto = 0; - traffic_selector_t *src_ts, *dst_ts; - struct xfrm_user_acquire *acquire; - struct rtattr *rta; - size_t rtasize; - job_t *job; - - acquire = (struct xfrm_user_acquire*)NLMSG_DATA(hdr); - rta = XFRM_RTA(hdr, struct xfrm_user_acquire); - rtasize = XFRM_PAYLOAD(hdr, struct xfrm_user_acquire); - - DBG2(DBG_KNL, "received a XFRM_MSG_ACQUIRE"); - - while (RTA_OK(rta, rtasize)) - { - DBG2(DBG_KNL, " %N", xfrm_attr_type_names, rta->rta_type); - - if (rta->rta_type == XFRMA_TMPL) - { - struct xfrm_user_tmpl* tmpl; - - tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rta); - reqid = tmpl->reqid; - proto = tmpl->id.proto; - } - rta = RTA_NEXT(rta, rtasize); - } - switch (proto) - { - case 0: - case IPPROTO_ESP: - case IPPROTO_AH: - break; - default: - /* acquire for AH/ESP only, not for IPCOMP */ - return; - } - src_ts = selector2ts(&acquire->sel, TRUE); - dst_ts = selector2ts(&acquire->sel, FALSE); - DBG1(DBG_KNL, "creating acquire job for policy %R === %R with reqid {%u}", - src_ts, dst_ts, reqid); - job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts); - charon->processor->queue_job(charon->processor, job); -} - -/** - * process a XFRM_MSG_EXPIRE from kernel - */ -static void process_expire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr) -{ - job_t *job; - protocol_id_t protocol; - u_int32_t spi, reqid; - struct xfrm_user_expire *expire; - - expire = (struct xfrm_user_expire*)NLMSG_DATA(hdr); - protocol = proto_kernel2ike(expire->state.id.proto); - spi = expire->state.id.spi; - reqid = expire->state.reqid; - - DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE"); - - if (protocol != PROTO_ESP && protocol != PROTO_AH) - { - DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA with SPI %.8x and reqid {%u} " - "which is not a CHILD_SA", ntohl(spi), reqid); - return; - } - - DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%d}", - expire->hard ? "delete" : "rekey", protocol_id_names, - protocol, ntohl(spi), reqid); - if (expire->hard) - { - job = (job_t*)delete_child_sa_job_create(reqid, protocol, spi); - } - else - { - job = (job_t*)rekey_child_sa_job_create(reqid, protocol, spi); - } - charon->processor->queue_job(charon->processor, job); -} - -/** - * process a XFRM_MSG_MIGRATE from kernel - */ -static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr) -{ - traffic_selector_t *src_ts, *dst_ts; - host_t *local = NULL, *remote = NULL; - host_t *old_src = NULL, *old_dst = NULL; - host_t *new_src = NULL, *new_dst = NULL; - struct xfrm_userpolicy_id *policy_id; - struct rtattr *rta; - size_t rtasize; - u_int32_t reqid = 0; - policy_dir_t dir; - job_t *job; - - policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr); - rta = XFRM_RTA(hdr, struct xfrm_userpolicy_id); - rtasize = XFRM_PAYLOAD(hdr, struct xfrm_userpolicy_id); - - DBG2(DBG_KNL, "received a XFRM_MSG_MIGRATE"); - - src_ts = selector2ts(&policy_id->sel, TRUE); - dst_ts = selector2ts(&policy_id->sel, FALSE); - dir = (policy_dir_t)policy_id->dir; - - DBG2(DBG_KNL, " policy: %R === %R %N", src_ts, dst_ts, policy_dir_names); - - while (RTA_OK(rta, rtasize)) - { - DBG2(DBG_KNL, " %N", xfrm_attr_type_names, rta->rta_type); - if (rta->rta_type == XFRMA_KMADDRESS) - { - struct xfrm_user_kmaddress *kmaddress; - - kmaddress = (struct xfrm_user_kmaddress*)RTA_DATA(rta); - local = xfrm2host(kmaddress->family, &kmaddress->local, 0); - remote = xfrm2host(kmaddress->family, &kmaddress->remote, 0); - DBG2(DBG_KNL, " kmaddress: %H...%H", local, remote); - } - else if (rta->rta_type == XFRMA_MIGRATE) - { - struct xfrm_user_migrate *migrate; - protocol_id_t proto; - - migrate = (struct xfrm_user_migrate*)RTA_DATA(rta); - old_src = xfrm2host(migrate->old_family, &migrate->old_saddr, 0); - old_dst = xfrm2host(migrate->old_family, &migrate->old_daddr, 0); - new_src = xfrm2host(migrate->new_family, &migrate->new_saddr, 0); - new_dst = xfrm2host(migrate->new_family, &migrate->new_daddr, 0); - proto = proto_kernel2ike(migrate->proto); - reqid = migrate->reqid; - DBG2(DBG_KNL, " migrate %N %H...%H to %H...%H, reqid {%u}", - protocol_id_names, proto, old_src, old_dst, - new_src, new_dst, reqid); - DESTROY_IF(old_src); - DESTROY_IF(old_dst); - DESTROY_IF(new_src); - DESTROY_IF(new_dst); - } - rta = RTA_NEXT(rta, rtasize); - } - - if (src_ts && dst_ts && local && remote) - { - DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}", - src_ts, dst_ts, policy_dir_names, dir, reqid, local); - job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, dir, - local, remote); - charon->processor->queue_job(charon->processor, job); - } - else - { - DESTROY_IF(src_ts); - DESTROY_IF(dst_ts); - DESTROY_IF(local); - DESTROY_IF(remote); - } -} - -/** - * process a XFRM_MSG_MAPPING from kernel - */ -static void process_mapping(private_kernel_netlink_ipsec_t *this, - struct nlmsghdr *hdr) -{ - job_t *job; - u_int32_t spi, reqid; - struct xfrm_user_mapping *mapping; - host_t *host; - - mapping = (struct xfrm_user_mapping*)NLMSG_DATA(hdr); - spi = mapping->id.spi; - reqid = mapping->reqid; - - DBG2(DBG_KNL, "received a XFRM_MSG_MAPPING"); - - if (proto_kernel2ike(mapping->id.proto) == PROTO_ESP) - { - host = xfrm2host(mapping->id.family, &mapping->new_saddr, - mapping->new_sport); - if (host) - { - DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and " - "reqid {%u} changed, queuing update job", ntohl(spi), reqid); - job = (job_t*)update_sa_job_create(reqid, host); - charon->processor->queue_job(charon->processor, job); - } - } -} - -/** - * Receives events from kernel - */ -static job_requeue_t receive_events(private_kernel_netlink_ipsec_t *this) -{ - char response[1024]; - struct nlmsghdr *hdr = (struct nlmsghdr*)response; - struct sockaddr_nl addr; - socklen_t addr_len = sizeof(addr); - int len; - bool oldstate; - - oldstate = thread_cancelability(TRUE); - len = recvfrom(this->socket_xfrm_events, response, sizeof(response), 0, - (struct sockaddr*)&addr, &addr_len); - thread_cancelability(oldstate); - - if (len < 0) - { - switch (errno) - { - case EINTR: - /* interrupted, try again */ - return JOB_REQUEUE_DIRECT; - case EAGAIN: - /* no data ready, select again */ - return JOB_REQUEUE_DIRECT; - default: - DBG1(DBG_KNL, "unable to receive from xfrm event socket"); - sleep(1); - return JOB_REQUEUE_FAIR; - } - } - - if (addr.nl_pid != 0) - { /* not from kernel. not interested, try another one */ - return JOB_REQUEUE_DIRECT; - } - - while (NLMSG_OK(hdr, len)) - { - switch (hdr->nlmsg_type) - { - case XFRM_MSG_ACQUIRE: - process_acquire(this, hdr); - break; - case XFRM_MSG_EXPIRE: - process_expire(this, hdr); - break; - case XFRM_MSG_MIGRATE: - process_migrate(this, hdr); - break; - case XFRM_MSG_MAPPING: - process_mapping(this, hdr); - break; - default: - DBG1(DBG_KNL, "received unknown event from xfrm event socket: %d", hdr->nlmsg_type); - break; - } - hdr = NLMSG_NEXT(hdr, len); - } - return JOB_REQUEUE_DIRECT; -} - -/** - * Get an SPI for a specific protocol from the kernel. - */ -static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this, - host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max, - u_int32_t reqid, u_int32_t *spi) -{ - netlink_buf_t request; - struct nlmsghdr *hdr, *out; - struct xfrm_userspi_info *userspi; - u_int32_t received_spi = 0; - size_t len; - - memset(&request, 0, sizeof(request)); - - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST; - hdr->nlmsg_type = XFRM_MSG_ALLOCSPI; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)); - - userspi = (struct xfrm_userspi_info*)NLMSG_DATA(hdr); - host2xfrm(src, &userspi->info.saddr); - host2xfrm(dst, &userspi->info.id.daddr); - userspi->info.id.proto = proto; - userspi->info.mode = XFRM_MODE_TUNNEL; - userspi->info.reqid = reqid; - userspi->info.family = src->get_family(src); - userspi->min = min; - userspi->max = max; - - if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) - { - hdr = out; - while (NLMSG_OK(hdr, len)) - { - switch (hdr->nlmsg_type) - { - case XFRM_MSG_NEWSA: - { - struct xfrm_usersa_info* usersa = NLMSG_DATA(hdr); - received_spi = usersa->id.spi; - break; - } - case NLMSG_ERROR: - { - struct nlmsgerr *err = NLMSG_DATA(hdr); - - DBG1(DBG_KNL, "allocating SPI failed: %s (%d)", - strerror(-err->error), -err->error); - break; - } - default: - hdr = NLMSG_NEXT(hdr, len); - continue; - case NLMSG_DONE: - break; - } - break; - } - free(out); - } - - if (received_spi == 0) - { - return FAILED; - } - - *spi = received_spi; - return SUCCESS; -} - -METHOD(kernel_ipsec_t, get_spi, status_t, - private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, - protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi) -{ - DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid); - - if (get_spi_internal(this, src, dst, proto_ike2kernel(protocol), - 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS) - { - DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid); - return FAILED; - } - - DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, get_cpi, status_t, - private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) -{ - u_int32_t received_spi = 0; - - DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid); - - if (get_spi_internal(this, src, dst, - IPPROTO_COMP, 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS) - { - DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid); - return FAILED; - } - - *cpi = htons((u_int16_t)ntohl(received_spi)); - - DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, add_sa, status_t, - private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, u_int32_t reqid, mark_t mark, - 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 inbound, - traffic_selector_t* src_ts, traffic_selector_t* dst_ts) -{ - netlink_buf_t request; - char *alg_name; - struct nlmsghdr *hdr; - struct xfrm_usersa_info *sa; - u_int16_t icv_size = 64; - - /* if IPComp is used, we install an additional IPComp SA. if the cpi is 0 - * we are in the recursive call below */ - if (ipcomp != IPCOMP_NONE && cpi != 0) - { - lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}}; - add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark, - &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty, - mode, ipcomp, 0, FALSE, inbound, NULL, NULL); - ipcomp = IPCOMP_NONE; - /* use transport mode ESP SA, IPComp uses tunnel mode */ - mode = MODE_TRANSPORT; - } - - memset(&request, 0, sizeof(request)); - - if (mark.value) - { - DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u} " - "(mark %u/0x%8x)", ntohl(spi), reqid, mark.value, mark.mask); - } - else - { - DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", - ntohl(spi), reqid); - } - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); - - sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr); - host2xfrm(src, &sa->saddr); - host2xfrm(dst, &sa->id.daddr); - sa->id.spi = spi; - sa->id.proto = proto_ike2kernel(protocol); - sa->family = src->get_family(src); - sa->mode = mode2kernel(mode); - switch (mode) - { - case MODE_TUNNEL: - sa->flags |= XFRM_STATE_AF_UNSPEC; - break; - case MODE_BEET: - if(src_ts && dst_ts) - { - sa->sel = ts2selector(src_ts, dst_ts); - } - break; - default: - break; - } - - sa->replay_window = (protocol == IPPROTO_COMP) ? 0 : 32; - sa->reqid = reqid; - sa->lft.soft_byte_limit = XFRM_LIMIT(lifetime->bytes.rekey); - sa->lft.hard_byte_limit = XFRM_LIMIT(lifetime->bytes.life); - sa->lft.soft_packet_limit = XFRM_LIMIT(lifetime->packets.rekey); - sa->lft.hard_packet_limit = XFRM_LIMIT(lifetime->packets.life); - /* we use lifetimes since added, not since used */ - sa->lft.soft_add_expires_seconds = lifetime->time.rekey; - sa->lft.hard_add_expires_seconds = lifetime->time.life; - sa->lft.soft_use_expires_seconds = 0; - sa->lft.hard_use_expires_seconds = 0; - - struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_info); - - switch (enc_alg) - { - case ENCR_UNDEFINED: - /* no encryption */ - break; - case ENCR_AES_CCM_ICV16: - case ENCR_AES_GCM_ICV16: - case ENCR_NULL_AUTH_AES_GMAC: - case ENCR_CAMELLIA_CCM_ICV16: - icv_size += 32; - /* FALL */ - case ENCR_AES_CCM_ICV12: - case ENCR_AES_GCM_ICV12: - case ENCR_CAMELLIA_CCM_ICV12: - icv_size += 32; - /* FALL */ - case ENCR_AES_CCM_ICV8: - case ENCR_AES_GCM_ICV8: - case ENCR_CAMELLIA_CCM_ICV8: - { - struct xfrm_algo_aead *algo; - - alg_name = lookup_algorithm(encryption_algs, enc_alg); - if (alg_name == NULL) - { - DBG1(DBG_KNL, "algorithm %N not supported by kernel!", - encryption_algorithm_names, enc_alg); - return FAILED; - } - DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", - encryption_algorithm_names, enc_alg, enc_key.len * 8); - - rthdr->rta_type = XFRMA_ALG_AEAD; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_aead) + enc_key.len); - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - algo = (struct xfrm_algo_aead*)RTA_DATA(rthdr); - algo->alg_key_len = enc_key.len * 8; - algo->alg_icv_len = icv_size; - strcpy(algo->alg_name, alg_name); - memcpy(algo->alg_key, enc_key.ptr, enc_key.len); - - rthdr = XFRM_RTA_NEXT(rthdr); - break; - } - default: - { - struct xfrm_algo *algo; - - alg_name = lookup_algorithm(encryption_algs, enc_alg); - if (alg_name == NULL) - { - DBG1(DBG_KNL, "algorithm %N not supported by kernel!", - encryption_algorithm_names, enc_alg); - return FAILED; - } - DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", - encryption_algorithm_names, enc_alg, enc_key.len * 8); - - rthdr->rta_type = XFRMA_ALG_CRYPT; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + enc_key.len); - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - algo = (struct xfrm_algo*)RTA_DATA(rthdr); - algo->alg_key_len = enc_key.len * 8; - strcpy(algo->alg_name, alg_name); - memcpy(algo->alg_key, enc_key.ptr, enc_key.len); - - rthdr = XFRM_RTA_NEXT(rthdr); - } - } - - if (int_alg != AUTH_UNDEFINED) - { - alg_name = lookup_algorithm(integrity_algs, int_alg); - if (alg_name == NULL) - { - DBG1(DBG_KNL, "algorithm %N not supported by kernel!", - integrity_algorithm_names, int_alg); - return FAILED; - } - DBG2(DBG_KNL, " using integrity algorithm %N with key size %d", - integrity_algorithm_names, int_alg, int_key.len * 8); - - if (int_alg == AUTH_HMAC_SHA2_256_128) - { - struct xfrm_algo_auth* algo; - - /* the kernel uses SHA256 with 96 bit truncation by default, - * use specified truncation size supported by newer kernels */ - rthdr->rta_type = XFRMA_ALG_AUTH_TRUNC; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_auth) + int_key.len); - - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - algo = (struct xfrm_algo_auth*)RTA_DATA(rthdr); - algo->alg_key_len = int_key.len * 8; - algo->alg_trunc_len = 128; - strcpy(algo->alg_name, alg_name); - memcpy(algo->alg_key, int_key.ptr, int_key.len); - } - else - { - struct xfrm_algo* algo; - - rthdr->rta_type = XFRMA_ALG_AUTH; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + int_key.len); - - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - algo = (struct xfrm_algo*)RTA_DATA(rthdr); - algo->alg_key_len = int_key.len * 8; - strcpy(algo->alg_name, alg_name); - memcpy(algo->alg_key, int_key.ptr, int_key.len); - } - rthdr = XFRM_RTA_NEXT(rthdr); - } - - if (ipcomp != IPCOMP_NONE) - { - rthdr->rta_type = XFRMA_ALG_COMP; - alg_name = lookup_algorithm(compression_algs, ipcomp); - if (alg_name == NULL) - { - DBG1(DBG_KNL, "algorithm %N not supported by kernel!", - ipcomp_transform_names, ipcomp); - return FAILED; - } - DBG2(DBG_KNL, " using compression algorithm %N", - ipcomp_transform_names, ipcomp); - - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo)); - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - struct xfrm_algo* algo = (struct xfrm_algo*)RTA_DATA(rthdr); - algo->alg_key_len = 0; - strcpy(algo->alg_name, alg_name); - - rthdr = XFRM_RTA_NEXT(rthdr); - } - - if (encap) - { - struct xfrm_encap_tmpl *tmpl; - - rthdr->rta_type = XFRMA_ENCAP; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl)); - - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr); - tmpl->encap_type = UDP_ENCAP_ESPINUDP; - tmpl->encap_sport = htons(src->get_port(src)); - tmpl->encap_dport = htons(dst->get_port(dst)); - memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t)); - /* encap_oa could probably be derived from the - * traffic selectors [rfc4306, p39]. In the netlink kernel implementation - * pluto does the same as we do here but it uses encap_oa in the - * pfkey implementation. BUT as /usr/src/linux/net/key/af_key.c indicates - * the kernel ignores it anyway - * -> does that mean that NAT-T encap doesn't work in transport mode? - * No. The reason the kernel ignores NAT-OA is that it recomputes - * (or, rather, just ignores) the checksum. If packets pass - * the IPsec checks it marks them "checksum ok" so OA isn't needed. */ - rthdr = XFRM_RTA_NEXT(rthdr); - } - - if (mark.value) - { - struct xfrm_mark *mrk; - - rthdr->rta_type = XFRMA_MARK; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark)); - - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - mrk = (struct xfrm_mark*)RTA_DATA(rthdr); - mrk->v = mark.value; - mrk->m = mark.mask; - rthdr = XFRM_RTA_NEXT(rthdr); - } - - if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) - { - if (mark.value) - { - DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x " - "(mark %u/0x%8x)", ntohl(spi), mark.value, mark.mask); - } - else - { - DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi)); - } - return FAILED; - } - return SUCCESS; -} - -/** - * Get the replay state (i.e. sequence numbers) of an SA. - */ -static status_t get_replay_state(private_kernel_netlink_ipsec_t *this, - u_int32_t spi, protocol_id_t protocol, host_t *dst, - struct xfrm_replay_state *replay) -{ - netlink_buf_t request; - struct nlmsghdr *hdr, *out = NULL; - struct xfrm_aevent_id *out_aevent = NULL, *aevent_id; - size_t len; - struct rtattr *rta; - size_t rtasize; - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "querying replay state from SAD entry with SPI %.8x", ntohl(spi)); - - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST; - hdr->nlmsg_type = XFRM_MSG_GETAE; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id)); - - aevent_id = (struct xfrm_aevent_id*)NLMSG_DATA(hdr); - aevent_id->flags = XFRM_AE_RVAL; - - host2xfrm(dst, &aevent_id->sa_id.daddr); - aevent_id->sa_id.spi = spi; - aevent_id->sa_id.proto = proto_ike2kernel(protocol); - aevent_id->sa_id.family = dst->get_family(dst); - - if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) - { - hdr = out; - while (NLMSG_OK(hdr, len)) - { - switch (hdr->nlmsg_type) - { - case XFRM_MSG_NEWAE: - { - out_aevent = NLMSG_DATA(hdr); - break; - } - case NLMSG_ERROR: - { - struct nlmsgerr *err = NLMSG_DATA(hdr); - DBG1(DBG_KNL, "querying replay state from SAD entry failed: %s (%d)", - strerror(-err->error), -err->error); - break; - } - default: - hdr = NLMSG_NEXT(hdr, len); - continue; - case NLMSG_DONE: - break; - } - break; - } - } - - if (out_aevent == NULL) - { - DBG1(DBG_KNL, "unable to query replay state from SAD entry with SPI %.8x", - ntohl(spi)); - free(out); - return FAILED; - } - - rta = XFRM_RTA(out, struct xfrm_aevent_id); - rtasize = XFRM_PAYLOAD(out, struct xfrm_aevent_id); - while(RTA_OK(rta, rtasize)) - { - if (rta->rta_type == XFRMA_REPLAY_VAL && - RTA_PAYLOAD(rta) == sizeof(struct xfrm_replay_state)) - { - memcpy(replay, RTA_DATA(rta), RTA_PAYLOAD(rta)); - free(out); - return SUCCESS; - } - rta = RTA_NEXT(rta, rtasize); - } - - DBG1(DBG_KNL, "unable to query replay state from SAD entry with SPI %.8x", - ntohl(spi)); - free(out); - return FAILED; -} - -METHOD(kernel_ipsec_t, query_sa, status_t, - private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes) -{ - netlink_buf_t request; - struct nlmsghdr *out = NULL, *hdr; - struct xfrm_usersa_id *sa_id; - struct xfrm_usersa_info *sa = NULL; - size_t len; - - memset(&request, 0, sizeof(request)); - - if (mark.value) - { - DBG2(DBG_KNL, "querying SAD entry with SPI %.8x (mark %u/0x%8x)", - ntohl(spi), mark.value, mark.mask); - } - else - { - DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); - } - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST; - hdr->nlmsg_type = XFRM_MSG_GETSA; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); - - sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr); - host2xfrm(dst, &sa_id->daddr); - sa_id->spi = spi; - sa_id->proto = proto_ike2kernel(protocol); - sa_id->family = dst->get_family(dst); - - if (mark.value) - { - struct xfrm_mark *mrk; - struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_id); - - rthdr->rta_type = XFRMA_MARK; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark)); - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - mrk = (struct xfrm_mark*)RTA_DATA(rthdr); - mrk->v = mark.value; - mrk->m = mark.mask; - } - - if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) - { - hdr = out; - while (NLMSG_OK(hdr, len)) - { - switch (hdr->nlmsg_type) - { - case XFRM_MSG_NEWSA: - { - sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr); - break; - } - case NLMSG_ERROR: - { - struct nlmsgerr *err = NLMSG_DATA(hdr); - - if (mark.value) - { - DBG1(DBG_KNL, "querying SAD entry with SPI %.8x " - "(mark %u/0x%8x) failed: %s (%d)", - ntohl(spi), mark.value, mark.mask, - strerror(-err->error), -err->error); - } - else - { - DBG1(DBG_KNL, "querying SAD entry with SPI %.8x " - "failed: %s (%d)", ntohl(spi), - strerror(-err->error), -err->error); - } - break; - } - default: - hdr = NLMSG_NEXT(hdr, len); - continue; - case NLMSG_DONE: - break; - } - break; - } - } - - if (sa == NULL) - { - DBG2(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); - free(out); - return FAILED; - } - *bytes = sa->curlft.bytes; - - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, del_sa, status_t, - private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark) -{ - netlink_buf_t request; - struct nlmsghdr *hdr; - struct xfrm_usersa_id *sa_id; - - /* if IPComp was used, we first delete the additional IPComp SA */ - if (cpi) - { - del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0, mark); - } - - memset(&request, 0, sizeof(request)); - - if (mark.value) - { - DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x (mark %u/0x%8x)", - ntohl(spi), mark.value, mark.mask); - } - else - { - DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi)); - } - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - hdr->nlmsg_type = XFRM_MSG_DELSA; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); - - sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr); - host2xfrm(dst, &sa_id->daddr); - sa_id->spi = spi; - sa_id->proto = proto_ike2kernel(protocol); - sa_id->family = dst->get_family(dst); - - if (mark.value) - { - struct xfrm_mark *mrk; - struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_id); - - rthdr->rta_type = XFRMA_MARK; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark)); - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - mrk = (struct xfrm_mark*)RTA_DATA(rthdr); - mrk->v = mark.value; - mrk->m = mark.mask; - } - - if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) - { - if (mark.value) - { - DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x " - "(mark %u/0x%8x)", ntohl(spi), mark.value, mark.mask); - } - else - { - DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi)); - } - return FAILED; - } - if (mark.value) - { - DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x (mark %u/0x%8x)", - ntohl(spi), mark.value, mark.mask); - } - else - { - DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi)); - } - return SUCCESS; -} - -METHOD(kernel_ipsec_t, update_sa, status_t, - private_kernel_netlink_ipsec_t *this, u_int32_t spi, protocol_id_t protocol, - u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst, - bool old_encap, bool new_encap, mark_t mark) -{ - netlink_buf_t request; - u_char *pos; - struct nlmsghdr *hdr, *out = NULL; - struct xfrm_usersa_id *sa_id; - struct xfrm_usersa_info *out_sa = NULL, *sa; - size_t len; - struct rtattr *rta; - size_t rtasize; - struct xfrm_encap_tmpl* tmpl = NULL; - bool got_replay_state = FALSE; - struct xfrm_replay_state replay; - - /* if IPComp is used, we first update the IPComp SA */ - if (cpi) - { - update_sa(this, htonl(ntohs(cpi)), IPPROTO_COMP, 0, - src, dst, new_src, new_dst, FALSE, FALSE, mark); - } - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "querying SAD entry with SPI %.8x for update", ntohl(spi)); - - /* query the existing SA first */ - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST; - hdr->nlmsg_type = XFRM_MSG_GETSA; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); - - sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr); - host2xfrm(dst, &sa_id->daddr); - sa_id->spi = spi; - sa_id->proto = proto_ike2kernel(protocol); - sa_id->family = dst->get_family(dst); - - if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) - { - hdr = out; - while (NLMSG_OK(hdr, len)) - { - switch (hdr->nlmsg_type) - { - case XFRM_MSG_NEWSA: - { - out_sa = NLMSG_DATA(hdr); - break; - } - case NLMSG_ERROR: - { - struct nlmsgerr *err = NLMSG_DATA(hdr); - DBG1(DBG_KNL, "querying SAD entry failed: %s (%d)", - strerror(-err->error), -err->error); - break; - } - default: - hdr = NLMSG_NEXT(hdr, len); - continue; - case NLMSG_DONE: - break; - } - break; - } - } - if (out_sa == NULL) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi)); - free(out); - return FAILED; - } - - /* try to get the replay state */ - if (get_replay_state(this, spi, protocol, dst, &replay) == SUCCESS) - { - got_replay_state = TRUE; - } - - /* delete the old SA (without affecting the IPComp SA) */ - if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS) - { - DBG1(DBG_KNL, "unable to delete old SAD entry with SPI %.8x", ntohl(spi)); - free(out); - return FAILED; - } - - DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H", - ntohl(spi), src, dst, new_src, new_dst); - /* copy over the SA from out to request */ - hdr = (struct nlmsghdr*)request; - memcpy(hdr, out, min(out->nlmsg_len, sizeof(request))); - hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - hdr->nlmsg_type = XFRM_MSG_NEWSA; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); - sa = NLMSG_DATA(hdr); - sa->family = new_dst->get_family(new_dst); - - if (!src->ip_equals(src, new_src)) - { - host2xfrm(new_src, &sa->saddr); - } - if (!dst->ip_equals(dst, new_dst)) - { - host2xfrm(new_dst, &sa->id.daddr); - } - - rta = XFRM_RTA(out, struct xfrm_usersa_info); - rtasize = XFRM_PAYLOAD(out, struct xfrm_usersa_info); - pos = (u_char*)XFRM_RTA(hdr, struct xfrm_usersa_info); - while(RTA_OK(rta, rtasize)) - { - /* copy all attributes, but not XFRMA_ENCAP if we are disabling it */ - if (rta->rta_type != XFRMA_ENCAP || new_encap) - { - if (rta->rta_type == XFRMA_ENCAP) - { /* update encap tmpl */ - tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rta); - tmpl->encap_sport = ntohs(new_src->get_port(new_src)); - tmpl->encap_dport = ntohs(new_dst->get_port(new_dst)); - } - memcpy(pos, rta, rta->rta_len); - pos += RTA_ALIGN(rta->rta_len); - hdr->nlmsg_len += RTA_ALIGN(rta->rta_len); - } - rta = RTA_NEXT(rta, rtasize); - } - - rta = (struct rtattr*)pos; - if (tmpl == NULL && new_encap) - { /* add tmpl if we are enabling it */ - rta->rta_type = XFRMA_ENCAP; - rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl)); - - hdr->nlmsg_len += rta->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rta); - tmpl->encap_type = UDP_ENCAP_ESPINUDP; - tmpl->encap_sport = ntohs(new_src->get_port(new_src)); - tmpl->encap_dport = ntohs(new_dst->get_port(new_dst)); - memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t)); - - rta = XFRM_RTA_NEXT(rta); - } - - if (got_replay_state) - { /* copy the replay data if available */ - rta->rta_type = XFRMA_REPLAY_VAL; - rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_replay_state)); - - hdr->nlmsg_len += rta->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - memcpy(RTA_DATA(rta), &replay, sizeof(replay)); - - rta = XFRM_RTA_NEXT(rta); - } - - if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi)); - free(out); - return FAILED; - } - free(out); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, add_policy, status_t, - private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts, - policy_dir_t direction, u_int32_t spi, protocol_id_t protocol, - u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp, - u_int16_t cpi, bool routed) -{ - policy_entry_t *current, *policy; - bool found = FALSE; - netlink_buf_t request; - struct xfrm_userpolicy_info *policy_info; - struct nlmsghdr *hdr; - - /* create a policy */ - policy = malloc_thing(policy_entry_t); - memset(policy, 0, sizeof(policy_entry_t)); - policy->sel = ts2selector(src_ts, dst_ts); - policy->mark = mark.value & mark.mask; - policy->direction = direction; - - /* find the policy, which matches EXACTLY */ - this->mutex->lock(this->mutex); - current = this->policies->get(this->policies, policy); - if (current) - { - /* use existing policy */ - current->refcount++; - if (mark.value) - { - DBG2(DBG_KNL, "policy %R === %R %N (mark %u/0x%8x) " - "already exists, increasing refcount", - src_ts, dst_ts, policy_dir_names, direction, - mark.value, mark.mask); - } - else - { - DBG2(DBG_KNL, "policy %R === %R %N " - "already exists, increasing refcount", - src_ts, dst_ts, policy_dir_names, direction); - } - free(policy); - policy = current; - found = TRUE; - } - else - { /* apply the new one, if we have no such policy */ - this->policies->put(this->policies, policy, policy); - policy->refcount = 1; - } - - if (mark.value) - { - DBG2(DBG_KNL, "adding policy %R === %R %N (mark %u/0x%8x)", - src_ts, dst_ts, policy_dir_names, direction, - mark.value, mark.mask); - } - else - { - DBG2(DBG_KNL, "adding policy %R === %R %N", - src_ts, dst_ts, policy_dir_names, direction); - } - - memset(&request, 0, sizeof(request)); - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - hdr->nlmsg_type = found ? XFRM_MSG_UPDPOLICY : XFRM_MSG_NEWPOLICY; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)); - - policy_info = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr); - policy_info->sel = policy->sel; - policy_info->dir = policy->direction; - /* calculate priority based on source selector size, small size = high prio */ - policy_info->priority = routed ? PRIO_LOW : PRIO_HIGH; - policy_info->priority -= policy->sel.prefixlen_s * 10; - policy_info->priority -= policy->sel.proto ? 2 : 0; - policy_info->priority -= policy->sel.sport_mask ? 1 : 0; - policy_info->action = XFRM_POLICY_ALLOW; - policy_info->share = XFRM_SHARE_ANY; - this->mutex->unlock(this->mutex); - - /* policies don't expire */ - policy_info->lft.soft_byte_limit = XFRM_INF; - policy_info->lft.soft_packet_limit = XFRM_INF; - policy_info->lft.hard_byte_limit = XFRM_INF; - policy_info->lft.hard_packet_limit = XFRM_INF; - policy_info->lft.soft_add_expires_seconds = 0; - policy_info->lft.hard_add_expires_seconds = 0; - policy_info->lft.soft_use_expires_seconds = 0; - policy_info->lft.hard_use_expires_seconds = 0; - - struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_info); - rthdr->rta_type = XFRMA_TMPL; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_user_tmpl)); - - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - struct xfrm_user_tmpl *tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rthdr); - - if (ipcomp != IPCOMP_NONE) - { - tmpl->reqid = reqid; - tmpl->id.proto = IPPROTO_COMP; - tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0; - tmpl->mode = mode2kernel(mode); - tmpl->optional = direction != POLICY_OUT; - tmpl->family = src->get_family(src); - - host2xfrm(src, &tmpl->saddr); - host2xfrm(dst, &tmpl->id.daddr); - - /* add an additional xfrm_user_tmpl */ - rthdr->rta_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl)); - hdr->nlmsg_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl)); - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - tmpl++; - - /* use transport mode for ESP if we have a tunnel mode IPcomp SA */ - mode = MODE_TRANSPORT; - } - else - { - /* when using IPcomp, only the IPcomp SA uses tmp src/dst addresses */ - host2xfrm(src, &tmpl->saddr); - host2xfrm(dst, &tmpl->id.daddr); - } - - tmpl->reqid = reqid; - tmpl->id.proto = proto_ike2kernel(protocol); - tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0; - tmpl->mode = mode2kernel(mode); - tmpl->family = src->get_family(src); - rthdr = XFRM_RTA_NEXT(rthdr); - - if (mark.value) - { - struct xfrm_mark *mrk; - - rthdr->rta_type = XFRMA_MARK; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark)); - - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - mrk = (struct xfrm_mark*)RTA_DATA(rthdr); - mrk->v = mark.value; - mrk->m = mark.mask; - } - - if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) - { - DBG1(DBG_KNL, "unable to add policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - return FAILED; - } - - /* install a route, if: - * - we are NOT updating a policy - * - this is a forward policy (to just get one for each child) - * - we are in tunnel/BEET mode - * - routing is not disabled via strongswan.conf - */ - if (policy->route == NULL && direction == POLICY_FWD && - mode != MODE_TRANSPORT && this->install_routes) - { - route_entry_t *route = malloc_thing(route_entry_t); - - if (charon->kernel_interface->get_address_by_ts(charon->kernel_interface, - dst_ts, &route->src_ip) == SUCCESS) - { - /* get the nexthop to src (src as we are in POLICY_FWD).*/ - route->gateway = charon->kernel_interface->get_nexthop( - charon->kernel_interface, src); - /* install route via outgoing interface */ - route->if_name = charon->kernel_interface->get_interface( - charon->kernel_interface, dst); - route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16); - memcpy(route->dst_net.ptr, &policy->sel.saddr, route->dst_net.len); - route->prefixlen = policy->sel.prefixlen_s; - - if (route->if_name) - { - switch (charon->kernel_interface->add_route( - charon->kernel_interface, route->dst_net, - route->prefixlen, route->gateway, - route->src_ip, route->if_name)) - { - default: - DBG1(DBG_KNL, "unable to install source route for %H", - route->src_ip); - /* FALL */ - case ALREADY_DONE: - /* route exists, do not uninstall */ - route_entry_destroy(route); - break; - case SUCCESS: - /* cache the installed route */ - policy->route = route; - break; - } - } - else - { - route_entry_destroy(route); - } - } - else - { - free(route); - } - } - return SUCCESS; -} - -METHOD(kernel_ipsec_t, query_policy, status_t, - private_kernel_netlink_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) -{ - netlink_buf_t request; - struct nlmsghdr *out = NULL, *hdr; - struct xfrm_userpolicy_id *policy_id; - struct xfrm_userpolicy_info *policy = NULL; - size_t len; - - memset(&request, 0, sizeof(request)); - - if (mark.value) - { - DBG2(DBG_KNL, "querying policy %R === %R %N (mark %u/0x%8x)", - src_ts, dst_ts, policy_dir_names, direction, - mark.value, mark.mask); - } - else - { - DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - } - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST; - hdr->nlmsg_type = XFRM_MSG_GETPOLICY; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)); - - policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr); - policy_id->sel = ts2selector(src_ts, dst_ts); - policy_id->dir = direction; - - if (mark.value) - { - struct xfrm_mark *mrk; - struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_id); - - rthdr->rta_type = XFRMA_MARK; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark)); - - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - mrk = (struct xfrm_mark*)RTA_DATA(rthdr); - mrk->v = mark.value; - mrk->m = mark.mask; - } - - if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) - { - hdr = out; - while (NLMSG_OK(hdr, len)) - { - switch (hdr->nlmsg_type) - { - case XFRM_MSG_NEWPOLICY: - { - policy = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr); - break; - } - case NLMSG_ERROR: - { - struct nlmsgerr *err = NLMSG_DATA(hdr); - DBG1(DBG_KNL, "querying policy failed: %s (%d)", - strerror(-err->error), -err->error); - break; - } - default: - hdr = NLMSG_NEXT(hdr, len); - continue; - case NLMSG_DONE: - break; - } - break; - } - } - - if (policy == NULL) - { - DBG2(DBG_KNL, "unable to query policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - free(out); - return FAILED; - } - - if (policy->curlft.use_time) - { - /* we need the monotonic time, but the kernel returns system time. */ - *use_time = time_monotonic(NULL) - (time(NULL) - policy->curlft.use_time); - } - else - { - *use_time = 0; - } - - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, del_policy, status_t, - private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, - bool unrouted) -{ - policy_entry_t *current, policy, *to_delete = NULL; - route_entry_t *route; - netlink_buf_t request; - struct nlmsghdr *hdr; - struct xfrm_userpolicy_id *policy_id; - - if (mark.value) - { - DBG2(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%8x)", - src_ts, dst_ts, policy_dir_names, direction, - mark.value, mark.mask); - } - else - { - DBG2(DBG_KNL, "deleting policy %R === %R %N", - src_ts, dst_ts, policy_dir_names, direction); - } - - /* create a policy */ - memset(&policy, 0, sizeof(policy_entry_t)); - policy.sel = ts2selector(src_ts, dst_ts); - policy.mark = mark.value & mark.mask; - policy.direction = direction; - - /* find the policy */ - this->mutex->lock(this->mutex); - current = this->policies->get(this->policies, &policy); - if (current) - { - to_delete = current; - if (--to_delete->refcount > 0) - { - /* is used by more SAs, keep in kernel */ - DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed"); - this->mutex->unlock(this->mutex); - return SUCCESS; - } - /* remove if last reference */ - this->policies->remove(this->policies, to_delete); - } - this->mutex->unlock(this->mutex); - if (!to_delete) - { - if (mark.value) - { - DBG1(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%8x) " - "failed, not found", src_ts, dst_ts, policy_dir_names, - direction, mark.value, mark.mask); - } - else - { - DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", - src_ts, dst_ts, policy_dir_names, direction); - } - return NOT_FOUND; - } - - memset(&request, 0, sizeof(request)); - - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - hdr->nlmsg_type = XFRM_MSG_DELPOLICY; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)); - - policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr); - policy_id->sel = to_delete->sel; - policy_id->dir = direction; - - if (mark.value) - { - struct xfrm_mark *mrk; - struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_id); - - rthdr->rta_type = XFRMA_MARK; - rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark)); - hdr->nlmsg_len += rthdr->rta_len; - if (hdr->nlmsg_len > sizeof(request)) - { - return FAILED; - } - - mrk = (struct xfrm_mark*)RTA_DATA(rthdr); - mrk->v = mark.value; - mrk->m = mark.mask; - } - - route = to_delete->route; - free(to_delete); - - if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) - { - if (mark.value) - { - DBG1(DBG_KNL, "unable to delete policy %R === %R %N " - "(mark %u/0x%8x)", src_ts, dst_ts, policy_dir_names, - direction, mark.value, mark.mask); - } - else - { - DBG1(DBG_KNL, "unable to delete policy %R === %R %N", - src_ts, dst_ts, policy_dir_names, direction); - } - return FAILED; - } - - if (route) - { - if (charon->kernel_interface->del_route(charon->kernel_interface, - route->dst_net, route->prefixlen, route->gateway, - route->src_ip, route->if_name) != SUCCESS) - { - DBG1(DBG_KNL, "error uninstalling route installed with " - "policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - } - route_entry_destroy(route); - } - return SUCCESS; -} - -METHOD(kernel_ipsec_t, bypass_socket, bool, - private_kernel_netlink_ipsec_t *this, int fd, int family) -{ - struct xfrm_userpolicy_info policy; - u_int sol, ipsec_policy; - - switch (family) - { - case AF_INET: - sol = SOL_IP; - ipsec_policy = IP_XFRM_POLICY; - break; - case AF_INET6: - sol = SOL_IPV6; - ipsec_policy = IPV6_XFRM_POLICY; - break; - default: - return FALSE; - } - - memset(&policy, 0, sizeof(policy)); - policy.action = XFRM_POLICY_ALLOW; - policy.sel.family = family; - - policy.dir = XFRM_POLICY_OUT; - if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) - { - DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s", - strerror(errno)); - return FALSE; - } - policy.dir = XFRM_POLICY_IN; - if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) - { - DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s", - strerror(errno)); - return FALSE; - } - return TRUE; -} - -METHOD(kernel_ipsec_t, destroy, void, - private_kernel_netlink_ipsec_t *this) -{ - enumerator_t *enumerator; - policy_entry_t *policy; - - if (this->job) - { - this->job->cancel(this->job); - } - if (this->socket_xfrm_events > 0) - { - close(this->socket_xfrm_events); - } - DESTROY_IF(this->socket_xfrm); - enumerator = this->policies->create_enumerator(this->policies); - while (enumerator->enumerate(enumerator, &policy, &policy)) - { - free(policy); - } - enumerator->destroy(enumerator); - this->policies->destroy(this->policies); - this->mutex->destroy(this->mutex); - free(this); -} - -/* - * Described in header. - */ -kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() -{ - private_kernel_netlink_ipsec_t *this; - struct sockaddr_nl addr; - int fd; - - INIT(this, - .public.interface = { - .get_spi = _get_spi, - .get_cpi = _get_cpi, - .add_sa = _add_sa, - .update_sa = _update_sa, - .query_sa = _query_sa, - .del_sa = _del_sa, - .add_policy = _add_policy, - .query_policy = _query_policy, - .del_policy = _del_policy, - .bypass_socket = _bypass_socket, - .destroy = _destroy, - }, - .policies = hashtable_create((hashtable_hash_t)policy_hash, - (hashtable_equals_t)policy_equals, 32), - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .install_routes = lib->settings->get_bool(lib->settings, - "charon.install_routes", TRUE), - ); - - /* disable lifetimes for allocated SPIs in kernel */ - fd = open("/proc/sys/net/core/xfrm_acq_expires", O_WRONLY); - if (fd) - { - ignore_result(write(fd, "165", 3)); - close(fd); - } - - this->socket_xfrm = netlink_socket_create(NETLINK_XFRM); - if (!this->socket_xfrm) - { - destroy(this); - return NULL; - } - - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - - /* create and bind XFRM socket for ACQUIRE, EXPIRE, MIGRATE & MAPPING */ - this->socket_xfrm_events = socket(AF_NETLINK, SOCK_RAW, NETLINK_XFRM); - if (this->socket_xfrm_events <= 0) - { - DBG1(DBG_KNL, "unable to create XFRM event socket"); - destroy(this); - return NULL; - } - addr.nl_groups = XFRMNLGRP(ACQUIRE) | XFRMNLGRP(EXPIRE) | - XFRMNLGRP(MIGRATE) | XFRMNLGRP(MAPPING); - if (bind(this->socket_xfrm_events, (struct sockaddr*)&addr, sizeof(addr))) - { - DBG1(DBG_KNL, "unable to bind XFRM event socket"); - destroy(this); - return NULL; - } - this->job = callback_job_create((callback_job_cb_t)receive_events, - this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); - - return &this->public; -} - diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h deleted file mode 100644 index 3a45cce06..000000000 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 kernel_netlink_ipsec_i kernel_netlink_ipsec - * @{ @ingroup kernel_netlink - */ - -#ifndef KERNEL_NETLINK_IPSEC_H_ -#define KERNEL_NETLINK_IPSEC_H_ - -#include <kernel/kernel_ipsec.h> - -typedef struct kernel_netlink_ipsec_t kernel_netlink_ipsec_t; - -/** - * Implementation of the kernel ipsec interface using Netlink. - */ -struct kernel_netlink_ipsec_t { - - /** - * Implements kernel_ipsec_t interface - */ - kernel_ipsec_t interface; -}; - -/** - * Create a netlink kernel ipsec interface instance. - * - * @return kernel_netlink_ipsec_t instance - */ -kernel_netlink_ipsec_t *kernel_netlink_ipsec_create(); - -#endif /** KERNEL_NETLINK_IPSEC_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c deleted file mode 100644 index 6750458cf..000000000 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ /dev/null @@ -1,1506 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2005-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. - */ - -/* - * Copyright (C) 2010 secunet Security Networks AG - * Copyright (C) 2010 Thomas Egerer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include <sys/socket.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <unistd.h> -#include <errno.h> -#include <net/if.h> - -#include "kernel_netlink_net.h" -#include "kernel_netlink_shared.h" - -#include <daemon.h> -#include <threading/thread.h> -#include <threading/condvar.h> -#include <threading/mutex.h> -#include <utils/linked_list.h> -#include <processing/jobs/callback_job.h> -#include <processing/jobs/roam_job.h> - -/** delay before firing roam jobs (ms) */ -#define ROAM_DELAY 100 - -typedef struct addr_entry_t addr_entry_t; - -/** - * IP address in an inface_entry_t - */ -struct addr_entry_t { - - /** The ip address */ - host_t *ip; - - /** virtual IP managed by us */ - bool virtual; - - /** scope of the address */ - u_char scope; - - /** Number of times this IP is used, if virtual */ - u_int refcount; -}; - -/** - * destroy a addr_entry_t object - */ -static void addr_entry_destroy(addr_entry_t *this) -{ - this->ip->destroy(this->ip); - free(this); -} - -typedef struct iface_entry_t iface_entry_t; - -/** - * A network interface on this system, containing addr_entry_t's - */ -struct iface_entry_t { - - /** interface index */ - int ifindex; - - /** name of the interface */ - char ifname[IFNAMSIZ]; - - /** interface flags, as in netdevice(7) SIOCGIFFLAGS */ - u_int flags; - - /** list of addresses as host_t */ - linked_list_t *addrs; -}; - -/** - * destroy an interface entry - */ -static void iface_entry_destroy(iface_entry_t *this) -{ - this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy); - free(this); -} - -typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t; - -/** - * Private variables and functions of kernel_netlink_net class. - */ -struct private_kernel_netlink_net_t { - /** - * Public part of the kernel_netlink_net_t object. - */ - kernel_netlink_net_t public; - - /** - * mutex to lock access to various lists - */ - mutex_t *mutex; - - /** - * condition variable to signal virtual IP add/removal - */ - condvar_t *condvar; - - /** - * Cached list of interfaces and its addresses (iface_entry_t) - */ - linked_list_t *ifaces; - - /** - * job receiving netlink events - */ - callback_job_t *job; - - /** - * netlink rt socket (routing) - */ - netlink_socket_t *socket; - - /** - * Netlink rt socket to receive address change events - */ - int socket_events; - - /** - * time of the last roam_job - */ - timeval_t last_roam; - - /** - * routing table to install routes - */ - int routing_table; - - /** - * priority of used routing table - */ - int routing_table_prio; - - /** - * whether to react to RTM_NEWROUTE or RTM_DELROUTE events - */ - bool process_route; - - /** - * whether to actually install virtual IPs - */ - bool install_virtual_ip; - - /** - * list with routing tables to be excluded from route lookup - */ - linked_list_t *rt_exclude; -}; - -/** - * get the refcount of a virtual ip - */ -static int get_vip_refcount(private_kernel_netlink_net_t *this, host_t* ip) -{ - iterator_t *ifaces, *addrs; - iface_entry_t *iface; - addr_entry_t *addr; - int refcount = 0; - - ifaces = this->ifaces->create_iterator(this->ifaces, TRUE); - while (ifaces->iterate(ifaces, (void**)&iface)) - { - addrs = iface->addrs->create_iterator(iface->addrs, TRUE); - while (addrs->iterate(addrs, (void**)&addr)) - { - if (addr->virtual && (iface->flags & IFF_UP) && - ip->ip_equals(ip, addr->ip)) - { - refcount = addr->refcount; - break; - } - } - addrs->destroy(addrs); - if (refcount) - { - break; - } - } - ifaces->destroy(ifaces); - - return refcount; -} - -/** - * start a roaming job. We delay it for a second and fire only one job - * for multiple events. Otherwise we would create two many jobs. - */ -static void fire_roam_job(private_kernel_netlink_net_t *this, bool address) -{ - timeval_t now; - - time_monotonic(&now); - if (timercmp(&now, &this->last_roam, >)) - { - now.tv_usec += ROAM_DELAY * 1000; - while (now.tv_usec > 1000000) - { - now.tv_sec++; - now.tv_usec -= 1000000; - } - this->last_roam = now; - charon->scheduler->schedule_job_ms(charon->scheduler, - (job_t*)roam_job_create(address), ROAM_DELAY); - } -} - -/** - * process RTM_NEWLINK/RTM_DELLINK from kernel - */ -static void process_link(private_kernel_netlink_net_t *this, - struct nlmsghdr *hdr, bool event) -{ - struct ifinfomsg* msg = (struct ifinfomsg*)(NLMSG_DATA(hdr)); - struct rtattr *rta = IFLA_RTA(msg); - size_t rtasize = IFLA_PAYLOAD (hdr); - enumerator_t *enumerator; - iface_entry_t *current, *entry = NULL; - char *name = NULL; - bool update = FALSE; - - while(RTA_OK(rta, rtasize)) - { - switch (rta->rta_type) - { - case IFLA_IFNAME: - name = RTA_DATA(rta); - break; - } - rta = RTA_NEXT(rta, rtasize); - } - if (!name) - { - name = "(unknown)"; - } - - this->mutex->lock(this->mutex); - switch (hdr->nlmsg_type) - { - case RTM_NEWLINK: - { - if (msg->ifi_flags & IFF_LOOPBACK) - { /* ignore loopback interfaces */ - break; - } - enumerator = this->ifaces->create_enumerator(this->ifaces); - while (enumerator->enumerate(enumerator, ¤t)) - { - if (current->ifindex == msg->ifi_index) - { - entry = current; - break; - } - } - enumerator->destroy(enumerator); - if (!entry) - { - entry = malloc_thing(iface_entry_t); - entry->ifindex = msg->ifi_index; - entry->flags = 0; - entry->addrs = linked_list_create(); - this->ifaces->insert_last(this->ifaces, entry); - } - memcpy(entry->ifname, name, IFNAMSIZ); - entry->ifname[IFNAMSIZ-1] = '\0'; - if (event) - { - if (!(entry->flags & IFF_UP) && (msg->ifi_flags & IFF_UP)) - { - update = TRUE; - DBG1(DBG_KNL, "interface %s activated", name); - } - if ((entry->flags & IFF_UP) && !(msg->ifi_flags & IFF_UP)) - { - update = TRUE; - DBG1(DBG_KNL, "interface %s deactivated", name); - } - } - entry->flags = msg->ifi_flags; - break; - } - case RTM_DELLINK: - { - enumerator = this->ifaces->create_enumerator(this->ifaces); - while (enumerator->enumerate(enumerator, ¤t)) - { - if (current->ifindex == msg->ifi_index) - { - /* we do not remove it, as an address may be added to a - * "down" interface and we wan't to know that. */ - current->flags = msg->ifi_flags; - break; - } - } - enumerator->destroy(enumerator); - break; - } - } - this->mutex->unlock(this->mutex); - - /* send an update to all IKE_SAs */ - if (update && event) - { - fire_roam_job(this, TRUE); - } -} - -/** - * process RTM_NEWADDR/RTM_DELADDR from kernel - */ -static void process_addr(private_kernel_netlink_net_t *this, - struct nlmsghdr *hdr, bool event) -{ - struct ifaddrmsg* msg = (struct ifaddrmsg*)(NLMSG_DATA(hdr)); - struct rtattr *rta = IFA_RTA(msg); - size_t rtasize = IFA_PAYLOAD (hdr); - host_t *host = NULL; - enumerator_t *ifaces, *addrs; - iface_entry_t *iface; - addr_entry_t *addr; - chunk_t local = chunk_empty, address = chunk_empty; - bool update = FALSE, found = FALSE, changed = FALSE; - - while(RTA_OK(rta, rtasize)) - { - switch (rta->rta_type) - { - case IFA_LOCAL: - local.ptr = RTA_DATA(rta); - local.len = RTA_PAYLOAD(rta); - break; - case IFA_ADDRESS: - address.ptr = RTA_DATA(rta); - address.len = RTA_PAYLOAD(rta); - break; - } - rta = RTA_NEXT(rta, rtasize); - } - - /* For PPP interfaces, we need the IFA_LOCAL address, - * IFA_ADDRESS is the peers address. But IFA_LOCAL is - * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */ - if (local.ptr) - { - host = host_create_from_chunk(msg->ifa_family, local, 0); - } - else if (address.ptr) - { - host = host_create_from_chunk(msg->ifa_family, address, 0); - } - - if (host == NULL) - { /* bad family? */ - return; - } - - this->mutex->lock(this->mutex); - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - if (iface->ifindex == msg->ifa_index) - { - addrs = iface->addrs->create_enumerator(iface->addrs); - while (addrs->enumerate(addrs, &addr)) - { - if (host->ip_equals(host, addr->ip)) - { - found = TRUE; - if (hdr->nlmsg_type == RTM_DELADDR) - { - iface->addrs->remove_at(iface->addrs, addrs); - if (!addr->virtual) - { - changed = TRUE; - DBG1(DBG_KNL, "%H disappeared from %s", - host, iface->ifname); - } - addr_entry_destroy(addr); - } - else if (hdr->nlmsg_type == RTM_NEWADDR && addr->virtual) - { - addr->refcount = 1; - } - } - } - addrs->destroy(addrs); - - if (hdr->nlmsg_type == RTM_NEWADDR) - { - if (!found) - { - found = TRUE; - changed = TRUE; - addr = malloc_thing(addr_entry_t); - addr->ip = host->clone(host); - addr->virtual = FALSE; - addr->refcount = 1; - addr->scope = msg->ifa_scope; - - iface->addrs->insert_last(iface->addrs, addr); - if (event) - { - DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname); - } - } - } - if (found && (iface->flags & IFF_UP)) - { - update = TRUE; - } - break; - } - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - host->destroy(host); - - /* send an update to all IKE_SAs */ - if (update && event && changed) - { - fire_roam_job(this, TRUE); - } -} - -/** - * process RTM_NEWROUTE and RTM_DELROUTE from kernel - */ -static void process_route(private_kernel_netlink_net_t *this, struct nlmsghdr *hdr) -{ - struct rtmsg* msg = (struct rtmsg*)(NLMSG_DATA(hdr)); - struct rtattr *rta = RTM_RTA(msg); - size_t rtasize = RTM_PAYLOAD(hdr); - host_t *host = NULL; - - /* ignore routes added by us */ - if (msg->rtm_table && msg->rtm_table == this->routing_table) - { - return; - } - - while (RTA_OK(rta, rtasize)) - { - switch (rta->rta_type) - { - case RTA_PREFSRC: - host = host_create_from_chunk(msg->rtm_family, - chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), 0); - break; - } - rta = RTA_NEXT(rta, rtasize); - } - if (host) - { - this->mutex->lock(this->mutex); - if (!get_vip_refcount(this, host)) - { /* ignore routes added for virtual IPs */ - fire_roam_job(this, FALSE); - } - this->mutex->unlock(this->mutex); - host->destroy(host); - } -} - -/** - * Receives events from kernel - */ -static job_requeue_t receive_events(private_kernel_netlink_net_t *this) -{ - char response[1024]; - struct nlmsghdr *hdr = (struct nlmsghdr*)response; - struct sockaddr_nl addr; - socklen_t addr_len = sizeof(addr); - int len; - bool oldstate; - - oldstate = thread_cancelability(TRUE); - len = recvfrom(this->socket_events, response, sizeof(response), 0, - (struct sockaddr*)&addr, &addr_len); - thread_cancelability(oldstate); - - if (len < 0) - { - switch (errno) - { - case EINTR: - /* interrupted, try again */ - return JOB_REQUEUE_DIRECT; - case EAGAIN: - /* no data ready, select again */ - return JOB_REQUEUE_DIRECT; - default: - DBG1(DBG_KNL, "unable to receive from rt event socket"); - sleep(1); - return JOB_REQUEUE_FAIR; - } - } - - if (addr.nl_pid != 0) - { /* not from kernel. not interested, try another one */ - return JOB_REQUEUE_DIRECT; - } - - while (NLMSG_OK(hdr, len)) - { - /* looks good so far, dispatch netlink message */ - switch (hdr->nlmsg_type) - { - case RTM_NEWADDR: - case RTM_DELADDR: - process_addr(this, hdr, TRUE); - this->condvar->broadcast(this->condvar); - break; - case RTM_NEWLINK: - case RTM_DELLINK: - process_link(this, hdr, TRUE); - this->condvar->broadcast(this->condvar); - break; - case RTM_NEWROUTE: - case RTM_DELROUTE: - if (this->process_route) - { - process_route(this, hdr); - } - break; - default: - break; - } - hdr = NLMSG_NEXT(hdr, len); - } - return JOB_REQUEUE_DIRECT; -} - -/** enumerator over addresses */ -typedef struct { - private_kernel_netlink_net_t* this; - /** whether to enumerate down interfaces */ - bool include_down_ifaces; - /** whether to enumerate virtual ip addresses */ - bool include_virtual_ips; -} address_enumerator_t; - -/** - * cleanup function for address enumerator - */ -static void address_enumerator_destroy(address_enumerator_t *data) -{ - data->this->mutex->unlock(data->this->mutex); - free(data); -} - -/** - * filter for addresses - */ -static bool filter_addresses(address_enumerator_t *data, addr_entry_t** in, host_t** out) -{ - if (!data->include_virtual_ips && (*in)->virtual) - { /* skip virtual interfaces added by us */ - return FALSE; - } - if ((*in)->scope >= RT_SCOPE_LINK) - { /* skip addresses with a unusable scope */ - return FALSE; - } - *out = (*in)->ip; - return TRUE; -} - -/** - * enumerator constructor for interfaces - */ -static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data) -{ - return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs), - (void*)filter_addresses, data, NULL); -} - -/** - * filter for interfaces - */ -static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, iface_entry_t** out) -{ - if (!data->include_down_ifaces && !((*in)->flags & IFF_UP)) - { /* skip interfaces not up */ - return FALSE; - } - *out = *in; - return TRUE; -} - -/** - * implementation of kernel_net_t.create_address_enumerator - */ -static enumerator_t *create_address_enumerator(private_kernel_netlink_net_t *this, - bool include_down_ifaces, bool include_virtual_ips) -{ - address_enumerator_t *data = malloc_thing(address_enumerator_t); - data->this = this; - data->include_down_ifaces = include_down_ifaces; - data->include_virtual_ips = include_virtual_ips; - - this->mutex->lock(this->mutex); - return enumerator_create_nested( - enumerator_create_filter(this->ifaces->create_enumerator(this->ifaces), - (void*)filter_interfaces, data, NULL), - (void*)create_iface_enumerator, data, (void*)address_enumerator_destroy); -} - -/** - * implementation of kernel_net_t.get_interface_name - */ -static char *get_interface_name(private_kernel_netlink_net_t *this, host_t* ip) -{ - enumerator_t *ifaces, *addrs; - iface_entry_t *iface; - addr_entry_t *addr; - char *name = NULL; - - DBG2(DBG_KNL, "getting interface name for %H", ip); - - this->mutex->lock(this->mutex); - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - addrs = iface->addrs->create_enumerator(iface->addrs); - while (addrs->enumerate(addrs, &addr)) - { - if (ip->ip_equals(ip, addr->ip)) - { - name = strdup(iface->ifname); - break; - } - } - addrs->destroy(addrs); - if (name) - { - break; - } - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - - if (name) - { - DBG2(DBG_KNL, "%H is on interface %s", ip, name); - } - else - { - DBG2(DBG_KNL, "%H is not a local address", ip); - } - return name; -} - -/** - * get the index of an interface by name - */ -static int get_interface_index(private_kernel_netlink_net_t *this, char* name) -{ - enumerator_t *ifaces; - iface_entry_t *iface; - int ifindex = 0; - - DBG2(DBG_KNL, "getting iface index for %s", name); - - this->mutex->lock(this->mutex); - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - if (streq(name, iface->ifname)) - { - ifindex = iface->ifindex; - break; - } - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - - if (ifindex == 0) - { - DBG1(DBG_KNL, "unable to get interface index for %s", name); - } - return ifindex; -} - -/** - * Check if an interface with a given index is up - */ -static bool is_interface_up(private_kernel_netlink_net_t *this, int index) -{ - enumerator_t *ifaces; - iface_entry_t *iface; - /* default to TRUE for interface we do not monitor (e.g. lo) */ - bool up = TRUE; - - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - if (iface->ifindex == index) - { - up = iface->flags & IFF_UP; - break; - } - } - ifaces->destroy(ifaces); - return up; -} - -/** - * check if an address (chunk) addr is in subnet (net with net_len net bits) - */ -static bool addr_in_subnet(chunk_t addr, chunk_t net, int net_len) -{ - static const u_char mask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; - int byte = 0; - - if (net_len == 0) - { /* any address matches a /0 network */ - return TRUE; - } - if (addr.len != net.len || net_len > 8 * net.len ) - { - return FALSE; - } - /* scan through all bytes in network order */ - while (net_len > 0) - { - if (net_len < 8) - { - return (mask[net_len] & addr.ptr[byte]) == (mask[net_len] & net.ptr[byte]); - } - else - { - if (addr.ptr[byte] != net.ptr[byte]) - { - return FALSE; - } - byte++; - net_len -= 8; - } - } - return TRUE; -} - -/** - * Get a route: If "nexthop", the nexthop is returned. source addr otherwise. - */ -static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, - bool nexthop, host_t *candidate) -{ - netlink_buf_t request; - struct nlmsghdr *hdr, *out, *current; - struct rtmsg *msg; - chunk_t chunk; - size_t len; - int best = -1; - enumerator_t *enumerator; - host_t *src = NULL, *gtw = NULL; - - DBG2(DBG_KNL, "getting address to reach %H", dest); - - memset(&request, 0, sizeof(request)); - - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST; - if (dest->get_family(dest) == AF_INET) - { - /* We dump all addresses for IPv4, as we want to ignore IPsec specific - * routes installed by us. But the kernel does not return source - * addresses in a IPv6 dump, so fall back to get() for v6 routes. */ - hdr->nlmsg_flags |= NLM_F_ROOT | NLM_F_DUMP; - } - hdr->nlmsg_type = RTM_GETROUTE; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - - msg = (struct rtmsg*)NLMSG_DATA(hdr); - msg->rtm_family = dest->get_family(dest); - if (candidate) - { - chunk = candidate->get_address(candidate); - netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request)); - } - chunk = dest->get_address(dest); - netlink_add_attribute(hdr, RTA_DST, chunk, sizeof(request)); - - if (this->socket->send(this->socket, hdr, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "getting address to %H failed", dest); - return NULL; - } - this->mutex->lock(this->mutex); - - for (current = out; NLMSG_OK(current, len); - current = NLMSG_NEXT(current, len)) - { - switch (current->nlmsg_type) - { - case NLMSG_DONE: - break; - case RTM_NEWROUTE: - { - struct rtattr *rta; - size_t rtasize; - chunk_t rta_gtw, rta_src, rta_dst; - u_int32_t rta_oif = 0; - host_t *new_src, *new_gtw; - bool cont = FALSE; - uintptr_t table; - - rta_gtw = rta_src = rta_dst = chunk_empty; - msg = (struct rtmsg*)(NLMSG_DATA(current)); - rta = RTM_RTA(msg); - rtasize = RTM_PAYLOAD(current); - while (RTA_OK(rta, rtasize)) - { - switch (rta->rta_type) - { - case RTA_PREFSRC: - rta_src = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)); - break; - case RTA_GATEWAY: - rta_gtw = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)); - break; - case RTA_DST: - rta_dst = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)); - break; - case RTA_OIF: - if (RTA_PAYLOAD(rta) == sizeof(rta_oif)) - { - rta_oif = *(u_int32_t*)RTA_DATA(rta); - } - break; - } - rta = RTA_NEXT(rta, rtasize); - } - if (msg->rtm_dst_len <= best) - { /* not better than a previous one */ - continue; - } - enumerator = this->rt_exclude->create_enumerator(this->rt_exclude); - while (enumerator->enumerate(enumerator, &table)) - { - if (table == msg->rtm_table) - { - cont = TRUE; - break; - } - } - enumerator->destroy(enumerator); - if (cont) - { - continue; - } - if (this->routing_table != 0 && - msg->rtm_table == this->routing_table) - { /* route is from our own ipsec routing table */ - continue; - } - if (rta_oif && !is_interface_up(this, rta_oif)) - { /* interface is down */ - continue; - } - if (!addr_in_subnet(chunk, rta_dst, msg->rtm_dst_len)) - { /* route destination does not contain dest */ - continue; - } - - if (nexthop) - { - /* nexthop lookup, return gateway if any */ - DESTROY_IF(gtw); - gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0); - best = msg->rtm_dst_len; - continue; - } - if (rta_src.ptr) - { - /* got a source address */ - new_src = host_create_from_chunk(msg->rtm_family, rta_src, 0); - if (new_src) - { - if (get_vip_refcount(this, new_src)) - { /* skip source address if it is installed by us */ - new_src->destroy(new_src); - } - else - { - DESTROY_IF(src); - src = new_src; - best = msg->rtm_dst_len; - } - } - continue; - } - if (rta_gtw.ptr) - { /* no source, but a gateway. Lookup source to reach gtw. */ - new_gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0); - new_src = get_route(this, new_gtw, FALSE, candidate); - new_gtw->destroy(new_gtw); - if (new_src) - { - DESTROY_IF(src); - src = new_src; - best = msg->rtm_dst_len; - } - continue; - } - continue; - } - default: - continue; - } - break; - } - free(out); - this->mutex->unlock(this->mutex); - - if (nexthop) - { - if (gtw) - { - return gtw; - } - return dest->clone(dest); - } - return src; -} - -/** - * Implementation of kernel_net_t.get_source_addr. - */ -static host_t* get_source_addr(private_kernel_netlink_net_t *this, - host_t *dest, host_t *src) -{ - return get_route(this, dest, FALSE, src); -} - -/** - * Implementation of kernel_net_t.get_nexthop. - */ -static host_t* get_nexthop(private_kernel_netlink_net_t *this, host_t *dest) -{ - return get_route(this, dest, TRUE, NULL); -} - -/** - * Manages the creation and deletion of ip addresses on an interface. - * By setting the appropriate nlmsg_type, the ip will be set or unset. - */ -static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type, - int flags, int if_index, host_t *ip) -{ - netlink_buf_t request; - struct nlmsghdr *hdr; - struct ifaddrmsg *msg; - chunk_t chunk; - - memset(&request, 0, sizeof(request)); - - chunk = ip->get_address(ip); - - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags; - hdr->nlmsg_type = nlmsg_type; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - - msg = (struct ifaddrmsg*)NLMSG_DATA(hdr); - msg->ifa_family = ip->get_family(ip); - msg->ifa_flags = 0; - msg->ifa_prefixlen = 8 * chunk.len; - msg->ifa_scope = RT_SCOPE_UNIVERSE; - msg->ifa_index = if_index; - - netlink_add_attribute(hdr, IFA_LOCAL, chunk, sizeof(request)); - - return this->socket->send_ack(this->socket, hdr); -} - -/** - * Implementation of kernel_net_t.add_ip. - */ -static status_t add_ip(private_kernel_netlink_net_t *this, - host_t *virtual_ip, host_t *iface_ip) -{ - iface_entry_t *iface; - addr_entry_t *addr; - enumerator_t *addrs, *ifaces; - int ifindex; - - if (!this->install_virtual_ip) - { /* disabled by config */ - return SUCCESS; - } - - DBG2(DBG_KNL, "adding virtual IP %H", virtual_ip); - - this->mutex->lock(this->mutex); - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - bool iface_found = FALSE; - - addrs = iface->addrs->create_enumerator(iface->addrs); - while (addrs->enumerate(addrs, &addr)) - { - if (iface_ip->ip_equals(iface_ip, addr->ip)) - { - iface_found = TRUE; - } - else if (virtual_ip->ip_equals(virtual_ip, addr->ip)) - { - addr->refcount++; - DBG2(DBG_KNL, "virtual IP %H already installed on %s", - virtual_ip, iface->ifname); - addrs->destroy(addrs); - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - return SUCCESS; - } - } - addrs->destroy(addrs); - - if (iface_found) - { - ifindex = iface->ifindex; - addr = malloc_thing(addr_entry_t); - addr->ip = virtual_ip->clone(virtual_ip); - addr->refcount = 0; - addr->virtual = TRUE; - addr->scope = RT_SCOPE_UNIVERSE; - iface->addrs->insert_last(iface->addrs, addr); - - if (manage_ipaddr(this, RTM_NEWADDR, NLM_F_CREATE | NLM_F_EXCL, - ifindex, virtual_ip) == SUCCESS) - { - while (get_vip_refcount(this, virtual_ip) == 0) - { /* wait until address appears */ - this->condvar->wait(this->condvar, this->mutex); - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - return SUCCESS; - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "adding virtual IP %H failed", virtual_ip); - return FAILED; - } - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - - DBG1(DBG_KNL, "interface address %H not found, unable to install" - "virtual IP %H", iface_ip, virtual_ip); - return FAILED; -} - -/** - * Implementation of kernel_net_t.del_ip. - */ -static status_t del_ip(private_kernel_netlink_net_t *this, host_t *virtual_ip) -{ - iface_entry_t *iface; - addr_entry_t *addr; - enumerator_t *addrs, *ifaces; - status_t status; - int ifindex; - - if (!this->install_virtual_ip) - { /* disabled by config */ - return SUCCESS; - } - - DBG2(DBG_KNL, "deleting virtual IP %H", virtual_ip); - - this->mutex->lock(this->mutex); - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - addrs = iface->addrs->create_enumerator(iface->addrs); - while (addrs->enumerate(addrs, &addr)) - { - if (virtual_ip->ip_equals(virtual_ip, addr->ip)) - { - ifindex = iface->ifindex; - if (addr->refcount == 1) - { - status = manage_ipaddr(this, RTM_DELADDR, 0, - ifindex, virtual_ip); - if (status == SUCCESS) - { /* wait until the address is really gone */ - while (get_vip_refcount(this, virtual_ip) > 0) - { - this->condvar->wait(this->condvar, this->mutex); - } - } - addrs->destroy(addrs); - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - return status; - } - else - { - addr->refcount--; - } - DBG2(DBG_KNL, "virtual IP %H used by other SAs, not deleting", - virtual_ip); - addrs->destroy(addrs); - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - return SUCCESS; - } - } - addrs->destroy(addrs); - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - - DBG2(DBG_KNL, "virtual IP %H not cached, unable to delete", virtual_ip); - return FAILED; -} - -/** - * Manages source routes in the routing table. - * By setting the appropriate nlmsg_type, the route gets added or removed. - */ -static status_t manage_srcroute(private_kernel_netlink_net_t *this, int nlmsg_type, - int flags, chunk_t dst_net, u_int8_t prefixlen, - host_t *gateway, host_t *src_ip, char *if_name) -{ - netlink_buf_t request; - struct nlmsghdr *hdr; - struct rtmsg *msg; - int ifindex; - chunk_t chunk; - - /* if route is 0.0.0.0/0, we can't install it, as it would - * overwrite the default route. Instead, we add two routes: - * 0.0.0.0/1 and 128.0.0.0/1 */ - if (this->routing_table == 0 && prefixlen == 0) - { - chunk_t half_net; - u_int8_t half_prefixlen; - status_t status; - - half_net = chunk_alloca(dst_net.len); - memset(half_net.ptr, 0, half_net.len); - half_prefixlen = 1; - - status = manage_srcroute(this, nlmsg_type, flags, half_net, half_prefixlen, - gateway, src_ip, if_name); - half_net.ptr[0] |= 0x80; - status = manage_srcroute(this, nlmsg_type, flags, half_net, half_prefixlen, - gateway, src_ip, if_name); - return status; - } - - memset(&request, 0, sizeof(request)); - - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags; - hdr->nlmsg_type = nlmsg_type; - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - - msg = (struct rtmsg*)NLMSG_DATA(hdr); - msg->rtm_family = src_ip->get_family(src_ip); - msg->rtm_dst_len = prefixlen; - msg->rtm_table = this->routing_table; - msg->rtm_protocol = RTPROT_STATIC; - msg->rtm_type = RTN_UNICAST; - msg->rtm_scope = RT_SCOPE_UNIVERSE; - - netlink_add_attribute(hdr, RTA_DST, dst_net, sizeof(request)); - chunk = src_ip->get_address(src_ip); - netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request)); - if (gateway && gateway->get_family(gateway) == src_ip->get_family(src_ip)) - { - chunk = gateway->get_address(gateway); - netlink_add_attribute(hdr, RTA_GATEWAY, chunk, sizeof(request)); - } - ifindex = get_interface_index(this, if_name); - chunk.ptr = (char*)&ifindex; - chunk.len = sizeof(ifindex); - netlink_add_attribute(hdr, RTA_OIF, chunk, sizeof(request)); - - return this->socket->send_ack(this->socket, hdr); -} - -/** - * Implementation of kernel_net_t.add_route. - */ -static status_t add_route(private_kernel_netlink_net_t *this, chunk_t dst_net, - u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name) -{ - return manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, - dst_net, prefixlen, gateway, src_ip, if_name); -} - -/** - * Implementation of kernel_net_t.del_route. - */ -static status_t del_route(private_kernel_netlink_net_t *this, chunk_t dst_net, - u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name) -{ - return manage_srcroute(this, RTM_DELROUTE, 0, dst_net, prefixlen, - gateway, src_ip, if_name); -} - -/** - * Initialize a list of local addresses. - */ -static status_t init_address_list(private_kernel_netlink_net_t *this) -{ - netlink_buf_t request; - struct nlmsghdr *out, *current, *in; - struct rtgenmsg *msg; - size_t len; - enumerator_t *ifaces, *addrs; - iface_entry_t *iface; - addr_entry_t *addr; - - DBG1(DBG_KNL, "listening on interfaces:"); - - memset(&request, 0, sizeof(request)); - - in = (struct nlmsghdr*)&request; - in->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); - in->nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT; - msg = (struct rtgenmsg*)NLMSG_DATA(in); - msg->rtgen_family = AF_UNSPEC; - - /* get all links */ - in->nlmsg_type = RTM_GETLINK; - if (this->socket->send(this->socket, in, &out, &len) != SUCCESS) - { - return FAILED; - } - current = out; - while (NLMSG_OK(current, len)) - { - switch (current->nlmsg_type) - { - case NLMSG_DONE: - break; - case RTM_NEWLINK: - process_link(this, current, FALSE); - /* fall through */ - default: - current = NLMSG_NEXT(current, len); - continue; - } - break; - } - free(out); - - /* get all interface addresses */ - in->nlmsg_type = RTM_GETADDR; - if (this->socket->send(this->socket, in, &out, &len) != SUCCESS) - { - return FAILED; - } - current = out; - while (NLMSG_OK(current, len)) - { - switch (current->nlmsg_type) - { - case NLMSG_DONE: - break; - case RTM_NEWADDR: - process_addr(this, current, FALSE); - /* fall through */ - default: - current = NLMSG_NEXT(current, len); - continue; - } - break; - } - free(out); - - this->mutex->lock(this->mutex); - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - if (iface->flags & IFF_UP) - { - DBG1(DBG_KNL, " %s", iface->ifname); - addrs = iface->addrs->create_enumerator(iface->addrs); - while (addrs->enumerate(addrs, (void**)&addr)) - { - DBG1(DBG_KNL, " %H", addr->ip); - } - addrs->destroy(addrs); - } - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - return SUCCESS; -} - -/** - * create or delete a rule to use our routing table - */ -static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type, - int family, u_int32_t table, u_int32_t prio) -{ - netlink_buf_t request; - struct nlmsghdr *hdr; - struct rtmsg *msg; - chunk_t chunk; - - memset(&request, 0, sizeof(request)); - hdr = (struct nlmsghdr*)request; - hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - hdr->nlmsg_type = nlmsg_type; - if (nlmsg_type == RTM_NEWRULE) - { - hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; - } - hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - - msg = (struct rtmsg*)NLMSG_DATA(hdr); - msg->rtm_table = table; - msg->rtm_family = family; - msg->rtm_protocol = RTPROT_BOOT; - msg->rtm_scope = RT_SCOPE_UNIVERSE; - msg->rtm_type = RTN_UNICAST; - - chunk = chunk_from_thing(prio); - netlink_add_attribute(hdr, RTA_PRIORITY, chunk, sizeof(request)); - - return this->socket->send_ack(this->socket, hdr); -} - -/** - * Implementation of kernel_netlink_net_t.destroy. - */ -static void destroy(private_kernel_netlink_net_t *this) -{ - if (this->routing_table) - { - manage_rule(this, RTM_DELRULE, AF_INET, this->routing_table, - this->routing_table_prio); - manage_rule(this, RTM_DELRULE, AF_INET6, this->routing_table, - this->routing_table_prio); - } - if (this->job) - { - this->job->cancel(this->job); - } - if (this->socket_events > 0) - { - close(this->socket_events); - } - DESTROY_IF(this->socket); - this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy); - this->rt_exclude->destroy(this->rt_exclude); - this->condvar->destroy(this->condvar); - this->mutex->destroy(this->mutex); - free(this); -} - -/* - * Described in header. - */ -kernel_netlink_net_t *kernel_netlink_net_create() -{ - private_kernel_netlink_net_t *this = malloc_thing(private_kernel_netlink_net_t); - struct sockaddr_nl addr; - enumerator_t *enumerator; - char *exclude; - - /* public functions */ - this->public.interface.get_interface = (char*(*)(kernel_net_t*,host_t*))get_interface_name; - this->public.interface.create_address_enumerator = (enumerator_t*(*)(kernel_net_t*,bool,bool))create_address_enumerator; - this->public.interface.get_source_addr = (host_t*(*)(kernel_net_t*, host_t *dest, host_t *src))get_source_addr; - this->public.interface.get_nexthop = (host_t*(*)(kernel_net_t*, host_t *dest))get_nexthop; - this->public.interface.add_ip = (status_t(*)(kernel_net_t*,host_t*,host_t*)) add_ip; - this->public.interface.del_ip = (status_t(*)(kernel_net_t*,host_t*)) del_ip; - this->public.interface.add_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) add_route; - this->public.interface.del_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) del_route; - this->public.interface.destroy = (void(*)(kernel_net_t*)) destroy; - - /* private members */ - this->ifaces = linked_list_create(); - this->mutex = mutex_create(MUTEX_TYPE_RECURSIVE); - this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT); - timerclear(&this->last_roam); - this->routing_table = lib->settings->get_int(lib->settings, - "charon.routing_table", ROUTING_TABLE); - this->routing_table_prio = lib->settings->get_int(lib->settings, - "charon.routing_table_prio", ROUTING_TABLE_PRIO); - this->process_route = lib->settings->get_bool(lib->settings, - "charon.process_route", TRUE); - this->install_virtual_ip = lib->settings->get_bool(lib->settings, - "charon.install_virtual_ip", TRUE); - - this->rt_exclude = linked_list_create(); - exclude = lib->settings->get_str(lib->settings, - "charon.ignore_routing_tables", NULL); - if (exclude) - { - char *token; - uintptr_t table; - - enumerator = enumerator_create_token(exclude, " ", " "); - while (enumerator->enumerate(enumerator, &token)) - { - errno = 0; - table = strtoul(token, NULL, 10); - - if (errno == 0) - { - this->rt_exclude->insert_last(this->rt_exclude, (void*)table); - } - } - enumerator->destroy(enumerator); - } - - this->socket = netlink_socket_create(NETLINK_ROUTE); - this->job = NULL; - - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - - /* create and bind RT socket for events (address/interface/route changes) */ - this->socket_events = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (this->socket_events < 0) - { - DBG1(DBG_KNL, "unable to create RT event socket"); - destroy(this); - return NULL; - } - addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | - RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_ROUTE | RTMGRP_LINK; - if (bind(this->socket_events, (struct sockaddr*)&addr, sizeof(addr))) - { - DBG1(DBG_KNL, "unable to bind RT event socket"); - destroy(this); - return NULL; - } - - this->job = callback_job_create((callback_job_cb_t)receive_events, - this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); - - if (init_address_list(this) != SUCCESS) - { - DBG1(DBG_KNL, "unable to get interface list"); - destroy(this); - return NULL; - } - - if (this->routing_table) - { - if (manage_rule(this, RTM_NEWRULE, AF_INET, this->routing_table, - this->routing_table_prio) != SUCCESS) - { - DBG1(DBG_KNL, "unable to create IPv4 routing table rule"); - } - if (manage_rule(this, RTM_NEWRULE, AF_INET6, this->routing_table, - this->routing_table_prio) != SUCCESS) - { - DBG1(DBG_KNL, "unable to create IPv6 routing table rule"); - } - } - - return &this->public; -} diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h deleted file mode 100644 index ff9831d3c..000000000 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 kernel_netlink_net_i kernel_netlink_net - * @{ @ingroup kernel_netlink - */ - -#ifndef KERNEL_NETLINK_NET_H_ -#define KERNEL_NETLINK_NET_H_ - -#include <kernel/kernel_net.h> - -typedef struct kernel_netlink_net_t kernel_netlink_net_t; - -/** - * Implementation of the kernel network interface using Netlink. - */ -struct kernel_netlink_net_t { - - /** - * Implements kernel_net_t interface - */ - kernel_net_t interface; -}; - -/** - * Create a netlink kernel network interface instance. - * - * @return kernel_netlink_net_t instance - */ -kernel_netlink_net_t *kernel_netlink_net_create(); - -#endif /** KERNEL_NETLINK_NET_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c deleted file mode 100644 index 4c61265aa..000000000 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 "kernel_netlink_plugin.h" - -#include "kernel_netlink_ipsec.h" -#include "kernel_netlink_net.h" - -#include <daemon.h> - -typedef struct private_kernel_netlink_plugin_t private_kernel_netlink_plugin_t; - -/** - * private data of kernel netlink plugin - */ -struct private_kernel_netlink_plugin_t { - /** - * implements plugin interface - */ - kernel_netlink_plugin_t public; -}; - -/** - * Implementation of plugin_t.destroy - */ -static void destroy(private_kernel_netlink_plugin_t *this) -{ - charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_netlink_ipsec_create); - charon->kernel_interface->remove_net_interface(charon->kernel_interface, (kernel_net_constructor_t)kernel_netlink_net_create); - free(this); -} - -/* - * see header file - */ -plugin_t *kernel_netlink_plugin_create() -{ - private_kernel_netlink_plugin_t *this = malloc_thing(private_kernel_netlink_plugin_t); - - this->public.plugin.destroy = (void(*)(plugin_t*))destroy; - - charon->kernel_interface->add_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_netlink_ipsec_create); - charon->kernel_interface->add_net_interface(charon->kernel_interface, (kernel_net_constructor_t)kernel_netlink_net_create); - - return &this->public.plugin; -} diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c deleted file mode 100644 index 5ed568150..000000000 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 <sys/socket.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <errno.h> -#include <unistd.h> - -#include "kernel_netlink_shared.h" - -#include <daemon.h> -#include <threading/mutex.h> - -typedef struct private_netlink_socket_t private_netlink_socket_t; - -/** - * Private variables and functions of netlink_socket_t class. - */ -struct private_netlink_socket_t { - /** - * public part of the netlink_socket_t object. - */ - netlink_socket_t public; - - /** - * mutex to lock access to netlink socket - */ - mutex_t *mutex; - - /** - * current sequence number for netlink request - */ - int seq; - - /** - * netlink socket protocol - */ - int protocol; - - /** - * netlink socket - */ - int socket; -}; - -/** - * Imported from kernel_netlink_ipsec.c - */ -extern enum_name_t *xfrm_msg_names; - -/** - * Implementation of netlink_socket_t.send - */ -static status_t netlink_send(private_netlink_socket_t *this, struct nlmsghdr *in, - struct nlmsghdr **out, size_t *out_len) -{ - int len, addr_len; - struct sockaddr_nl addr; - chunk_t result = chunk_empty, tmp; - struct nlmsghdr *msg, peek; - - this->mutex->lock(this->mutex); - - in->nlmsg_seq = ++this->seq; - in->nlmsg_pid = getpid(); - - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - addr.nl_pid = 0; - addr.nl_groups = 0; - - if (this->protocol == NETLINK_XFRM) - { - chunk_t in_chunk = { (u_char*)in, in->nlmsg_len }; - - DBG3(DBG_KNL, "sending %N: %B", xfrm_msg_names, in->nlmsg_type, &in_chunk); - } - - while (TRUE) - { - len = sendto(this->socket, in, in->nlmsg_len, 0, - (struct sockaddr*)&addr, sizeof(addr)); - - if (len != in->nlmsg_len) - { - if (errno == EINTR) - { - /* interrupted, try again */ - continue; - } - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "error sending to netlink socket: %s", strerror(errno)); - return FAILED; - } - break; - } - - while (TRUE) - { - char buf[4096]; - tmp.len = sizeof(buf); - tmp.ptr = buf; - msg = (struct nlmsghdr*)tmp.ptr; - - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - addr.nl_pid = getpid(); - addr.nl_groups = 0; - addr_len = sizeof(addr); - - len = recvfrom(this->socket, tmp.ptr, tmp.len, 0, - (struct sockaddr*)&addr, &addr_len); - - if (len < 0) - { - if (errno == EINTR) - { - DBG1(DBG_KNL, "got interrupted"); - /* interrupted, try again */ - continue; - } - DBG1(DBG_KNL, "error reading from netlink socket: %s", strerror(errno)); - this->mutex->unlock(this->mutex); - free(result.ptr); - return FAILED; - } - if (!NLMSG_OK(msg, len)) - { - DBG1(DBG_KNL, "received corrupted netlink message"); - this->mutex->unlock(this->mutex); - free(result.ptr); - return FAILED; - } - if (msg->nlmsg_seq != this->seq) - { - DBG1(DBG_KNL, "received invalid netlink sequence number"); - if (msg->nlmsg_seq < this->seq) - { - continue; - } - this->mutex->unlock(this->mutex); - free(result.ptr); - return FAILED; - } - - tmp.len = len; - result.ptr = realloc(result.ptr, result.len + tmp.len); - memcpy(result.ptr + result.len, tmp.ptr, tmp.len); - result.len += tmp.len; - - /* NLM_F_MULTI flag does not seem to be set correctly, we use sequence - * numbers to detect multi header messages */ - len = recvfrom(this->socket, &peek, sizeof(peek), MSG_PEEK | MSG_DONTWAIT, - (struct sockaddr*)&addr, &addr_len); - - if (len == sizeof(peek) && peek.nlmsg_seq == this->seq) - { - /* seems to be multipart */ - continue; - } - break; - } - - *out_len = result.len; - *out = (struct nlmsghdr*)result.ptr; - - this->mutex->unlock(this->mutex); - - return SUCCESS; -} - -/** - * Implementation of netlink_socket_t.send_ack. - */ -static status_t netlink_send_ack(private_netlink_socket_t *this, struct nlmsghdr *in) -{ - struct nlmsghdr *out, *hdr; - size_t len; - - if (netlink_send(this, in, &out, &len) != SUCCESS) - { - return FAILED; - } - hdr = out; - while (NLMSG_OK(hdr, len)) - { - switch (hdr->nlmsg_type) - { - case NLMSG_ERROR: - { - struct nlmsgerr* err = (struct nlmsgerr*)NLMSG_DATA(hdr); - - if (err->error) - { - if (-err->error == EEXIST) - { /* do not report existing routes */ - free(out); - return ALREADY_DONE; - } - DBG1(DBG_KNL, "received netlink error: %s (%d)", - strerror(-err->error), -err->error); - free(out); - return FAILED; - } - free(out); - return SUCCESS; - } - default: - hdr = NLMSG_NEXT(hdr, len); - continue; - case NLMSG_DONE: - break; - } - break; - } - DBG1(DBG_KNL, "netlink request not acknowledged"); - free(out); - return FAILED; -} - -/** - * Implementation of netlink_socket_t.destroy. - */ -static void destroy(private_netlink_socket_t *this) -{ - if (this->socket > 0) - { - close(this->socket); - } - this->mutex->destroy(this->mutex); - free(this); -} - -/** - * Described in header. - */ -netlink_socket_t *netlink_socket_create(int protocol) -{ - private_netlink_socket_t *this = malloc_thing(private_netlink_socket_t); - struct sockaddr_nl addr; - - /* public functions */ - this->public.send = (status_t(*)(netlink_socket_t*,struct nlmsghdr*, struct nlmsghdr**, size_t*))netlink_send; - this->public.send_ack = (status_t(*)(netlink_socket_t*,struct nlmsghdr*))netlink_send_ack; - this->public.destroy = (void(*)(netlink_socket_t*))destroy; - - /* private members */ - this->seq = 200; - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - - this->protocol = protocol; - this->socket = socket(AF_NETLINK, SOCK_RAW, protocol); - if (this->socket < 0) - { - DBG1(DBG_KNL, "unable to create netlink socket"); - destroy(this); - return NULL; - } - - addr.nl_groups = 0; - if (bind(this->socket, (struct sockaddr*)&addr, sizeof(addr))) - { - DBG1(DBG_KNL, "unable to bind netlink socket"); - destroy(this); - return NULL; - } - - return &this->public; -} - -/** - * Described in header. - */ -void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data, - size_t buflen) -{ - struct rtattr *rta; - - if (NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(data.len) > buflen) - { - DBG1(DBG_KNL, "unable to add attribute, buffer too small"); - return; - } - - rta = (struct rtattr*)(((char*)hdr) + NLMSG_ALIGN(hdr->nlmsg_len)); - rta->rta_type = rta_type; - rta->rta_len = RTA_LENGTH(data.len); - memcpy(RTA_DATA(rta), data.ptr, data.len); - hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + rta->rta_len; -} diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h deleted file mode 100644 index dfd27a21a..000000000 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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. - */ - -#ifndef KERNEL_NETLINK_SHARED_H_ -#define KERNEL_NETLINK_SHARED_H_ - -#include <library.h> - -#include <linux/rtnetlink.h> - -/** - * General purpose netlink buffer. - * - * 1024 byte is currently sufficient for all operations. Some platform - * require an enforced aligment to four bytes (e.g. ARM). - */ -typedef u_char netlink_buf_t[1024] __attribute__((aligned(RTA_ALIGNTO))); - -typedef struct netlink_socket_t netlink_socket_t; - -/** - * Wrapper around a netlink socket. - */ -struct netlink_socket_t { - - /** - * Send a netlink message and wait for a reply. - * - * @param in netlink message to send - * @param out received netlink message - * @param out_len length of the received message - */ - status_t (*send)(netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out, size_t *out_len); - - /** - * Send a netlink message and wait for its acknowledge. - * - * @param in netlink message to send - */ - status_t (*send_ack)(netlink_socket_t *this, struct nlmsghdr *in); - - /** - * Destroy the socket. - */ - void (*destroy)(netlink_socket_t *this); -}; - -/** - * Create a netlink_socket_t object. - * - * @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE) - */ -netlink_socket_t *netlink_socket_create(int protocol); - -/** - * Creates an rtattr and adds it to the given netlink message. - * - * @param hdr netlink message - * @param rta_type type of the rtattr - * @param data data to add to the rtattr - * @param buflen length of the netlink message buffer - */ -void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data, size_t buflen); - -#endif /* KERNEL_NETLINK_SHARED_H_ */ diff --git a/src/libcharon/plugins/kernel_pfkey/Makefile.am b/src/libcharon/plugins/kernel_pfkey/Makefile.am deleted file mode 100644 index 778a7f9a9..000000000 --- a/src/libcharon/plugins/kernel_pfkey/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ - -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon - -AM_CFLAGS = -rdynamic - -if MONOLITHIC -noinst_LTLIBRARIES = libstrongswan-kernel-pfkey.la -else -plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la -endif - -libstrongswan_kernel_pfkey_la_SOURCES = \ - kernel_pfkey_plugin.h kernel_pfkey_plugin.c \ - kernel_pfkey_ipsec.h kernel_pfkey_ipsec.c - -libstrongswan_kernel_pfkey_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c deleted file mode 100644 index a64c27f6f..000000000 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ /dev/null @@ -1,2210 +0,0 @@ -/* - * Copyright (C) 2008-2010 Tobias Brunner - * Copyright (C) 2008 Andreas Steffen - * 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 <sys/types.h> -#include <sys/socket.h> - -#ifdef __FreeBSD__ -#include <limits.h> /* for LONG_MAX */ -#endif - -#ifdef HAVE_NET_PFKEYV2_H -#include <net/pfkeyv2.h> -#else -#include <stdint.h> -#include <linux/pfkeyv2.h> -#endif - -#ifdef SADB_X_EXT_NAT_T_TYPE -#define HAVE_NATT -#endif - -#ifdef HAVE_NETIPSEC_IPSEC_H -#include <netipsec/ipsec.h> -#elif defined(HAVE_NETINET6_IPSEC_H) -#include <netinet6/ipsec.h> -#else -#include <linux/ipsec.h> -#endif - -#ifdef HAVE_NATT -#ifdef HAVE_LINUX_UDP_H -#include <linux/udp.h> -#else -#include <netinet/udp.h> -#endif /*HAVE_LINUX_UDP_H*/ -#endif /*HAVE_NATT*/ - -#include <unistd.h> -#include <time.h> -#include <errno.h> - -#include "kernel_pfkey_ipsec.h" - -#include <daemon.h> -#include <utils/host.h> -#include <threading/thread.h> -#include <threading/mutex.h> -#include <processing/jobs/callback_job.h> -#include <processing/jobs/acquire_job.h> -#include <processing/jobs/migrate_job.h> -#include <processing/jobs/rekey_child_sa_job.h> -#include <processing/jobs/delete_child_sa_job.h> -#include <processing/jobs/update_sa_job.h> - -/** non linux specific */ -#ifndef IPPROTO_COMP -#ifdef IPPROTO_IPCOMP -#define IPPROTO_COMP IPPROTO_IPCOMP -#endif -#endif - -#ifndef SADB_X_AALG_SHA2_256HMAC -#define SADB_X_AALG_SHA2_256HMAC SADB_X_AALG_SHA2_256 -#define SADB_X_AALG_SHA2_384HMAC SADB_X_AALG_SHA2_384 -#define SADB_X_AALG_SHA2_512HMAC SADB_X_AALG_SHA2_512 -#endif - -#ifndef SADB_X_EALG_AESCBC -#define SADB_X_EALG_AESCBC SADB_X_EALG_AES -#endif - -#ifndef SADB_X_EALG_CASTCBC -#define SADB_X_EALG_CASTCBC SADB_X_EALG_CAST128CBC -#endif - -#ifndef SOL_IP -#define SOL_IP IPPROTO_IP -#define SOL_IPV6 IPPROTO_IPV6 -#endif - -/** from linux/in.h */ -#ifndef IP_IPSEC_POLICY -#define IP_IPSEC_POLICY 16 -#endif - -/** missing on uclibc */ -#ifndef IPV6_IPSEC_POLICY -#define IPV6_IPSEC_POLICY 34 -#endif - -/** default priority of installed policies */ -#define PRIO_LOW 3000 -#define PRIO_HIGH 2000 - -#ifdef __APPLE__ -/** from xnu/bsd/net/pfkeyv2.h */ -#define SADB_X_EXT_NATT 0x002 - struct sadb_sa_2 { - struct sadb_sa sa; - u_int16_t sadb_sa_natt_port; - u_int16_t sadb_reserved0; - u_int32_t sadb_reserved1; - }; -#endif - -/** buffer size for PF_KEY messages */ -#define PFKEY_BUFFER_SIZE 4096 - -/** PF_KEY messages are 64 bit aligned */ -#define PFKEY_ALIGNMENT 8 -/** aligns len to 64 bits */ -#define PFKEY_ALIGN(len) (((len) + PFKEY_ALIGNMENT - 1) & ~(PFKEY_ALIGNMENT - 1)) -/** calculates the properly padded length in 64 bit chunks */ -#define PFKEY_LEN(len) ((PFKEY_ALIGN(len) / PFKEY_ALIGNMENT)) -/** calculates user mode length i.e. in bytes */ -#define PFKEY_USER_LEN(len) ((len) * PFKEY_ALIGNMENT) - -/** given a PF_KEY message header and an extension this updates the length in the header */ -#define PFKEY_EXT_ADD(msg, ext) ((msg)->sadb_msg_len += ((struct sadb_ext*)ext)->sadb_ext_len) -/** given a PF_KEY message header this returns a pointer to the next extension */ -#define PFKEY_EXT_ADD_NEXT(msg) ((struct sadb_ext*)(((char*)(msg)) + PFKEY_USER_LEN((msg)->sadb_msg_len))) -/** copy an extension and append it to a PF_KEY message */ -#define PFKEY_EXT_COPY(msg, ext) (PFKEY_EXT_ADD(msg, memcpy(PFKEY_EXT_ADD_NEXT(msg), ext, PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len)))) -/** given a PF_KEY extension this returns a pointer to the next extension */ -#define PFKEY_EXT_NEXT(ext) ((struct sadb_ext*)(((char*)(ext)) + PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len))) -/** given a PF_KEY extension this returns a pointer to the next extension also updates len (len in 64 bit words) */ -#define PFKEY_EXT_NEXT_LEN(ext,len) ((len) -= (ext)->sadb_ext_len, PFKEY_EXT_NEXT(ext)) -/** true if ext has a valid length and len is large enough to contain ext (assuming len in 64 bit words) */ -#define PFKEY_EXT_OK(ext,len) ((len) >= PFKEY_LEN(sizeof(struct sadb_ext)) && \ - (ext)->sadb_ext_len >= PFKEY_LEN(sizeof(struct sadb_ext)) && \ - (ext)->sadb_ext_len <= (len)) - -typedef struct private_kernel_pfkey_ipsec_t private_kernel_pfkey_ipsec_t; - -/** - * Private variables and functions of kernel_pfkey class. - */ -struct private_kernel_pfkey_ipsec_t -{ - /** - * Public part of the kernel_pfkey_t object. - */ - kernel_pfkey_ipsec_t public; - - /** - * mutex to lock access to various lists - */ - mutex_t *mutex; - - /** - * List of installed policies (policy_entry_t) - */ - linked_list_t *policies; - - /** - * whether to install routes along policies - */ - bool install_routes; - - /** - * job receiving PF_KEY events - */ - callback_job_t *job; - - /** - * mutex to lock access to the PF_KEY socket - */ - mutex_t *mutex_pfkey; - - /** - * PF_KEY socket to communicate with the kernel - */ - int socket; - - /** - * PF_KEY socket to receive acquire and expire events - */ - int socket_events; - - /** - * sequence number for messages sent to the kernel - */ - int seq; -}; - -typedef struct route_entry_t route_entry_t; - -/** - * installed routing entry - */ -struct route_entry_t { - /** Name of the interface the route is bound to */ - char *if_name; - - /** Source ip of the route */ - host_t *src_ip; - - /** gateway for this route */ - host_t *gateway; - - /** Destination net */ - chunk_t dst_net; - - /** Destination net prefixlen */ - u_int8_t prefixlen; -}; - -/** - * destroy an route_entry_t object - */ -static void route_entry_destroy(route_entry_t *this) -{ - free(this->if_name); - DESTROY_IF(this->src_ip); - DESTROY_IF(this->gateway); - chunk_free(&this->dst_net); - free(this); -} - -typedef struct policy_entry_t policy_entry_t; - -/** - * installed kernel policy. - */ -struct policy_entry_t { - - /** reqid of this policy */ - u_int32_t reqid; - - /** index assigned by the kernel */ - u_int32_t index; - - /** direction of this policy: in, out, forward */ - u_int8_t direction; - - /** parameters of installed policy */ - struct { - /** subnet and port */ - host_t *net; - /** subnet mask */ - u_int8_t mask; - /** protocol */ - u_int8_t proto; - } src, dst; - - /** associated route installed for this policy */ - route_entry_t *route; - - /** by how many CHILD_SA's this policy is used */ - u_int refcount; -}; - -/** - * create a policy_entry_t object - */ -static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t dir, u_int32_t reqid) -{ - policy_entry_t *policy = malloc_thing(policy_entry_t); - policy->reqid = reqid; - policy->index = 0; - policy->direction = dir; - policy->route = NULL; - policy->refcount = 0; - - src_ts->to_subnet(src_ts, &policy->src.net, &policy->src.mask); - dst_ts->to_subnet(dst_ts, &policy->dst.net, &policy->dst.mask); - - /* src or dest proto may be "any" (0), use more restrictive one */ - policy->src.proto = max(src_ts->get_protocol(src_ts), dst_ts->get_protocol(dst_ts)); - policy->src.proto = policy->src.proto ? policy->src.proto : IPSEC_PROTO_ANY; - policy->dst.proto = policy->src.proto; - - return policy; -} - -/** - * destroy a policy_entry_t object - */ -static void policy_entry_destroy(policy_entry_t *this) -{ - DESTROY_IF(this->src.net); - DESTROY_IF(this->dst.net); - if (this->route) - { - route_entry_destroy(this->route); - } - free(this); -} - -/** - * compares two policy_entry_t - */ -static inline bool policy_entry_equals(policy_entry_t *current, policy_entry_t *policy) -{ - return current->direction == policy->direction && - current->src.proto == policy->src.proto && - current->dst.proto == policy->dst.proto && - current->src.mask == policy->src.mask && - current->dst.mask == policy->dst.mask && - current->src.net->equals(current->src.net, policy->src.net) && - current->dst.net->equals(current->dst.net, policy->dst.net); -} - -/** - * compare the given kernel index with that of a policy - */ -static inline bool policy_entry_match_byindex(policy_entry_t *current, u_int32_t *index) -{ - return current->index == *index; -} - -typedef struct pfkey_msg_t pfkey_msg_t; - -struct pfkey_msg_t -{ - /** - * PF_KEY message base - */ - struct sadb_msg *msg; - - /** - * PF_KEY message extensions - */ - union { - struct sadb_ext *ext[SADB_EXT_MAX + 1]; - struct { - struct sadb_ext *reserved; /* SADB_EXT_RESERVED */ - struct sadb_sa *sa; /* SADB_EXT_SA */ - struct sadb_lifetime *lft_current; /* SADB_EXT_LIFETIME_CURRENT */ - struct sadb_lifetime *lft_hard; /* SADB_EXT_LIFETIME_HARD */ - struct sadb_lifetime *lft_soft; /* SADB_EXT_LIFETIME_SOFT */ - struct sadb_address *src; /* SADB_EXT_ADDRESS_SRC */ - struct sadb_address *dst; /* SADB_EXT_ADDRESS_DST */ - struct sadb_address *proxy; /* SADB_EXT_ADDRESS_PROXY */ - struct sadb_key *key_auth; /* SADB_EXT_KEY_AUTH */ - struct sadb_key *key_encr; /* SADB_EXT_KEY_ENCRYPT */ - struct sadb_ident *id_src; /* SADB_EXT_IDENTITY_SRC */ - struct sadb_ident *id_dst; /* SADB_EXT_IDENTITY_DST */ - struct sadb_sens *sensitivity; /* SADB_EXT_SENSITIVITY */ - struct sadb_prop *proposal; /* SADB_EXT_PROPOSAL */ - struct sadb_supported *supported_auth; /* SADB_EXT_SUPPORTED_AUTH */ - struct sadb_supported *supported_encr; /* SADB_EXT_SUPPORTED_ENCRYPT */ - struct sadb_spirange *spirange; /* SADB_EXT_SPIRANGE */ - struct sadb_x_kmprivate *x_kmprivate; /* SADB_X_EXT_KMPRIVATE */ - struct sadb_x_policy *x_policy; /* SADB_X_EXT_POLICY */ - struct sadb_x_sa2 *x_sa2; /* SADB_X_EXT_SA2 */ - struct sadb_x_nat_t_type *x_natt_type; /* SADB_X_EXT_NAT_T_TYPE */ - struct sadb_x_nat_t_port *x_natt_sport; /* SADB_X_EXT_NAT_T_SPORT */ - struct sadb_x_nat_t_port *x_natt_dport; /* SADB_X_EXT_NAT_T_DPORT */ - struct sadb_address *x_natt_oa; /* SADB_X_EXT_NAT_T_OA */ - struct sadb_x_sec_ctx *x_sec_ctx; /* SADB_X_EXT_SEC_CTX */ - struct sadb_x_kmaddress *x_kmaddress; /* SADB_X_EXT_KMADDRESS */ - } __attribute__((__packed__)); - }; -}; - -ENUM(sadb_ext_type_names, SADB_EXT_RESERVED, SADB_EXT_MAX, - "SADB_EXT_RESERVED", - "SADB_EXT_SA", - "SADB_EXT_LIFETIME_CURRENT", - "SADB_EXT_LIFETIME_HARD", - "SADB_EXT_LIFETIME_SOFT", - "SADB_EXT_ADDRESS_SRC", - "SADB_EXT_ADDRESS_DST", - "SADB_EXT_ADDRESS_PROXY", - "SADB_EXT_KEY_AUTH", - "SADB_EXT_KEY_ENCRYPT", - "SADB_EXT_IDENTITY_SRC", - "SADB_EXT_IDENTITY_DST", - "SADB_EXT_SENSITIVITY", - "SADB_EXT_PROPOSAL", - "SADB_EXT_SUPPORTED_AUTH", - "SADB_EXT_SUPPORTED_ENCRYPT", - "SADB_EXT_SPIRANGE", - "SADB_X_EXT_KMPRIVATE", - "SADB_X_EXT_POLICY", - "SADB_X_EXT_SA2", - "SADB_X_EXT_NAT_T_TYPE", - "SADB_X_EXT_NAT_T_SPORT", - "SADB_X_EXT_NAT_T_DPORT", - "SADB_X_EXT_NAT_T_OA", - "SADB_X_EXT_SEC_CTX", - "SADB_X_EXT_KMADDRESS" -); - -/** - * convert a IKEv2 specific protocol identifier to the PF_KEY sa type - */ -static u_int8_t proto_ike2satype(protocol_id_t proto) -{ - switch (proto) - { - case PROTO_ESP: - return SADB_SATYPE_ESP; - case PROTO_AH: - return SADB_SATYPE_AH; - case IPPROTO_COMP: - return SADB_X_SATYPE_IPCOMP; - default: - return proto; - } -} - -/** - * convert a PF_KEY sa type to a IKEv2 specific protocol identifier - */ -static protocol_id_t proto_satype2ike(u_int8_t proto) -{ - switch (proto) - { - case SADB_SATYPE_ESP: - return PROTO_ESP; - case SADB_SATYPE_AH: - return PROTO_AH; - case SADB_X_SATYPE_IPCOMP: - return IPPROTO_COMP; - default: - return proto; - } -} - -/** - * convert a IKEv2 specific protocol identifier to the IP protocol identifier - */ -static u_int8_t proto_ike2ip(protocol_id_t proto) -{ - switch (proto) - { - case PROTO_ESP: - return IPPROTO_ESP; - case PROTO_AH: - return IPPROTO_AH; - default: - return proto; - } -} - -/** - * convert the general ipsec mode to the one defined in ipsec.h - */ -static u_int8_t mode2kernel(ipsec_mode_t mode) -{ - switch (mode) - { - case MODE_TRANSPORT: - return IPSEC_MODE_TRANSPORT; - case MODE_TUNNEL: - return IPSEC_MODE_TUNNEL; -#ifdef HAVE_IPSEC_MODE_BEET - case MODE_BEET: - return IPSEC_MODE_BEET; -#endif - default: - return mode; - } -} - -/** - * convert the general policy direction to the one defined in ipsec.h - */ -static u_int8_t dir2kernel(policy_dir_t dir) -{ - switch (dir) - { - case POLICY_IN: - return IPSEC_DIR_INBOUND; - case POLICY_OUT: - return IPSEC_DIR_OUTBOUND; -#ifdef HAVE_IPSEC_DIR_FWD - case POLICY_FWD: - return IPSEC_DIR_FWD; -#endif - default: - return IPSEC_DIR_INVALID; - } -} - -#ifdef SADB_X_MIGRATE -/** - * convert the policy direction in ipsec.h to the general one. - */ -static policy_dir_t kernel2dir(u_int8_t dir) -{ - switch (dir) - { - case IPSEC_DIR_INBOUND: - return POLICY_IN; - case IPSEC_DIR_OUTBOUND: - return POLICY_OUT; -#ifdef HAVE_IPSEC_DIR_FWD - case IPSEC_DIR_FWD: - return POLICY_FWD; -#endif - default: - return dir; - } -} -#endif /*SADB_X_MIGRATE*/ - -typedef struct kernel_algorithm_t kernel_algorithm_t; - -/** - * Mapping of IKEv2 algorithms to PF_KEY algorithms - */ -struct kernel_algorithm_t { - /** - * Identifier specified in IKEv2 - */ - int ikev2; - - /** - * Identifier as defined in pfkeyv2.h - */ - int kernel; -}; - -#define END_OF_LIST -1 - -/** - * Algorithms for encryption - */ -static kernel_algorithm_t encryption_algs[] = { -/* {ENCR_DES_IV64, 0 }, */ - {ENCR_DES, SADB_EALG_DESCBC }, - {ENCR_3DES, SADB_EALG_3DESCBC }, -/* {ENCR_RC5, 0 }, */ -/* {ENCR_IDEA, 0 }, */ - {ENCR_CAST, SADB_X_EALG_CASTCBC }, - {ENCR_BLOWFISH, SADB_X_EALG_BLOWFISHCBC }, -/* {ENCR_3IDEA, 0 }, */ -/* {ENCR_DES_IV32, 0 }, */ - {ENCR_NULL, SADB_EALG_NULL }, - {ENCR_AES_CBC, SADB_X_EALG_AESCBC }, -/* {ENCR_AES_CTR, SADB_X_EALG_AESCTR }, */ -/* {ENCR_AES_CCM_ICV8, SADB_X_EALG_AES_CCM_ICV8 }, */ -/* {ENCR_AES_CCM_ICV12, SADB_X_EALG_AES_CCM_ICV12 }, */ -/* {ENCR_AES_CCM_ICV16, SADB_X_EALG_AES_CCM_ICV16 }, */ -/* {ENCR_AES_GCM_ICV8, SADB_X_EALG_AES_GCM_ICV8 }, */ -/* {ENCR_AES_GCM_ICV12, SADB_X_EALG_AES_GCM_ICV12 }, */ -/* {ENCR_AES_GCM_ICV16, SADB_X_EALG_AES_GCM_ICV16 }, */ - {END_OF_LIST, 0 }, -}; - -/** - * Algorithms for integrity protection - */ -static kernel_algorithm_t integrity_algs[] = { - {AUTH_HMAC_MD5_96, SADB_AALG_MD5HMAC }, - {AUTH_HMAC_SHA1_96, SADB_AALG_SHA1HMAC }, - {AUTH_HMAC_SHA2_256_128, SADB_X_AALG_SHA2_256HMAC }, - {AUTH_HMAC_SHA2_384_192, SADB_X_AALG_SHA2_384HMAC }, - {AUTH_HMAC_SHA2_512_256, SADB_X_AALG_SHA2_512HMAC }, -/* {AUTH_DES_MAC, 0, }, */ -/* {AUTH_KPDK_MD5, 0, }, */ -#ifdef SADB_X_AALG_AES_XCBC_MAC - {AUTH_AES_XCBC_96, SADB_X_AALG_AES_XCBC_MAC, }, -#endif - {END_OF_LIST, 0, }, -}; - -#if 0 -/** - * Algorithms for IPComp, unused yet - */ -static kernel_algorithm_t compression_algs[] = { -/* {IPCOMP_OUI, 0 }, */ - {IPCOMP_DEFLATE, SADB_X_CALG_DEFLATE }, - {IPCOMP_LZS, SADB_X_CALG_LZS }, - {IPCOMP_LZJH, SADB_X_CALG_LZJH }, - {END_OF_LIST, 0 }, -}; -#endif - -/** - * Look up a kernel algorithm ID and its key size - */ -static int lookup_algorithm(kernel_algorithm_t *list, int ikev2) -{ - while (list->ikev2 != END_OF_LIST) - { - if (ikev2 == list->ikev2) - { - return list->kernel; - } - list++; - } - return 0; -} - -/** - * Copy a host_t as sockaddr_t to the given memory location. Ports are - * reset to zero as per RFC 2367. - * @return the number of bytes copied - */ -static size_t hostcpy(void *dest, host_t *host) -{ - sockaddr_t *addr = host->get_sockaddr(host), *dest_addr = dest; - socklen_t *len = host->get_sockaddr_len(host); - memcpy(dest, addr, *len); -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - dest_addr->sa_len = *len; -#endif - switch (dest_addr->sa_family) - { - case AF_INET: - { - struct sockaddr_in *sin = dest; - sin->sin_port = 0; - break; - } - case AF_INET6: - { - struct sockaddr_in6 *sin6 = dest; - sin6->sin6_port = 0; - break; - } - } - return *len; -} - -/** - * add a host behind an sadb_address extension - */ -static void host2ext(host_t *host, struct sadb_address *ext) -{ - size_t len = hostcpy(ext + 1, host); - ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + len); -} - -/** - * add a host to the given sadb_msg - */ -static void add_addr_ext(struct sadb_msg *msg, host_t *host, u_int16_t type, - u_int8_t proto, u_int8_t prefixlen) -{ - struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg); - addr->sadb_address_exttype = type; - addr->sadb_address_proto = proto; - addr->sadb_address_prefixlen = prefixlen; - host2ext(host, addr); - PFKEY_EXT_ADD(msg, addr); -} - -/** - * adds an empty address extension to the given sadb_msg - */ -static void add_anyaddr_ext(struct sadb_msg *msg, int family, u_int8_t type) -{ - socklen_t len = (family == AF_INET) ? sizeof(struct sockaddr_in) : - sizeof(struct sockaddr_in6); - struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg); - addr->sadb_address_exttype = type; - sockaddr_t *saddr = (sockaddr_t*)(addr + 1); - saddr->sa_family = family; -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - saddr->sa_len = len; -#endif - addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len); - PFKEY_EXT_ADD(msg, addr); -} - -#ifdef HAVE_NATT -/** - * add udp encap extensions to a sadb_msg - */ -static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst) -{ - struct sadb_x_nat_t_type* nat_type; - struct sadb_x_nat_t_port* nat_port; - - nat_type = (struct sadb_x_nat_t_type*)PFKEY_EXT_ADD_NEXT(msg); - nat_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; - nat_type->sadb_x_nat_t_type_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_type)); - nat_type->sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP; - PFKEY_EXT_ADD(msg, nat_type); - - nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg); - nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT; - nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port)); - nat_port->sadb_x_nat_t_port_port = htons(src->get_port(src)); - PFKEY_EXT_ADD(msg, nat_port); - - nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg); - nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT; - nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port)); - nat_port->sadb_x_nat_t_port_port = htons(dst->get_port(dst)); - PFKEY_EXT_ADD(msg, nat_port); -} -#endif /*HAVE_NATT*/ - -/** - * Convert a sadb_address to a traffic_selector - */ -static traffic_selector_t* sadb_address2ts(struct sadb_address *address) -{ - traffic_selector_t *ts; - host_t *host; - - /* The Linux 2.6 kernel does not set the protocol and port information - * in the src and dst sadb_address extensions of the SADB_ACQUIRE message. - */ - host = host_create_from_sockaddr((sockaddr_t*)&address[1]) ; - ts = traffic_selector_create_from_subnet(host, address->sadb_address_prefixlen, - address->sadb_address_proto, host->get_port(host)); - return ts; -} - -/** - * Parses a pfkey message received from the kernel - */ -static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out) -{ - struct sadb_ext* ext; - size_t len; - - memset(out, 0, sizeof(pfkey_msg_t)); - out->msg = msg; - - len = msg->sadb_msg_len; - len -= PFKEY_LEN(sizeof(struct sadb_msg)); - - ext = (struct sadb_ext*)(((char*)msg) + sizeof(struct sadb_msg)); - - while (len >= PFKEY_LEN(sizeof(struct sadb_ext))) - { - DBG3(DBG_KNL, " %N", sadb_ext_type_names, ext->sadb_ext_type); - if (ext->sadb_ext_len < PFKEY_LEN(sizeof(struct sadb_ext)) || - ext->sadb_ext_len > len) - { - DBG1(DBG_KNL, "length of %N extension is invalid", - sadb_ext_type_names, ext->sadb_ext_type); - break; - } - - if ((ext->sadb_ext_type > SADB_EXT_MAX) || (!ext->sadb_ext_type)) - { - DBG1(DBG_KNL, "type of PF_KEY extension (%d) is invalid", ext->sadb_ext_type); - break; - } - - if (out->ext[ext->sadb_ext_type]) - { - DBG1(DBG_KNL, "duplicate %N extension", - sadb_ext_type_names, ext->sadb_ext_type); - break; - } - - out->ext[ext->sadb_ext_type] = ext; - ext = PFKEY_EXT_NEXT_LEN(ext, len); - } - - if (len) - { - DBG1(DBG_KNL, "PF_KEY message length is invalid"); - return FAILED; - } - - return SUCCESS; -} - -/** - * Send a message to a specific PF_KEY socket and handle the response. - */ -static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket, - struct sadb_msg *in, struct sadb_msg **out, size_t *out_len) -{ - unsigned char buf[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg; - int in_len, len; - - this->mutex_pfkey->lock(this->mutex_pfkey); - - /* FIXME: our usage of sequence numbers is probably wrong. check RFC 2367, - * in particular the behavior in response to an SADB_ACQUIRE. */ - in->sadb_msg_seq = ++this->seq; - in->sadb_msg_pid = getpid(); - - in_len = PFKEY_USER_LEN(in->sadb_msg_len); - - while (TRUE) - { - len = send(socket, in, in_len, 0); - - if (len != in_len) - { - if (errno == EINTR) - { - /* interrupted, try again */ - continue; - } - this->mutex_pfkey->unlock(this->mutex_pfkey); - DBG1(DBG_KNL, "error sending to PF_KEY socket: %s", strerror(errno)); - return FAILED; - } - break; - } - - while (TRUE) - { - msg = (struct sadb_msg*)buf; - - len = recv(socket, buf, sizeof(buf), 0); - - if (len < 0) - { - if (errno == EINTR) - { - DBG1(DBG_KNL, "got interrupted"); - /* interrupted, try again */ - continue; - } - DBG1(DBG_KNL, "error reading from PF_KEY socket: %s", strerror(errno)); - this->mutex_pfkey->unlock(this->mutex_pfkey); - return FAILED; - } - if (len < sizeof(struct sadb_msg) || - msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg))) - { - DBG1(DBG_KNL, "received corrupted PF_KEY message"); - this->mutex_pfkey->unlock(this->mutex_pfkey); - return FAILED; - } - if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT) - { - DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message"); - this->mutex_pfkey->unlock(this->mutex_pfkey); - return FAILED; - } - if (msg->sadb_msg_pid != in->sadb_msg_pid) - { - DBG2(DBG_KNL, "received PF_KEY message is not intended for us"); - continue; - } - if (msg->sadb_msg_seq != this->seq) - { - DBG1(DBG_KNL, "received PF_KEY message with unexpected sequence " - "number, was %d expected %d", msg->sadb_msg_seq, this->seq); - if (msg->sadb_msg_seq == 0) - { - /* FreeBSD and Mac OS X do this for the response to - * SADB_X_SPDGET (but not for the response to SADB_GET). - * FreeBSD: 'key_spdget' in /usr/src/sys/netipsec/key.c. */ - } - else if (msg->sadb_msg_seq < this->seq) - { - continue; - } - else - { - this->mutex_pfkey->unlock(this->mutex_pfkey); - return FAILED; - } - } - if (msg->sadb_msg_type != in->sadb_msg_type) - { - DBG2(DBG_KNL, "received PF_KEY message of wrong type, " - "was %d expected %d, ignoring", - msg->sadb_msg_type, in->sadb_msg_type); - } - break; - } - - *out_len = len; - *out = (struct sadb_msg*)malloc(len); - memcpy(*out, buf, len); - - this->mutex_pfkey->unlock(this->mutex_pfkey); - - return SUCCESS; -} - -/** - * Send a message to the default PF_KEY socket and handle the response. - */ -static status_t pfkey_send(private_kernel_pfkey_ipsec_t *this, - struct sadb_msg *in, struct sadb_msg **out, size_t *out_len) -{ - return pfkey_send_socket(this, this->socket, in, out, out_len); -} - -/** - * Process a SADB_ACQUIRE message from the kernel - */ -static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg) -{ - pfkey_msg_t response; - u_int32_t index, reqid = 0; - traffic_selector_t *src_ts, *dst_ts; - policy_entry_t *policy; - job_t *job; - - switch (msg->sadb_msg_satype) - { - case SADB_SATYPE_UNSPEC: - case SADB_SATYPE_ESP: - case SADB_SATYPE_AH: - break; - default: - /* acquire for AH/ESP only */ - return; - } - DBG2(DBG_KNL, "received an SADB_ACQUIRE"); - - if (parse_pfkey_message(msg, &response) != SUCCESS) - { - DBG1(DBG_KNL, "parsing SADB_ACQUIRE from kernel failed"); - return; - } - - index = response.x_policy->sadb_x_policy_id; - this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_match_byindex, (void**)&policy, &index) == SUCCESS) - { - reqid = policy->reqid; - } - else - { - DBG1(DBG_KNL, "received an SADB_ACQUIRE with policy id %d but no matching policy found", - index); - } - src_ts = sadb_address2ts(response.src); - dst_ts = sadb_address2ts(response.dst); - this->mutex->unlock(this->mutex); - - DBG1(DBG_KNL, "creating acquire job for policy %R === %R with reqid {%u}", - src_ts, dst_ts, reqid); - job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts); - charon->processor->queue_job(charon->processor, job); -} - -/** - * Process a SADB_EXPIRE message from the kernel - */ -static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg) -{ - pfkey_msg_t response; - protocol_id_t protocol; - u_int32_t spi, reqid; - bool hard; - job_t *job; - - DBG2(DBG_KNL, "received an SADB_EXPIRE"); - - if (parse_pfkey_message(msg, &response) != SUCCESS) - { - DBG1(DBG_KNL, "parsing SADB_EXPIRE from kernel failed"); - return; - } - - protocol = proto_satype2ike(msg->sadb_msg_satype); - spi = response.sa->sadb_sa_spi; - reqid = response.x_sa2->sadb_x_sa2_reqid; - hard = response.lft_hard != NULL; - - if (protocol != PROTO_ESP && protocol != PROTO_AH) - { - DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and reqid {%u} " - "which is not a CHILD_SA", ntohl(spi), reqid); - return; - } - - DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}", - hard ? "delete" : "rekey", protocol_id_names, - protocol, ntohl(spi), reqid); - if (hard) - { - job = (job_t*)delete_child_sa_job_create(reqid, protocol, spi); - } - else - { - job = (job_t*)rekey_child_sa_job_create(reqid, protocol, spi); - } - charon->processor->queue_job(charon->processor, job); -} - -#ifdef SADB_X_MIGRATE -/** - * Process a SADB_X_MIGRATE message from the kernel - */ -static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg) -{ - pfkey_msg_t response; - traffic_selector_t *src_ts, *dst_ts; - policy_dir_t dir; - u_int32_t reqid = 0; - host_t *local = NULL, *remote = NULL; - job_t *job; - - DBG2(DBG_KNL, "received an SADB_X_MIGRATE"); - - if (parse_pfkey_message(msg, &response) != SUCCESS) - { - DBG1(DBG_KNL, "parsing SADB_X_MIGRATE from kernel failed"); - return; - } - src_ts = sadb_address2ts(response.src); - dst_ts = sadb_address2ts(response.dst); - dir = kernel2dir(response.x_policy->sadb_x_policy_dir); - DBG2(DBG_KNL, " policy %R === %R %N, id %u", src_ts, dst_ts, - policy_dir_names, dir); - - /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */ - if (response.x_kmaddress) - { - sockaddr_t *local_addr, *remote_addr; - u_int32_t local_len; - - local_addr = (sockaddr_t*)&response.x_kmaddress[1]; - local = host_create_from_sockaddr(local_addr); - local_len = (local_addr->sa_family == AF_INET6)? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); - remote_addr = (sockaddr_t*)((u_int8_t*)local_addr + local_len); - remote = host_create_from_sockaddr(remote_addr); - DBG2(DBG_KNL, " kmaddress: %H...%H", local, remote); - } - - if (src_ts && dst_ts && local && remote) - { - DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}", - src_ts, dst_ts, policy_dir_names, dir, reqid, local); - job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, dir, - local, remote); - charon->processor->queue_job(charon->processor, job); - } - else - { - DESTROY_IF(src_ts); - DESTROY_IF(dst_ts); - DESTROY_IF(local); - DESTROY_IF(remote); - } -} -#endif /*SADB_X_MIGRATE*/ - -#ifdef SADB_X_NAT_T_NEW_MAPPING -/** - * Process a SADB_X_NAT_T_NEW_MAPPING message from the kernel - */ -static void process_mapping(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg) -{ - pfkey_msg_t response; - u_int32_t spi, reqid; - host_t *host; - job_t *job; - - DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING"); - - if (parse_pfkey_message(msg, &response) != SUCCESS) - { - DBG1(DBG_KNL, "parsing SADB_X_NAT_T_NEW_MAPPING from kernel failed"); - return; - } - - if (!response.x_sa2) - { - DBG1(DBG_KNL, "received SADB_X_NAT_T_NEW_MAPPING is missing required information"); - return; - } - - spi = response.sa->sadb_sa_spi; - reqid = response.x_sa2->sadb_x_sa2_reqid; - - if (proto_satype2ike(msg->sadb_msg_satype) == PROTO_ESP) - { - sockaddr_t *sa = (sockaddr_t*)(response.dst + 1); - switch (sa->sa_family) - { - case AF_INET: - { - struct sockaddr_in *sin = (struct sockaddr_in*)sa; - sin->sin_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port); - } - case AF_INET6: - { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa; - sin6->sin6_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port); - } - default: - break; - } - host = host_create_from_sockaddr(sa); - if (host) - { - DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and " - "reqid {%u} changed, queuing update job", ntohl(spi), reqid); - job = (job_t*)update_sa_job_create(reqid, host); - charon->processor->queue_job(charon->processor, job); - } - } -} -#endif /*SADB_X_NAT_T_NEW_MAPPING*/ - -/** - * Receives events from kernel - */ -static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this) -{ - unsigned char buf[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg = (struct sadb_msg*)buf; - int len; - bool oldstate; - - oldstate = thread_cancelability(TRUE); - len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0); - thread_cancelability(oldstate); - - if (len < 0) - { - switch (errno) - { - case EINTR: - /* interrupted, try again */ - return JOB_REQUEUE_DIRECT; - case EAGAIN: - /* no data ready, select again */ - return JOB_REQUEUE_DIRECT; - default: - DBG1(DBG_KNL, "unable to receive from PF_KEY event socket"); - sleep(1); - return JOB_REQUEUE_FAIR; - } - } - - if (len < sizeof(struct sadb_msg) || - msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg))) - { - DBG2(DBG_KNL, "received corrupted PF_KEY message"); - return JOB_REQUEUE_DIRECT; - } - if (msg->sadb_msg_pid != 0) - { /* not from kernel. not interested, try another one */ - return JOB_REQUEUE_DIRECT; - } - if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT) - { - DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message"); - return JOB_REQUEUE_DIRECT; - } - - switch (msg->sadb_msg_type) - { - case SADB_ACQUIRE: - process_acquire(this, msg); - break; - case SADB_EXPIRE: - process_expire(this, msg); - break; -#ifdef SADB_X_MIGRATE - case SADB_X_MIGRATE: - process_migrate(this, msg); - break; -#endif /*SADB_X_MIGRATE*/ -#ifdef SADB_X_NAT_T_NEW_MAPPING - case SADB_X_NAT_T_NEW_MAPPING: - process_mapping(this, msg); - break; -#endif /*SADB_X_NAT_T_NEW_MAPPING*/ - default: - break; - } - - return JOB_REQUEUE_DIRECT; -} - -METHOD(kernel_ipsec_t, get_spi, status_t, - private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, - protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_x_sa2 *sa2; - struct sadb_spirange *range; - pfkey_msg_t response; - u_int32_t received_spi = 0; - size_t len; - - memset(&request, 0, sizeof(request)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_GETSPI; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg); - sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2; - sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange)); - sa2->sadb_x_sa2_reqid = reqid; - PFKEY_EXT_ADD(msg, sa2); - - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); - - range = (struct sadb_spirange*)PFKEY_EXT_ADD_NEXT(msg); - range->sadb_spirange_exttype = SADB_EXT_SPIRANGE; - range->sadb_spirange_len = PFKEY_LEN(sizeof(struct sadb_spirange)); - range->sadb_spirange_min = 0xc0000000; - range->sadb_spirange_max = 0xcFFFFFFF; - PFKEY_EXT_ADD(msg, range); - - if (pfkey_send(this, msg, &out, &len) == SUCCESS) - { - if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "allocating SPI failed: %s (%d)", - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - } - else if (parse_pfkey_message(out, &response) == SUCCESS) - { - received_spi = response.sa->sadb_sa_spi; - } - free(out); - } - - if (received_spi == 0) - { - return FAILED; - } - - *spi = received_spi; - return SUCCESS; -} - -METHOD(kernel_ipsec_t, get_cpi, status_t, - private_kernel_pfkey_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_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi, - protocol_id_t protocol, u_int32_t reqid, mark_t mark, - 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 inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - struct sadb_x_sa2 *sa2; - struct sadb_lifetime *lft; - struct sadb_key *key; - size_t len; - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", ntohl(spi), reqid); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = inbound ? SADB_UPDATE : SADB_ADD; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - -#ifdef __APPLE__ - if (encap) - { - struct sadb_sa_2 *sa_2; - sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg); - sa_2->sadb_sa_natt_port = dst->get_port(dst); - sa = &sa_2->sa; - sa->sadb_sa_flags |= SADB_X_EXT_NATT; - len = sizeof(struct sadb_sa_2); - } - else -#endif - { - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - len = sizeof(struct sadb_sa); - } - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(len); - sa->sadb_sa_spi = spi; - sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32; - sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg); - sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg); - PFKEY_EXT_ADD(msg, sa); - - sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg); - sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2; - sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange)); - sa2->sadb_x_sa2_mode = mode2kernel(mode); - sa2->sadb_x_sa2_reqid = reqid; - PFKEY_EXT_ADD(msg, sa2); - - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); - - lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); - lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; - lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); - lft->sadb_lifetime_allocations = lifetime->packets.rekey; - lft->sadb_lifetime_bytes = lifetime->bytes.rekey; - lft->sadb_lifetime_addtime = lifetime->time.rekey; - lft->sadb_lifetime_usetime = 0; /* we only use addtime */ - PFKEY_EXT_ADD(msg, lft); - - lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); - lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; - lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); - lft->sadb_lifetime_allocations = lifetime->packets.life; - lft->sadb_lifetime_bytes = lifetime->bytes.life; - lft->sadb_lifetime_addtime = lifetime->time.life; - lft->sadb_lifetime_usetime = 0; /* we only use addtime */ - PFKEY_EXT_ADD(msg, lft); - - if (enc_alg != ENCR_UNDEFINED) - { - if (!sa->sadb_sa_encrypt) - { - DBG1(DBG_KNL, "algorithm %N not supported by kernel!", - encryption_algorithm_names, enc_alg); - return FAILED; - } - DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", - encryption_algorithm_names, enc_alg, enc_key.len * 8); - - key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg); - key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; - key->sadb_key_bits = enc_key.len * 8; - key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + enc_key.len); - memcpy(key + 1, enc_key.ptr, enc_key.len); - - PFKEY_EXT_ADD(msg, key); - } - - if (int_alg != AUTH_UNDEFINED) - { - if (!sa->sadb_sa_auth) - { - DBG1(DBG_KNL, "algorithm %N not supported by kernel!", - integrity_algorithm_names, int_alg); - return FAILED; - } - DBG2(DBG_KNL, " using integrity algorithm %N with key size %d", - integrity_algorithm_names, int_alg, int_key.len * 8); - - key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg); - key->sadb_key_exttype = SADB_EXT_KEY_AUTH; - key->sadb_key_bits = int_key.len * 8; - key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + int_key.len); - memcpy(key + 1, int_key.ptr, int_key.len); - - PFKEY_EXT_ADD(msg, key); - } - - if (ipcomp != IPCOMP_NONE) - { - /*TODO*/ - } - -#ifdef HAVE_NATT - if (encap) - { - add_encap_ext(msg, src, dst); - } -#endif /*HAVE_NATT*/ - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, update_sa, status_t, - private_kernel_pfkey_ipsec_t *this, u_int32_t spi, protocol_id_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) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - pfkey_msg_t response; - size_t len; - - /* we can't update the SA if any of the ip addresses have changed. - * that's because we can't use SADB_UPDATE and by deleting and readding the - * SA the sequence numbers would get lost */ - if (!src->ip_equals(src, new_src) || - !dst->ip_equals(dst, new_dst)) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: address changes" - " are not supported", ntohl(spi)); - return NOT_SUPPORTED; - } - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_GET; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - PFKEY_EXT_ADD(msg, sa); - - /* the kernel wants a SADB_EXT_ADDRESS_SRC to be present even though - * it is not used for anything. */ - add_anyaddr_ext(msg, dst->get_family(dst), SADB_EXT_ADDRESS_SRC); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", - ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - else if (parse_pfkey_message(out, &response) != SUCCESS) - { - DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: parsing response " - "from kernel failed", ntohl(spi)); - free(out); - return FAILED; - } - - DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H", - ntohl(spi), src, dst, new_src, new_dst); - - memset(&request, 0, sizeof(request)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_UPDATE; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - -#ifdef __APPLE__ - { - struct sadb_sa_2 *sa_2; - sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg); - sa_2->sa.sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa_2)); - memcpy(&sa_2->sa, response.sa, sizeof(struct sadb_sa)); - if (encap) - { - sa_2->sadb_sa_natt_port = new_dst->get_port(new_dst); - sa_2->sa.sadb_sa_flags |= SADB_X_EXT_NATT; - } - } -#else - PFKEY_EXT_COPY(msg, response.sa); -#endif - PFKEY_EXT_COPY(msg, response.x_sa2); - - PFKEY_EXT_COPY(msg, response.src); - PFKEY_EXT_COPY(msg, response.dst); - - PFKEY_EXT_COPY(msg, response.lft_soft); - PFKEY_EXT_COPY(msg, response.lft_hard); - - if (response.key_encr) - { - PFKEY_EXT_COPY(msg, response.key_encr); - } - - if (response.key_auth) - { - PFKEY_EXT_COPY(msg, response.key_auth); - } - -#ifdef HAVE_NATT - if (new_encap) - { - add_encap_ext(msg, new_src, new_dst); - } -#endif /*HAVE_NATT*/ - - free(out); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, query_sa, status_t, - private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - pfkey_msg_t response; - size_t len; - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_GET; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - PFKEY_EXT_ADD(msg, sa); - - /* the Linux Kernel doesn't care for the src address, but other systems do - * (e.g. FreeBSD) - */ - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - else if (parse_pfkey_message(out, &response) != SUCCESS) - { - DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); - free(out); - return FAILED; - } - *bytes = response.lft_current->sadb_lifetime_bytes; - - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, del_sa, status_t, - private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_sa *sa; - size_t len; - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_DELETE; - msg->sadb_msg_satype = proto_ike2satype(protocol); - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); - sa->sadb_sa_exttype = SADB_EXT_SA; - sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); - sa->sadb_sa_spi = spi; - PFKEY_EXT_ADD(msg, sa); - - /* the Linux Kernel doesn't care for the src address, but other systems do - * (e.g. FreeBSD) - */ - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi)); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x: %s (%d)", - ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - - DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi)); - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, add_policy, status_t, - private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts, - policy_dir_t direction, u_int32_t spi, protocol_id_t protocol, - u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp, - u_int16_t cpi, bool routed) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_x_policy *pol; - struct sadb_x_ipsecrequest *req; - policy_entry_t *policy, *found = NULL; - pfkey_msg_t response; - size_t len; - - if (dir2kernel(direction) == IPSEC_DIR_INVALID) - { - /* FWD policies are not supported on all platforms */ - return SUCCESS; - } - - /* create a policy */ - policy = create_policy_entry(src_ts, dst_ts, direction, reqid); - - /* find a matching policy */ - this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, (void**)&found, policy) == SUCCESS) - { - /* use existing policy */ - found->refcount++; - DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing " - "refcount", src_ts, dst_ts, - policy_dir_names, direction); - policy_entry_destroy(policy); - policy = found; - } - else - { - /* apply the new one, if we have no such policy */ - this->policies->insert_last(this->policies, policy); - policy->refcount = 1; - } - - memset(&request, 0, sizeof(request)); - - DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = found ? SADB_X_SPDUPDATE : SADB_X_SPDADD; - msg->sadb_msg_satype = 0; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); - pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; - pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy)); - pol->sadb_x_policy_id = 0; - pol->sadb_x_policy_dir = dir2kernel(direction); - pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; -#ifdef HAVE_STRUCT_SADB_X_POLICY_SADB_X_POLICY_PRIORITY - /* calculate priority based on source selector size, small size = high prio */ - pol->sadb_x_policy_priority = routed ? PRIO_LOW : PRIO_HIGH; - pol->sadb_x_policy_priority -= policy->src.mask * 10; - pol->sadb_x_policy_priority -= policy->src.proto != IPSEC_PROTO_ANY ? 2 : 0; - pol->sadb_x_policy_priority -= policy->src.net->get_port(policy->src.net) ? 1 : 0; -#endif - - /* one or more sadb_x_ipsecrequest extensions are added to the sadb_x_policy extension */ - req = (struct sadb_x_ipsecrequest*)(pol + 1); - req->sadb_x_ipsecrequest_proto = proto_ike2ip(protocol); - /* !!! the length of this struct MUST be in octets instead of 64 bit words */ - req->sadb_x_ipsecrequest_len = sizeof(struct sadb_x_ipsecrequest); - req->sadb_x_ipsecrequest_mode = mode2kernel(mode); - req->sadb_x_ipsecrequest_reqid = reqid; - req->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE; - if (mode == MODE_TUNNEL) - { - len = hostcpy(req + 1, src); - req->sadb_x_ipsecrequest_len += len; - len = hostcpy((char*)(req + 1) + len, dst); - req->sadb_x_ipsecrequest_len += len; - } - - pol->sadb_x_policy_len += PFKEY_LEN(req->sadb_x_ipsecrequest_len); - PFKEY_EXT_ADD(msg, pol); - - add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, - policy->src.mask); - add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, - policy->dst.mask); - -#ifdef __FreeBSD__ - { /* on FreeBSD a lifetime has to be defined to be able to later query - * the current use time. */ - struct sadb_lifetime *lft; - lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); - lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; - lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); - lft->sadb_lifetime_addtime = LONG_MAX; - PFKEY_EXT_ADD(msg, lft); - } -#endif - - this->mutex->unlock(this->mutex); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to add policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to add policy %R === %R %N: %s (%d)", src_ts, dst_ts, - policy_dir_names, direction, - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - else if (parse_pfkey_message(out, &response) != SUCCESS) - { - DBG1(DBG_KNL, "unable to add policy %R === %R %N: parsing response " - "from kernel failed", src_ts, dst_ts, policy_dir_names, direction); - free(out); - return FAILED; - } - - this->mutex->lock(this->mutex); - - /* we try to find the policy again and update the kernel index */ - if (this->policies->find_last(this->policies, NULL, (void**)&policy) != SUCCESS) - { - DBG2(DBG_KNL, "unable to update index, the policy %R === %R %N is " - "already gone, ignoring", src_ts, dst_ts, policy_dir_names, direction); - this->mutex->unlock(this->mutex); - free(out); - return SUCCESS; - } - policy->index = response.x_policy->sadb_x_policy_id; - free(out); - - /* install a route, if: - * - we are NOT updating a policy - * - this is a forward policy (to just get one for each child) - * - we are in tunnel mode - * - we are not using IPv6 (does not work correctly yet!) - * - routing is not disabled via strongswan.conf - */ - if (policy->route == NULL && direction == POLICY_FWD && - mode != MODE_TRANSPORT && src->get_family(src) != AF_INET6 && - this->install_routes) - { - route_entry_t *route = malloc_thing(route_entry_t); - - if (charon->kernel_interface->get_address_by_ts(charon->kernel_interface, - dst_ts, &route->src_ip) == SUCCESS) - { - /* get the nexthop to src (src as we are in POLICY_FWD).*/ - route->gateway = charon->kernel_interface->get_nexthop( - charon->kernel_interface, src); - route->if_name = charon->kernel_interface->get_interface( - charon->kernel_interface, dst); - route->dst_net = chunk_clone(policy->src.net->get_address(policy->src.net)); - route->prefixlen = policy->src.mask; - - if (route->if_name) - { - switch (charon->kernel_interface->add_route( - charon->kernel_interface, route->dst_net, - route->prefixlen, route->gateway, - route->src_ip, route->if_name)) - { - default: - DBG1(DBG_KNL, "unable to install source route for %H", - route->src_ip); - /* FALL */ - case ALREADY_DONE: - /* route exists, do not uninstall */ - route_entry_destroy(route); - break; - case SUCCESS: - /* cache the installed route */ - policy->route = route; - break; - } - } - else - { - route_entry_destroy(route); - } - } - else - { - free(route); - } - } - - this->mutex->unlock(this->mutex); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, query_policy, status_t, - private_kernel_pfkey_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) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_x_policy *pol; - policy_entry_t *policy, *found = NULL; - pfkey_msg_t response; - size_t len; - - if (dir2kernel(direction) == IPSEC_DIR_INVALID) - { - /* FWD policies are not supported on all platforms */ - return NOT_FOUND; - } - - DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - - /* create a policy */ - policy = create_policy_entry(src_ts, dst_ts, direction, 0); - - /* find a matching policy */ - this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, (void**)&found, policy) != SUCCESS) - { - DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", src_ts, - dst_ts, policy_dir_names, direction); - policy_entry_destroy(policy); - this->mutex->unlock(this->mutex); - return NOT_FOUND; - } - policy_entry_destroy(policy); - policy = found; - - memset(&request, 0, sizeof(request)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_X_SPDGET; - msg->sadb_msg_satype = 0; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); - pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; - pol->sadb_x_policy_id = policy->index; - pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy)); - pol->sadb_x_policy_dir = dir2kernel(direction); - pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; - PFKEY_EXT_ADD(msg, pol); - - add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, - policy->src.mask); - add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, - policy->dst.mask); - - this->mutex->unlock(this->mutex); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to query policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to query policy %R === %R %N: %s (%d)", src_ts, - dst_ts, policy_dir_names, direction, - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - else if (parse_pfkey_message(out, &response) != SUCCESS) - { - DBG1(DBG_KNL, "unable to query policy %R === %R %N: parsing response " - "from kernel failed", src_ts, dst_ts, policy_dir_names, direction); - free(out); - return FAILED; - } - else if (response.lft_current == NULL) - { - DBG1(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no " - "use time", src_ts, dst_ts, policy_dir_names, direction); - free(out); - return FAILED; - } - /* we need the monotonic time, but the kernel returns system time. */ - if (response.lft_current->sadb_lifetime_usetime) - { - *use_time = time_monotonic(NULL) - - (time(NULL) - response.lft_current->sadb_lifetime_usetime); - } - else - { - *use_time = 0; - } - free(out); - - return SUCCESS; -} - -METHOD(kernel_ipsec_t, del_policy, status_t, - private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, - bool unrouted) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - struct sadb_x_policy *pol; - policy_entry_t *policy, *found = NULL; - route_entry_t *route; - size_t len; - - if (dir2kernel(direction) == IPSEC_DIR_INVALID) - { - /* FWD policies are not supported on all platforms */ - return SUCCESS; - } - - DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - - /* create a policy */ - policy = create_policy_entry(src_ts, dst_ts, direction, 0); - - /* find a matching policy */ - this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, (void**)&found, policy) == SUCCESS) - { - if (--found->refcount > 0) - { - /* is used by more SAs, keep in kernel */ - DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed"); - policy_entry_destroy(policy); - this->mutex->unlock(this->mutex); - return SUCCESS; - } - /* remove if last reference */ - this->policies->remove(this->policies, found, NULL); - policy_entry_destroy(policy); - policy = found; - } - else - { - DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts, - dst_ts, policy_dir_names, direction); - policy_entry_destroy(policy); - this->mutex->unlock(this->mutex); - return NOT_FOUND; - } - this->mutex->unlock(this->mutex); - - memset(&request, 0, sizeof(request)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_X_SPDDELETE; - msg->sadb_msg_satype = 0; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); - pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; - pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy)); - pol->sadb_x_policy_dir = dir2kernel(direction); - pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; - PFKEY_EXT_ADD(msg, pol); - - add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, - policy->src.mask); - add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, - policy->dst.mask); - - route = policy->route; - policy->route = NULL; - policy_entry_destroy(policy); - - if (pfkey_send(this, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to delete policy %R === %R %N: %s (%d)", src_ts, - dst_ts, policy_dir_names, direction, - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - - if (route) - { - if (charon->kernel_interface->del_route(charon->kernel_interface, - route->dst_net, route->prefixlen, route->gateway, - route->src_ip, route->if_name) != SUCCESS) - { - DBG1(DBG_KNL, "error uninstalling route installed with " - "policy %R === %R %N", src_ts, dst_ts, - policy_dir_names, direction); - } - route_entry_destroy(route); - } - - return SUCCESS; -} - -/** - * Register a socket for AQUIRE/EXPIRE messages - */ -static status_t register_pfkey_socket(private_kernel_pfkey_ipsec_t *this, - u_int8_t satype) -{ - unsigned char request[PFKEY_BUFFER_SIZE]; - struct sadb_msg *msg, *out; - size_t len; - - memset(&request, 0, sizeof(request)); - - msg = (struct sadb_msg*)request; - msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = SADB_REGISTER; - msg->sadb_msg_satype = satype; - msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - - if (pfkey_send_socket(this, this->socket_events, msg, &out, &len) != SUCCESS) - { - DBG1(DBG_KNL, "unable to register PF_KEY socket"); - return FAILED; - } - else if (out->sadb_msg_errno) - { - DBG1(DBG_KNL, "unable to register PF_KEY socket: %s (%d)", - strerror(out->sadb_msg_errno), out->sadb_msg_errno); - free(out); - return FAILED; - } - free(out); - return SUCCESS; -} - -METHOD(kernel_ipsec_t, bypass_socket, bool, - private_kernel_pfkey_ipsec_t *this, int fd, int family) -{ - struct sadb_x_policy policy; - u_int sol, ipsec_policy; - - switch (family) - { - case AF_INET: - { - sol = SOL_IP; - ipsec_policy = IP_IPSEC_POLICY; - break; - } - case AF_INET6: - { - sol = SOL_IPV6; - ipsec_policy = IPV6_IPSEC_POLICY; - break; - } - default: - return FALSE; - } - - memset(&policy, 0, sizeof(policy)); - policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t); - policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; - policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS; - - policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND; - if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) - { - DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s", - strerror(errno)); - return FALSE; - } - policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND; - if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) - { - DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s", - strerror(errno)); - return FALSE; - } - return TRUE; -} - -METHOD(kernel_ipsec_t, destroy, void, - private_kernel_pfkey_ipsec_t *this) -{ - if (this->job) - { - this->job->cancel(this->job); - } - if (this->socket > 0) - { - close(this->socket); - } - if (this->socket_events > 0) - { - close(this->socket_events); - } - this->policies->destroy_function(this->policies, (void*)policy_entry_destroy); - this->mutex->destroy(this->mutex); - this->mutex_pfkey->destroy(this->mutex_pfkey); - free(this); -} - -/* - * Described in header. - */ -kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() -{ - private_kernel_pfkey_ipsec_t *this; - - INIT(this, - .public.interface = { - .get_spi = _get_spi, - .get_cpi = _get_cpi, - .add_sa = _add_sa, - .update_sa = _update_sa, - .query_sa = _query_sa, - .del_sa = _del_sa, - .add_policy = _add_policy, - .query_policy = _query_policy, - .del_policy = _del_policy, - .bypass_socket = _bypass_socket, - .destroy = _destroy, - }, - .policies = linked_list_create(), - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT), - .install_routes = lib->settings->get_bool(lib->settings, - "charon.install_routes", TRUE), - ); - - /* create a PF_KEY socket to communicate with the kernel */ - this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); - if (this->socket <= 0) - { - DBG1(DBG_KNL, "unable to create PF_KEY socket"); - destroy(this); - return NULL; - } - - /* create a PF_KEY socket for ACQUIRE & EXPIRE */ - this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); - if (this->socket_events <= 0) - { - DBG1(DBG_KNL, "unable to create PF_KEY event socket"); - destroy(this); - return NULL; - } - - /* register the event socket */ - if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS || - register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS) - { - DBG1(DBG_KNL, "unable to register PF_KEY event socket"); - destroy(this); - return NULL; - } - - this->job = callback_job_create((callback_job_cb_t)receive_events, - this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); - - return &this->public; -} - diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h deleted file mode 100644 index 649f93733..000000000 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 kernel_pfkey_ipsec_i kernel_pfkey_ipsec - * @{ @ingroup kernel_pfkey - */ - -#ifndef KERNEL_PFKEY_IPSEC_H_ -#define KERNEL_PFKEY_IPSEC_H_ - -#include <kernel/kernel_ipsec.h> - -typedef struct kernel_pfkey_ipsec_t kernel_pfkey_ipsec_t; - -/** - * Implementation of the kernel ipsec interface using PF_KEY. - */ -struct kernel_pfkey_ipsec_t { - - /** - * Implements kernel_ipsec_t interface - */ - kernel_ipsec_t interface; -}; - -/** - * Create a PF_KEY kernel ipsec interface instance. - * - * @return kernel_pfkey_ipsec_t instance - */ -kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create(); - -#endif /** KERNEL_PFKEY_IPSEC_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c deleted file mode 100644 index b84ccf150..000000000 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * 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 "kernel_pfkey_plugin.h" - -#include "kernel_pfkey_ipsec.h" - -#include <daemon.h> - -typedef struct private_kernel_pfkey_plugin_t private_kernel_pfkey_plugin_t; - -/** - * private data of kernel PF_KEY plugin - */ -struct private_kernel_pfkey_plugin_t { - /** - * implements plugin interface - */ - kernel_pfkey_plugin_t public; -}; - -/** - * Implementation of plugin_t.destroy - */ -static void destroy(private_kernel_pfkey_plugin_t *this) -{ - charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_pfkey_ipsec_create); - free(this); -} - -/* - * see header file - */ -plugin_t *kernel_pfkey_plugin_create() -{ - private_kernel_pfkey_plugin_t *this = malloc_thing(private_kernel_pfkey_plugin_t); - - this->public.plugin.destroy = (void(*)(plugin_t*))destroy; - - charon->kernel_interface->add_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_pfkey_ipsec_create); - - return &this->public.plugin; -} diff --git a/src/libcharon/plugins/kernel_pfroute/Makefile.am b/src/libcharon/plugins/kernel_pfroute/Makefile.am deleted file mode 100644 index 83db48160..000000000 --- a/src/libcharon/plugins/kernel_pfroute/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ - -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon - -AM_CFLAGS = -rdynamic - -if MONOLITHIC -noinst_LTLIBRARIES = libstrongswan-kernel-pfroute.la -else -plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la -endif - -libstrongswan_kernel_pfroute_la_SOURCES = \ - kernel_pfroute_plugin.h kernel_pfroute_plugin.c \ - kernel_pfroute_net.h kernel_pfroute_net.c - -libstrongswan_kernel_pfroute_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c deleted file mode 100644 index 97c019b58..000000000 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Copyright (C) 2009 Tobias Brunner - * 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 <sys/types.h> -#include <sys/socket.h> -#include <net/if.h> -#include <ifaddrs.h> -#include <net/route.h> -#include <unistd.h> -#include <errno.h> - -#include "kernel_pfroute_net.h" - -#include <daemon.h> -#include <utils/host.h> -#include <threading/thread.h> -#include <threading/mutex.h> -#include <utils/linked_list.h> -#include <processing/jobs/callback_job.h> -#include <processing/jobs/roam_job.h> - -#ifndef HAVE_STRUCT_SOCKADDR_SA_LEN -#error Cannot compile this plugin on systems where 'struct sockaddr' has no sa_len member. -#endif - -/** delay before firing roam jobs (ms) */ -#define ROAM_DELAY 100 - -/** buffer size for PF_ROUTE messages */ -#define PFROUTE_BUFFER_SIZE 4096 - -typedef struct addr_entry_t addr_entry_t; - -/** - * IP address in an inface_entry_t - */ -struct addr_entry_t { - - /** The ip address */ - host_t *ip; - - /** virtual IP managed by us */ - bool virtual; - - /** Number of times this IP is used, if virtual */ - u_int refcount; -}; - -/** - * destroy a addr_entry_t object - */ -static void addr_entry_destroy(addr_entry_t *this) -{ - this->ip->destroy(this->ip); - free(this); -} - -typedef struct iface_entry_t iface_entry_t; - -/** - * A network interface on this system, containing addr_entry_t's - */ -struct iface_entry_t { - - /** interface index */ - int ifindex; - - /** name of the interface */ - char ifname[IFNAMSIZ]; - - /** interface flags, as in netdevice(7) SIOCGIFFLAGS */ - u_int flags; - - /** list of addresses as host_t */ - linked_list_t *addrs; -}; - -/** - * destroy an interface entry - */ -static void iface_entry_destroy(iface_entry_t *this) -{ - this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy); - free(this); -} - - -typedef struct private_kernel_pfroute_net_t private_kernel_pfroute_net_t; - -/** - * Private variables and functions of kernel_pfroute class. - */ -struct private_kernel_pfroute_net_t -{ - /** - * Public part of the kernel_pfroute_t object. - */ - kernel_pfroute_net_t public; - - /** - * mutex to lock access to various lists - */ - mutex_t *mutex; - - /** - * Cached list of interfaces and their addresses (iface_entry_t) - */ - linked_list_t *ifaces; - - /** - * job receiving PF_ROUTE events - */ - callback_job_t *job; - - /** - * mutex to lock access to the PF_ROUTE socket - */ - mutex_t *mutex_pfroute; - - /** - * PF_ROUTE socket to communicate with the kernel - */ - int socket; - - /** - * PF_ROUTE socket to receive events - */ - int socket_events; - - /** - * sequence number for messages sent to the kernel - */ - int seq; - - /** - * time of last roam job - */ - timeval_t last_roam; -}; - -/** - * Start a roaming job. We delay it a bit and fire only one job - * for multiple events. Otherwise we would create too many jobs. - */ -static void fire_roam_job(private_kernel_pfroute_net_t *this, bool address) -{ - timeval_t now; - - time_monotonic(&now); - if (timercmp(&now, &this->last_roam, >)) - { - now.tv_usec += ROAM_DELAY * 1000; - while (now.tv_usec > 1000000) - { - now.tv_sec++; - now.tv_usec -= 1000000; - } - this->last_roam = now; - charon->scheduler->schedule_job_ms(charon->scheduler, - (job_t*)roam_job_create(address), ROAM_DELAY); - } -} - -/** - * Process an RTM_*ADDR message from the kernel - */ -static void process_addr(private_kernel_pfroute_net_t *this, - struct rt_msghdr *msg) -{ - struct ifa_msghdr *ifa = (struct ifa_msghdr*)msg; - sockaddr_t *sockaddr = (sockaddr_t*)(ifa + 1); - host_t *host = NULL; - enumerator_t *ifaces, *addrs; - iface_entry_t *iface; - addr_entry_t *addr; - bool found = FALSE, changed = FALSE, roam = FALSE; - int i; - - for (i = 1; i < (1 << RTAX_MAX); i <<= 1) - { - if (ifa->ifam_addrs & i) - { - if (RTA_IFA & i) - { - host = host_create_from_sockaddr(sockaddr); - break; - } - sockaddr = (sockaddr_t*)((char*)sockaddr + sockaddr->sa_len); - } - } - - if (!host) - { - return; - } - - this->mutex->lock(this->mutex); - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - if (iface->ifindex == ifa->ifam_index) - { - addrs = iface->addrs->create_enumerator(iface->addrs); - while (addrs->enumerate(addrs, &addr)) - { - if (host->ip_equals(host, addr->ip)) - { - found = TRUE; - if (ifa->ifam_type == RTM_DELADDR) - { - iface->addrs->remove_at(iface->addrs, addrs); - if (!addr->virtual) - { - changed = TRUE; - DBG1(DBG_KNL, "%H disappeared from %s", - host, iface->ifname); - } - addr_entry_destroy(addr); - } - else if (ifa->ifam_type == RTM_NEWADDR && addr->virtual) - { - addr->refcount = 1; - } - } - } - addrs->destroy(addrs); - - if (!found && ifa->ifam_type == RTM_NEWADDR) - { - changed = TRUE; - addr = malloc_thing(addr_entry_t); - addr->ip = host->clone(host); - addr->virtual = FALSE; - addr->refcount = 1; - iface->addrs->insert_last(iface->addrs, addr); - DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname); - } - - if (changed && (iface->flags & IFF_UP)) - { - roam = TRUE; - } - break; - } - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - host->destroy(host); - - if (roam) - { - fire_roam_job(this, TRUE); - } -} - -/** - * Process an RTM_IFINFO message from the kernel - */ -static void process_link(private_kernel_pfroute_net_t *this, - struct rt_msghdr *hdr) -{ - struct if_msghdr *msg = (struct if_msghdr*)hdr; - enumerator_t *enumerator; - iface_entry_t *iface; - bool roam = FALSE; - - if (msg->ifm_flags & IFF_LOOPBACK) - { /* ignore loopback interfaces */ - return; - } - - this->mutex->lock(this->mutex); - enumerator = this->ifaces->create_enumerator(this->ifaces); - while (enumerator->enumerate(enumerator, &iface)) - { - if (iface->ifindex == msg->ifm_index) - { - if (!(iface->flags & IFF_UP) && (msg->ifm_flags & IFF_UP)) - { - roam = TRUE; - DBG1(DBG_KNL, "interface %s activated", iface->ifname); - } - else if ((iface->flags & IFF_UP) && !(msg->ifm_flags & IFF_UP)) - { - roam = TRUE; - DBG1(DBG_KNL, "interface %s deactivated", iface->ifname); - } - iface->flags = msg->ifm_flags; - break; - } - } - enumerator->destroy(enumerator); - this->mutex->unlock(this->mutex); - - if (roam) - { - fire_roam_job(this, TRUE); - } -} - -/** - * Process an RTM_*ROUTE message from the kernel - */ -static void process_route(private_kernel_pfroute_net_t *this, - struct rt_msghdr *msg) -{ - -} - -/** - * Receives events from kernel - */ -static job_requeue_t receive_events(private_kernel_pfroute_net_t *this) -{ - unsigned char buf[PFROUTE_BUFFER_SIZE]; - struct rt_msghdr *msg = (struct rt_msghdr*)buf; - int len; - bool oldstate; - - oldstate = thread_cancelability(TRUE); - len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0); - thread_cancelability(oldstate); - - if (len < 0) - { - switch (errno) - { - case EINTR: - /* interrupted, try again */ - return JOB_REQUEUE_DIRECT; - case EAGAIN: - /* no data ready, select again */ - return JOB_REQUEUE_DIRECT; - default: - DBG1(DBG_KNL, "unable to receive from PF_ROUTE event socket"); - sleep(1); - return JOB_REQUEUE_FAIR; - } - } - - if (len < sizeof(msg->rtm_msglen) || len < msg->rtm_msglen || - msg->rtm_version != RTM_VERSION) - { - DBG2(DBG_KNL, "received corrupted PF_ROUTE message"); - return JOB_REQUEUE_DIRECT; - } - - switch (msg->rtm_type) - { - case RTM_NEWADDR: - case RTM_DELADDR: - process_addr(this, msg); - break; - case RTM_IFINFO: - /*case RTM_IFANNOUNCE <- what about this*/ - process_link(this, msg); - break; - case RTM_ADD: - case RTM_DELETE: - process_route(this, msg); - default: - break; - } - - return JOB_REQUEUE_DIRECT; -} - - -/** enumerator over addresses */ -typedef struct { - private_kernel_pfroute_net_t* this; - /** whether to enumerate down interfaces */ - bool include_down_ifaces; - /** whether to enumerate virtual ip addresses */ - bool include_virtual_ips; -} address_enumerator_t; - -/** - * cleanup function for address enumerator - */ -static void address_enumerator_destroy(address_enumerator_t *data) -{ - data->this->mutex->unlock(data->this->mutex); - free(data); -} - -/** - * filter for addresses - */ -static bool filter_addresses(address_enumerator_t *data, addr_entry_t** in, host_t** out) -{ - host_t *ip; - if (!data->include_virtual_ips && (*in)->virtual) - { /* skip virtual interfaces added by us */ - return FALSE; - } - ip = (*in)->ip; - if (ip->get_family(ip) == AF_INET6) - { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip); - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) - { /* skip addresses with a unusable scope */ - return FALSE; - } - } - *out = ip; - return TRUE; -} - -/** - * enumerator constructor for interfaces - */ -static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data) -{ - return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs), - (void*)filter_addresses, data, NULL); -} - -/** - * filter for interfaces - */ -static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, iface_entry_t** out) -{ - if (!data->include_down_ifaces && !((*in)->flags & IFF_UP)) - { /* skip interfaces not up */ - return FALSE; - } - *out = *in; - return TRUE; -} - -/** - * implementation of kernel_net_t.create_address_enumerator - */ -static enumerator_t *create_address_enumerator(private_kernel_pfroute_net_t *this, - bool include_down_ifaces, bool include_virtual_ips) -{ - address_enumerator_t *data = malloc_thing(address_enumerator_t); - data->this = this; - data->include_down_ifaces = include_down_ifaces; - data->include_virtual_ips = include_virtual_ips; - - this->mutex->lock(this->mutex); - return enumerator_create_nested( - enumerator_create_filter(this->ifaces->create_enumerator(this->ifaces), - (void*)filter_interfaces, data, NULL), - (void*)create_iface_enumerator, data, (void*)address_enumerator_destroy); -} - -/** - * implementation of kernel_net_t.get_interface_name - */ -static char *get_interface_name(private_kernel_pfroute_net_t *this, host_t* ip) -{ - enumerator_t *ifaces, *addrs; - iface_entry_t *iface; - addr_entry_t *addr; - char *name = NULL; - - DBG2(DBG_KNL, "getting interface name for %H", ip); - - this->mutex->lock(this->mutex); - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - addrs = iface->addrs->create_enumerator(iface->addrs); - while (addrs->enumerate(addrs, &addr)) - { - if (ip->ip_equals(ip, addr->ip)) - { - name = strdup(iface->ifname); - break; - } - } - addrs->destroy(addrs); - if (name) - { - break; - } - } - ifaces->destroy(ifaces); - this->mutex->unlock(this->mutex); - - if (name) - { - DBG2(DBG_KNL, "%H is on interface %s", ip, name); - } - else - { - DBG2(DBG_KNL, "%H is not a local address", ip); - } - return name; -} - -/** - * Implementation of kernel_net_t.get_source_addr. - */ -static host_t* get_source_addr(private_kernel_pfroute_net_t *this, - host_t *dest, host_t *src) -{ - return NULL; -} - -/** - * Implementation of kernel_net_t.get_nexthop. - */ -static host_t* get_nexthop(private_kernel_pfroute_net_t *this, host_t *dest) -{ - return NULL; -} - -/** - * Implementation of kernel_net_t.add_ip. - */ -static status_t add_ip(private_kernel_pfroute_net_t *this, - host_t *virtual_ip, host_t *iface_ip) -{ - return FAILED; -} - -/** - * Implementation of kernel_net_t.del_ip. - */ -static status_t del_ip(private_kernel_pfroute_net_t *this, host_t *virtual_ip) -{ - return FAILED; -} - -/** - * Implementation of kernel_net_t.add_route. - */ -static status_t add_route(private_kernel_pfroute_net_t *this, chunk_t dst_net, - u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name) -{ - return FAILED; -} - -/** - * Implementation of kernel_net_t.del_route. - */ -static status_t del_route(private_kernel_pfroute_net_t *this, chunk_t dst_net, - u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name) -{ - return FAILED; -} - -/** - * Initialize a list of local addresses. - */ -static status_t init_address_list(private_kernel_pfroute_net_t *this) -{ - struct ifaddrs *ifap, *ifa; - iface_entry_t *iface, *current; - addr_entry_t *addr; - enumerator_t *ifaces, *addrs; - - DBG1(DBG_KNL, "listening on interfaces:"); - - if (getifaddrs(&ifap) < 0) - { - DBG1(DBG_KNL, " failed to get interfaces!"); - return FAILED; - } - - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) - { - if (ifa->ifa_addr == NULL) - { - continue; - } - switch(ifa->ifa_addr->sa_family) - { - case AF_LINK: - case AF_INET: - case AF_INET6: - { - if (ifa->ifa_flags & IFF_LOOPBACK) - { /* ignore loopback interfaces */ - continue; - } - - iface = NULL; - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, ¤t)) - { - if (streq(current->ifname, ifa->ifa_name)) - { - iface = current; - break; - } - } - ifaces->destroy(ifaces); - - if (!iface) - { - iface = malloc_thing(iface_entry_t); - memcpy(iface->ifname, ifa->ifa_name, IFNAMSIZ); - iface->ifindex = if_nametoindex(ifa->ifa_name); - iface->flags = ifa->ifa_flags; - iface->addrs = linked_list_create(); - this->ifaces->insert_last(this->ifaces, iface); - } - - if (ifa->ifa_addr->sa_family != AF_LINK) - { - addr = malloc_thing(addr_entry_t); - addr->ip = host_create_from_sockaddr(ifa->ifa_addr); - addr->virtual = FALSE; - addr->refcount = 1; - iface->addrs->insert_last(iface->addrs, addr); - } - } - } - } - freeifaddrs(ifap); - - ifaces = this->ifaces->create_enumerator(this->ifaces); - while (ifaces->enumerate(ifaces, &iface)) - { - if (iface->flags & IFF_UP) - { - DBG1(DBG_KNL, " %s", iface->ifname); - addrs = iface->addrs->create_enumerator(iface->addrs); - while (addrs->enumerate(addrs, (void**)&addr)) - { - DBG1(DBG_KNL, " %H", addr->ip); - } - addrs->destroy(addrs); - } - } - ifaces->destroy(ifaces); - - return SUCCESS; -} - -/** - * Implementation of kernel_netlink_net_t.destroy. - */ -static void destroy(private_kernel_pfroute_net_t *this) -{ - if (this->job) - { - this->job->cancel(this->job); - } - if (this->socket > 0) - { - close(this->socket); - } - if (this->socket_events) - { - close(this->socket_events); - } - this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy); - this->mutex->destroy(this->mutex); - this->mutex_pfroute->destroy(this->mutex_pfroute); - free(this); -} - -/* - * Described in header. - */ -kernel_pfroute_net_t *kernel_pfroute_net_create() -{ - private_kernel_pfroute_net_t *this = malloc_thing(private_kernel_pfroute_net_t); - - /* public functions */ - this->public.interface.get_interface = (char*(*)(kernel_net_t*,host_t*))get_interface_name; - this->public.interface.create_address_enumerator = (enumerator_t*(*)(kernel_net_t*,bool,bool))create_address_enumerator; - this->public.interface.get_source_addr = (host_t*(*)(kernel_net_t*, host_t *dest, host_t *src))get_source_addr; - this->public.interface.get_nexthop = (host_t*(*)(kernel_net_t*, host_t *dest))get_nexthop; - this->public.interface.add_ip = (status_t(*)(kernel_net_t*,host_t*,host_t*)) add_ip; - this->public.interface.del_ip = (status_t(*)(kernel_net_t*,host_t*)) del_ip; - this->public.interface.add_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) add_route; - this->public.interface.del_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) del_route; - - this->public.interface.destroy = (void(*)(kernel_net_t*)) destroy; - - /* private members */ - this->ifaces = linked_list_create(); - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - this->mutex_pfroute = mutex_create(MUTEX_TYPE_DEFAULT); - - this->seq = 0; - this->socket_events = 0; - this->job = NULL; - - /* create a PF_ROUTE socket to communicate with the kernel */ - this->socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC); - if (this->socket < 0) - { - DBG1(DBG_KNL, "unable to create PF_ROUTE socket"); - destroy(this); - return NULL; - } - - /* create a PF_ROUTE socket to receive events */ - this->socket_events = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC); - if (this->socket_events < 0) - { - DBG1(DBG_KNL, "unable to create PF_ROUTE event socket"); - destroy(this); - return NULL; - } - - this->job = callback_job_create((callback_job_cb_t)receive_events, - this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); - - if (init_address_list(this) != SUCCESS) - { - DBG1(DBG_KNL, "unable to get interface list"); - destroy(this); - return NULL; - } - - return &this->public; -} diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h deleted file mode 100644 index 10c3c9eb7..000000000 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2009 Tobias Brunner - * 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 kernel_pfroute_net_i kernel_pfroute_net - * @{ @ingroup kernel_pfroute - */ - -#ifndef KERNEL_PFROUTE_NET_H_ -#define KERNEL_PFROUTE_NET_H_ - -#include <kernel/kernel_net.h> - -typedef struct kernel_pfroute_net_t kernel_pfroute_net_t; - -/** - * Implementation of the kernel net interface using PF_ROUTE. - */ -struct kernel_pfroute_net_t { - - /** - * Implements kernel_net_t interface - */ - kernel_net_t interface; -}; - -/** - * Create a PF_ROUTE kernel net interface instance. - * - * @return kernel_pfroute_net_t instance - */ -kernel_pfroute_net_t *kernel_pfroute_net_create(); - -#endif /** KERNEL_PFROUTE_NET_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c deleted file mode 100644 index 97139fb56..000000000 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2009 Tobias Brunner - * 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 "kernel_pfroute_plugin.h" - -#include "kernel_pfroute_net.h" - -#include <daemon.h> - -typedef struct private_kernel_pfroute_plugin_t private_kernel_pfroute_plugin_t; - -/** - * private data of kernel PF_ROUTE plugin - */ -struct private_kernel_pfroute_plugin_t { - /** - * implements plugin interface - */ - kernel_pfroute_plugin_t public; -}; - -/** - * Implementation of plugin_t.destroy - */ -static void destroy(private_kernel_pfroute_plugin_t *this) -{ - charon->kernel_interface->remove_net_interface(charon->kernel_interface, - (kernel_net_constructor_t)kernel_pfroute_net_create); - free(this); -} - -/* - * see header file - */ -plugin_t *kernel_pfroute_plugin_create() -{ - private_kernel_pfroute_plugin_t *this = malloc_thing(private_kernel_pfroute_plugin_t); - - this->public.plugin.destroy = (void(*)(plugin_t*))destroy; - - charon->kernel_interface->add_net_interface(charon->kernel_interface, - (kernel_net_constructor_t)kernel_pfroute_net_create); - - return &this->public.plugin; -} diff --git a/src/libcharon/plugins/led/Makefile.am b/src/libcharon/plugins/led/Makefile.am new file mode 100644 index 000000000..6428361fc --- /dev/null +++ b/src/libcharon/plugins/led/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-led.la +else +plugin_LTLIBRARIES = libstrongswan-led.la +endif + +libstrongswan_led_la_SOURCES = led_plugin.h led_plugin.c \ + led_listener.h led_listener.c + +libstrongswan_led_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/kernel_klips/Makefile.in b/src/libcharon/plugins/led/Makefile.in index 9cac89ec3..a4e529d89 100644 --- a/src/libcharon/plugins/kernel_klips/Makefile.in +++ b/src/libcharon/plugins/led/Makefile.in @@ -34,7 +34,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/libcharon/plugins/kernel_klips +subdir = src/libcharon/plugins/led DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -73,18 +74,14 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_kernel_klips_la_LIBADD = -am_libstrongswan_kernel_klips_la_OBJECTS = kernel_klips_plugin.lo \ - kernel_klips_ipsec.lo -libstrongswan_kernel_klips_la_OBJECTS = \ - $(am_libstrongswan_kernel_klips_la_OBJECTS) -libstrongswan_kernel_klips_la_LINK = $(LIBTOOL) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libstrongswan_kernel_klips_la_LDFLAGS) $(LDFLAGS) -o $@ -@MONOLITHIC_FALSE@am_libstrongswan_kernel_klips_la_rpath = -rpath \ -@MONOLITHIC_FALSE@ $(plugindir) -@MONOLITHIC_TRUE@am_libstrongswan_kernel_klips_la_rpath = +libstrongswan_led_la_LIBADD = +am_libstrongswan_led_la_OBJECTS = led_plugin.lo led_listener.lo +libstrongswan_led_la_OBJECTS = $(am_libstrongswan_led_la_OBJECTS) +libstrongswan_led_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_led_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_led_la_rpath = -rpath $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_led_la_rpath = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -98,8 +95,8 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libstrongswan_kernel_klips_la_SOURCES) -DIST_SOURCES = $(libstrongswan_kernel_klips_la_SOURCES) +SOURCES = $(libstrongswan_led_la_SOURCES) +DIST_SOURCES = $(libstrongswan_led_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -168,6 +165,8 @@ 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@ @@ -199,14 +198,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +223,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +255,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ @@ -262,13 +274,12 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = -rdynamic -@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-klips.la -@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-klips.la -libstrongswan_kernel_klips_la_SOURCES = \ - kernel_klips_plugin.h kernel_klips_plugin.c \ - kernel_klips_ipsec.h kernel_klips_ipsec.c pfkeyv2.h +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-led.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-led.la +libstrongswan_led_la_SOURCES = led_plugin.h led_plugin.c \ + led_listener.h led_listener.c -libstrongswan_kernel_klips_la_LDFLAGS = -module -avoid-version +libstrongswan_led_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: @@ -282,9 +293,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_klips/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/led/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_klips/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/led/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -343,8 +354,8 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libstrongswan-kernel-klips.la: $(libstrongswan_kernel_klips_la_OBJECTS) $(libstrongswan_kernel_klips_la_DEPENDENCIES) - $(libstrongswan_kernel_klips_la_LINK) $(am_libstrongswan_kernel_klips_la_rpath) $(libstrongswan_kernel_klips_la_OBJECTS) $(libstrongswan_kernel_klips_la_LIBADD) $(LIBS) +libstrongswan-led.la: $(libstrongswan_led_la_OBJECTS) $(libstrongswan_led_la_DEPENDENCIES) + $(libstrongswan_led_la_LINK) $(am_libstrongswan_led_la_rpath) $(libstrongswan_led_la_OBJECTS) $(libstrongswan_led_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -352,8 +363,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_klips_ipsec.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_klips_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/led_listener.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/led_plugin.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/libcharon/plugins/led/led_listener.c b/src/libcharon/plugins/led/led_listener.c new file mode 100644 index 000000000..18def8005 --- /dev/null +++ b/src/libcharon/plugins/led/led_listener.c @@ -0,0 +1,241 @@ +/* + * 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 "led_listener.h" + +#include <errno.h> + +#include <daemon.h> +#include <threading/mutex.h> +#include <processing/jobs/callback_job.h> + +typedef struct private_led_listener_t private_led_listener_t; + +/** + * Private data of an led_listener_t object. + */ +struct private_led_listener_t { + + /** + * Public led_listener_t interface. + */ + led_listener_t public; + + /** + * Mutex + */ + mutex_t *mutex; + + /** + * Number of established IKE_SAs + */ + int count; + + /** + * LED blink on/off time, in ms + */ + int blink_time; + + /** + * Activity LED fd, if any + */ + FILE *activity; + + /** + * Activity LED maximum brightness + */ + int activity_max; +}; + +/** + * Open a LED brightness control file, get max brightness + */ +static FILE *open_led(char *name, int *max_brightness) +{ + char path[PATH_MAX]; + FILE *f; + + if (!name) + { + return NULL; + } + + *max_brightness = 1; + snprintf(path, sizeof(path), "/sys/class/leds/%s/max_brightness", name); + f = fopen(path, "r"); + if (f) + { + if (fscanf(f, "%d\n", max_brightness) != 1) + { + DBG1(DBG_CFG, "reading max brightness for '%s' failed: %s, using 1", + name, strerror(errno)); + } + fclose(f); + } + else + { + DBG1(DBG_CFG, "reading max_brightness for '%s' failed: %s, using 1", + name, strerror(errno)); + } + + snprintf(path, sizeof(path), "/sys/class/leds/%s/brightness", name); + f = fopen(path, "w"); + if (!f) + { + DBG1(DBG_CFG, "opening LED file '%s' failed: %s", path, strerror(errno)); + } + return f; +} + +/** + * Set a LED to a given brightness + */ +static void set_led(FILE *led, int brightness) +{ + if (led) + { + if (fprintf(led, "%d\n", brightness) <= 0 || + fflush(led) != 0) + { + DBG1(DBG_CFG, "setting LED brightness failed: %s", strerror(errno)); + } + } +} + +/** + * Plugin unloaded? + */ +static bool plugin_gone = FALSE; + +/** + * Reset activity LED after timeout + */ +static job_requeue_t reset_activity_led(private_led_listener_t *this) +{ + if (!plugin_gone) + { /* TODO: fix race */ + this->mutex->lock(this->mutex); + if (this->count) + { + set_led(this->activity, this->activity_max); + } + else + { + set_led(this->activity, 0); + } + this->mutex->unlock(this->mutex); + } + return JOB_REQUEUE_NONE; +} + +/** + * Blink the activity LED + */ +static void blink_activity(private_led_listener_t *this) +{ + if (this->activity) + { + this->mutex->lock(this->mutex); + if (this->count) + { + set_led(this->activity, 0); + } + else + { + 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); + this->mutex->unlock(this->mutex); + } +} + +METHOD(listener_t, ike_state_change, bool, + private_led_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state) +{ + this->mutex->lock(this->mutex); + if (state == IKE_ESTABLISHED && ike_sa->get_state(ike_sa) != IKE_ESTABLISHED) + { + this->count++; + if (this->count == 1) + { + set_led(this->activity, this->activity_max); + } + } + if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && state != IKE_ESTABLISHED) + { + this->count--; + if (this->count == 0) + { + set_led(this->activity, 0); + } + } + this->mutex->unlock(this->mutex); + return TRUE; +} + +METHOD(listener_t, message_hook, bool, + private_led_listener_t *this, ike_sa_t *ike_sa, + message_t *message, bool incoming) +{ + if (incoming || message->get_request(message)) + { + blink_activity(this); + } + return TRUE; +} + +METHOD(led_listener_t, destroy, void, + private_led_listener_t *this) +{ + this->mutex->lock(this->mutex); + set_led(this->activity, 0); + plugin_gone = TRUE; + this->mutex->unlock(this->mutex); + if (this->activity) + { + fclose(this->activity); + } + this->mutex->destroy(this->mutex); + free(this); +} + +/** + * See header + */ +led_listener_t *led_listener_create() +{ + private_led_listener_t *this; + + INIT(this, + .public = { + .listener = { + .ike_state_change = _ike_state_change, + .message = _message_hook, + }, + .destroy = _destroy, + }, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .blink_time = lib->settings->get_int(lib->settings, + "charon.plugins.led.blink_time", 50), + ); + + this->activity = open_led(lib->settings->get_str(lib->settings, + "charon.plugins.led.activity_led", NULL), &this->activity_max); + set_led(this->activity, 0); + + return &this->public; +} diff --git a/src/libcharon/plugins/led/led_listener.h b/src/libcharon/plugins/led/led_listener.h new file mode 100644 index 000000000..05ae28275 --- /dev/null +++ b/src/libcharon/plugins/led/led_listener.h @@ -0,0 +1,49 @@ +/* + * 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 led_listener led_listener + * @{ @ingroup led + */ + +#ifndef LED_LISTENER_H_ +#define LED_LISTENER_H_ + +#include <bus/listeners/listener.h> + +typedef struct led_listener_t led_listener_t; + +/** + * Listener that controls LEDs based on IKEv2 activity/state. + */ +struct led_listener_t { + + /** + * Implements listener_t interface. + */ + listener_t listener; + + /** + * Destroy a led_listener_t. + */ + void (*destroy)(led_listener_t *this); +}; + +/** + * Create a led_listener instance. + */ +led_listener_t *led_listener_create(); + +#endif /** LED_LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/led/led_plugin.c b/src/libcharon/plugins/led/led_plugin.c new file mode 100644 index 000000000..322d198ff --- /dev/null +++ b/src/libcharon/plugins/led/led_plugin.c @@ -0,0 +1,67 @@ +/* + * 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 "led_plugin.h" + +#include "led_listener.h" + +#include <daemon.h> + +typedef struct private_led_plugin_t private_led_plugin_t; + +/** + * private data of led plugin + */ +struct private_led_plugin_t { + + /** + * implements plugin interface + */ + led_plugin_t public; + + /** + * Listener controlling LEDs + */ + led_listener_t *listener; +}; + +METHOD(plugin_t, destroy, void, + private_led_plugin_t *this) +{ + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); + free(this); +} + +/** + * Plugin constructor + */ +plugin_t *led_plugin_create() +{ + private_led_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .destroy = _destroy, + }, + }, + .listener = led_listener_create(), + ); + + charon->bus->add_listener(charon->bus, &this->listener->listener); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h b/src/libcharon/plugins/led/led_plugin.h index 50642a572..a7449addd 100644 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h +++ b/src/libcharon/plugins/led/led_plugin.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2009 Tobias Brunner - * Hochschule fuer Technik Rapperswil + * 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 @@ -14,24 +14,24 @@ */ /** - * @defgroup kernel_pfroute kernel_pfroute + * @defgroup led led * @ingroup cplugins * - * @defgroup kernel_pfroute_plugin kernel_pfroute_plugin - * @{ @ingroup kernel_pfroute + * @defgroup led_plugin led_plugin + * @{ @ingroup led */ -#ifndef KERNEL_PFROUTE_PLUGIN_H_ -#define KERNEL_PFROUTE_PLUGIN_H_ +#ifndef LED_PLUGIN_H_ +#define LED_PLUGIN_H_ #include <plugins/plugin.h> -typedef struct kernel_pfroute_plugin_t kernel_pfroute_plugin_t; +typedef struct led_plugin_t led_plugin_t; /** - * PF_ROUTE kernel interface plugin + * Linux LED control based on IKE activity/state. */ -struct kernel_pfroute_plugin_t { +struct led_plugin_t { /** * implements plugin interface @@ -39,4 +39,4 @@ struct kernel_pfroute_plugin_t { plugin_t plugin; }; -#endif /** KERNEL_PFROUTE_PLUGIN_H_ @}*/ +#endif /** LED_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in index d049bb41b..85db9a10b 100644 --- a/src/libcharon/plugins/load_tester/Makefile.in +++ b/src/libcharon/plugins/load_tester/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -170,6 +171,8 @@ 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@ @@ -201,14 +204,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -223,24 +229,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -248,7 +261,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c index 43c0ef009..aece95e12 100644 --- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c +++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c @@ -36,7 +36,7 @@ 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, - protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi) + u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) { *spi = ++this->spi; return SUCCESS; @@ -51,7 +51,7 @@ METHOD(kernel_ipsec_t, get_cpi, status_t, METHOD(kernel_ipsec_t, add_sa, status_t, private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, u_int32_t reqid, mark_t mark, + u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark, 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 inbound, traffic_selector_t *src_ts, @@ -61,7 +61,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t, } METHOD(kernel_ipsec_t, update_sa, status_t, - private_load_tester_ipsec_t *this, u_int32_t spi, protocol_id_t protocol, + 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) { @@ -70,14 +70,14 @@ METHOD(kernel_ipsec_t, update_sa, status_t, METHOD(kernel_ipsec_t, query_sa, status_t, private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes) + 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, protocol_id_t protocol, u_int16_t cpi, mark_t mark) + u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark) { return SUCCESS; } @@ -85,9 +85,8 @@ METHOD(kernel_ipsec_t, del_sa, status_t, 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, u_int32_t spi, protocol_id_t protocol, - u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp, - u_int16_t cpi, bool routed) + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, + mark_t mark, bool routed) { return SUCCESS; } diff --git a/src/libcharon/plugins/load_tester/load_tester_listener.c b/src/libcharon/plugins/load_tester/load_tester_listener.c index 96b0cf1ec..cf6dd0562 100644 --- a/src/libcharon/plugins/load_tester/load_tester_listener.c +++ b/src/libcharon/plugins/load_tester/load_tester_listener.c @@ -59,7 +59,7 @@ static bool ike_state_change(private_load_tester_listener_t *this, if (this->delete_after_established) { - charon->processor->queue_job(charon->processor, + lib->processor->queue_job(lib->processor, (job_t*)delete_ike_sa_job_create(id, TRUE)); } diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c index 15dbccb00..cb9b80c7f 100644 --- a/src/libcharon/plugins/load_tester/load_tester_plugin.c +++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c @@ -22,6 +22,7 @@ #include <unistd.h> +#include <hydra.h> #include <daemon.h> #include <processing/jobs/callback_job.h> #include <threading/condvar.h> @@ -155,7 +156,7 @@ static void destroy(private_load_tester_plugin_t *this) this->condvar->wait(this->condvar, this->mutex); } this->mutex->unlock(this->mutex); - charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface, + hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface, (kernel_ipsec_constructor_t)load_tester_ipsec_create); charon->backends->remove_backend(charon->backends, &this->config->backend); lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set); @@ -215,13 +216,13 @@ plugin_t *load_tester_plugin_create() if (lib->settings->get_bool(lib->settings, "charon.plugins.load-tester.fake_kernel", FALSE)) { - charon->kernel_interface->add_ipsec_interface(charon->kernel_interface, + 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++) { - charon->processor->queue_job(charon->processor, + lib->processor->queue_job(lib->processor, (job_t*)callback_job_create((callback_job_cb_t)do_load_test, this, NULL, NULL)); } diff --git a/src/libcharon/plugins/maemo/Makefile.am b/src/libcharon/plugins/maemo/Makefile.am new file mode 100644 index 000000000..ed6c76c0f --- /dev/null +++ b/src/libcharon/plugins/maemo/Makefile.am @@ -0,0 +1,23 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon ${maemo_CFLAGS} + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-maemo.la +else +plugin_LTLIBRARIES = libstrongswan-maemo.la +endif + +libstrongswan_maemo_la_SOURCES = \ + maemo_plugin.h maemo_plugin.c \ + maemo_service.h maemo_service.c + +libstrongswan_maemo_la_LDFLAGS = -module -avoid-version +libstrongswan_maemo_la_LIBADD = ${maemo_LIBS} + +dbusservice_DATA = org.strongswan.charon.service + +EXTRA_DIST = $(dbusservice_DATA) + diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in new file mode 100644 index 000000000..978950d22 --- /dev/null +++ b/src/libcharon/plugins/maemo/Makefile.in @@ -0,0 +1,631 @@ +# 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/maemo +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)" \ + "$(DESTDIR)$(dbusservicedir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libstrongswan_maemo_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libstrongswan_maemo_la_OBJECTS = maemo_plugin.lo maemo_service.lo +libstrongswan_maemo_la_OBJECTS = $(am_libstrongswan_maemo_la_OBJECTS) +libstrongswan_maemo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_maemo_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_maemo_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_maemo_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_maemo_la_SOURCES) +DIST_SOURCES = $(libstrongswan_maemo_la_SOURCES) +DATA = $(dbusservice_DATA) +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@ +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@ +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@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ +ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ +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@ +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@ +srcdir = @srcdir@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +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 ${maemo_CFLAGS} + +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-maemo.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-maemo.la +libstrongswan_maemo_la_SOURCES = \ + maemo_plugin.h maemo_plugin.c \ + maemo_service.h maemo_service.c + +libstrongswan_maemo_la_LDFLAGS = -module -avoid-version +libstrongswan_maemo_la_LIBADD = ${maemo_LIBS} +dbusservice_DATA = org.strongswan.charon.service +EXTRA_DIST = $(dbusservice_DATA) +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/maemo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/maemo/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-maemo.la: $(libstrongswan_maemo_la_OBJECTS) $(libstrongswan_maemo_la_DEPENDENCIES) + $(libstrongswan_maemo_la_LINK) $(am_libstrongswan_maemo_la_rpath) $(libstrongswan_maemo_la_OBJECTS) $(libstrongswan_maemo_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maemo_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maemo_service.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 +install-dbusserviceDATA: $(dbusservice_DATA) + @$(NORMAL_INSTALL) + test -z "$(dbusservicedir)" || $(MKDIR_P) "$(DESTDIR)$(dbusservicedir)" + @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbusservicedir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dbusservicedir)" || exit $$?; \ + done + +uninstall-dbusserviceDATA: + @$(NORMAL_UNINSTALL) + @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(dbusservicedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(dbusservicedir)" && rm -f $$files + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(dbusservicedir)"; 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-dbusserviceDATA 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-dbusserviceDATA 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-dbusserviceDATA 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-dbusserviceDATA \ + 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/maemo/maemo_plugin.c b/src/libcharon/plugins/maemo/maemo_plugin.c new file mode 100644 index 000000000..d4549f43a --- /dev/null +++ b/src/libcharon/plugins/maemo/maemo_plugin.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010 Tobias Brunner + * 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 "maemo_plugin.h" +#include "maemo_service.h" + +#include <daemon.h> + +typedef struct private_maemo_plugin_t private_maemo_plugin_t; + +/** + * private data of maemo plugin + */ +struct private_maemo_plugin_t { + + /** + * implements plugin interface + */ + maemo_plugin_t public; + + /** + * service + */ + maemo_service_t *service; + +}; + +METHOD(plugin_t, destroy, void, + private_maemo_plugin_t *this) +{ + this->service->destroy(this->service); + free(this); +} + +/* + * See header + */ +plugin_t *maemo_plugin_create() +{ + private_maemo_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .destroy = _destroy, + }, + }, + ); + + this->service = maemo_service_create(); + if (!this->service) + { + return NULL; + } + + return &this->public.plugin; +} + diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.h b/src/libcharon/plugins/maemo/maemo_plugin.h index 6086217ad..23d139b49 100644 --- a/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.h +++ b/src/libcharon/plugins/maemo/maemo_plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2010 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,24 +14,24 @@ */ /** - * @defgroup kernel_klips kernel_klips + * @defgroup maemo maemo * @ingroup cplugins * - * @defgroup kernel_klips_plugin kernel_klips_plugin - * @{ @ingroup kernel_klips + * @defgroup maemo_plugin maemo_plugin + * @{ @ingroup maemo */ -#ifndef KERNEL_KLIPS_PLUGIN_H_ -#define KERNEL_KLIPS_PLUGIN_H_ +#ifndef MAEMO_PLUGIN_H_ +#define MAEMO_PLUGIN_H_ #include <plugins/plugin.h> -typedef struct kernel_klips_plugin_t kernel_klips_plugin_t; +typedef struct maemo_plugin_t maemo_plugin_t; /** - * PF_KEY kernel interface plugin + * Maemo integration plugin. */ -struct kernel_klips_plugin_t { +struct maemo_plugin_t { /** * implements plugin interface @@ -39,4 +39,4 @@ struct kernel_klips_plugin_t { plugin_t plugin; }; -#endif /** KERNEL_KLIPS_PLUGIN_H_ @}*/ +#endif /** MAEMO_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/maemo/maemo_service.c b/src/libcharon/plugins/maemo/maemo_service.c new file mode 100644 index 000000000..efd914a00 --- /dev/null +++ b/src/libcharon/plugins/maemo/maemo_service.c @@ -0,0 +1,510 @@ +/* + * Copyright (C) 2010 Tobias Brunner + * 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 <glib.h> +#include <libosso.h> +#include <sys/stat.h> + +#include "maemo_service.h" + +#include <daemon.h> +#include <credentials/sets/mem_cred.h> +#include <processing/jobs/callback_job.h> + +#define OSSO_STATUS_NAME "status" +#define OSSO_STATUS_SERVICE "org.strongswan."OSSO_STATUS_NAME +#define OSSO_STATUS_OBJECT "/org/strongswan/"OSSO_STATUS_NAME +#define OSSO_STATUS_IFACE "org.strongswan."OSSO_STATUS_NAME + +#define OSSO_CHARON_NAME "charon" +#define OSSO_CHARON_SERVICE "org.strongswan."OSSO_CHARON_NAME +#define OSSO_CHARON_OBJECT "/org/strongswan/"OSSO_CHARON_NAME +#define OSSO_CHARON_IFACE "org.strongswan."OSSO_CHARON_NAME + +#define MAEMO_COMMON_CA_DIR "/etc/certs/common-ca" +#define MAEMO_USER_CA_DIR "/home/user/.maemosec-certs/wifi-ca" +/* there is also an smime-ca and an ssl-ca sub-directory and the same for + * ...-user, which store end user/server certificates */ + +typedef enum { + VPN_STATUS_DISCONNECTED, + VPN_STATUS_CONNECTING, + VPN_STATUS_CONNECTED, + VPN_STATUS_AUTH_FAILED, + VPN_STATUS_CONNECTION_FAILED, +} vpn_status_t; + +typedef struct private_maemo_service_t private_maemo_service_t; + +/** + * private data of maemo service + */ +struct private_maemo_service_t { + + /** + * public interface + */ + maemo_service_t public; + + /** + * credentials + */ + mem_cred_t *creds; + + /** + * Glib main loop for a thread, handles DBUS calls + */ + GMainLoop *loop; + + /** + * Context for OSSO + */ + osso_context_t *context; + + /** + * Current IKE_SA + */ + ike_sa_t *ike_sa; + + /** + * Status of the current connection + */ + vpn_status_t status; + + /** + * Name of the current connection + */ + gchar *current; + +}; + +static gint change_status(private_maemo_service_t *this, int status) +{ + osso_rpc_t retval; + gint res; + this->status = status; + res = osso_rpc_run (this->context, OSSO_STATUS_SERVICE, OSSO_STATUS_OBJECT, + OSSO_STATUS_IFACE, "StatusChanged", &retval, + DBUS_TYPE_INT32, status, + DBUS_TYPE_INVALID); + return res; +} + +METHOD(listener_t, ike_updown, bool, + private_maemo_service_t *this, ike_sa_t *ike_sa, bool up) +{ + /* this callback is only registered during initiation, so if the IKE_SA + * goes down we assume an authentication error */ + if (this->ike_sa == ike_sa && !up) + { + change_status(this, VPN_STATUS_AUTH_FAILED); + return FALSE; + } + return TRUE; +} + +METHOD(listener_t, child_state_change, bool, + private_maemo_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + child_sa_state_t state) +{ + /* this call back is only registered during initiation */ + if (this->ike_sa == ike_sa && state == CHILD_DESTROYING) + { + change_status(this, VPN_STATUS_CONNECTION_FAILED); + return FALSE; + } + return TRUE; +} + +METHOD(listener_t, child_updown, bool, + private_maemo_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + bool up) +{ + if (this->ike_sa == ike_sa) + { + if (up) + { + /* disable hooks registered to catch initiation failures */ + this->public.listener.ike_updown = NULL; + this->public.listener.child_state_change = NULL; + change_status(this, VPN_STATUS_CONNECTED); + } + else + { + change_status(this, VPN_STATUS_CONNECTION_FAILED); + return FALSE; + } + } + return TRUE; +} + +METHOD(listener_t, ike_rekey, bool, + private_maemo_service_t *this, ike_sa_t *old, ike_sa_t *new) +{ + if (this->ike_sa == old) + { + this->ike_sa = new; + } + return TRUE; +} + +/** + * load all CA certificates in the given directory + */ +static void load_ca_dir(private_maemo_service_t *this, char *dir) +{ + enumerator_t *enumerator; + char *rel, *abs; + struct stat st; + + enumerator = enumerator_create_directory(dir); + if (enumerator) + { + while (enumerator->enumerate(enumerator, &rel, &abs, &st)) + { + if (rel[0] != '.') + { + if (S_ISREG(st.st_mode)) + { + certificate_t *cert; + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, + CERT_X509, BUILD_FROM_FILE, abs, + BUILD_END); + if (!cert) + { + DBG1(DBG_CFG, "loading CA certificate '%s' failed", + abs); + continue; + } + DBG2(DBG_CFG, "loaded CA certificate '%Y'", + cert->get_subject(cert)); + this->creds->add_cert(this->creds, TRUE, cert); + } + } + } + enumerator->destroy(enumerator); + } +} + +static void disconnect(private_maemo_service_t *this) +{ + ike_sa_t *ike_sa; + u_int id; + + if (!this->current) + { + return; + } + + /* avoid status updates, as this is called from the Glib main loop */ + charon->bus->remove_listener(charon->bus, &this->public.listener); + + ike_sa = charon->ike_sa_manager->checkout_by_name(charon->ike_sa_manager, + this->current, FALSE); + if (ike_sa) + { + 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); + } + this->current = (g_free(this->current), NULL); + this->status = VPN_STATUS_DISCONNECTED; +} + +static gboolean initiate_connection(private_maemo_service_t *this, + GArray *arguments) +{ + gint i; + gchar *hostname = NULL, *cacert = NULL, *username = NULL, *password = NULL; + identification_t *gateway = NULL, *user = NULL; + ike_sa_t *ike_sa; + ike_cfg_t *ike_cfg; + peer_cfg_t *peer_cfg; + child_cfg_t *child_cfg; + traffic_selector_t *ts; + auth_cfg_t *auth; + certificate_t *cert; + lifetime_cfg_t lifetime = { + .time = { + .life = 10800, /* 3h */ + .rekey = 10200, /* 2h50min */ + .jitter = 300 /* 5min */ + } + }; + + if (this->status == VPN_STATUS_CONNECTED || + this->status == VPN_STATUS_CONNECTING) + { + DBG1(DBG_CFG, "currently connected to '%s', disconnecting first", + this->current); + disconnect (this); + } + + if (arguments->len != 5) + { + DBG1(DBG_CFG, "wrong number of arguments: %d", arguments->len); + return FALSE; + } + + for (i = 0; i < arguments->len; i++) + { + osso_rpc_t *arg = &g_array_index(arguments, osso_rpc_t, i); + if (arg->type != DBUS_TYPE_STRING) + { + DBG1(DBG_CFG, "invalid argument [%d]: %d", i, arg->type); + return FALSE; + } + switch (i) + { + case 0: /* name */ + this->current = (g_free(this->current), NULL); + this->current = g_strdup(arg->value.s); + break; + case 1: /* hostname */ + hostname = arg->value.s; + break; + case 2: /* CA certificate path */ + cacert = arg->value.s; + break; + case 3: /* username */ + username = arg->value.s; + break; + case 4: /* password */ + password = arg->value.s; + break; + } + } + + DBG1(DBG_CFG, "received initiate for connection '%s'", this->current); + + this->creds->clear(this->creds); + + if (cacert && !streq(cacert, "")) + { + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_FROM_FILE, cacert, BUILD_END); + if (cert) + { + this->creds->add_cert(this->creds, TRUE, cert); + } + else + { + DBG1(DBG_CFG, "failed to load CA certificate"); + } + /* if this is a server cert we could use the cert subject as id */ + } + else + { + load_ca_dir(this, MAEMO_COMMON_CA_DIR); + load_ca_dir(this, MAEMO_USER_CA_DIR); + } + + gateway = identification_create_from_string(hostname); + DBG1(DBG_CFG, "using CA certificate, gateway identitiy '%Y'", gateway); + + { + shared_key_t *shared_key; + chunk_t secret = chunk_create(password, strlen(password)); + user = identification_create_from_string(username); + shared_key = shared_key_create(SHARED_EAP, chunk_clone(secret)); + this->creds->add_shared(this->creds, shared_key, user->clone(user), + NULL); + } + + ike_cfg = ike_cfg_create(TRUE, FALSE, "0.0.0.0", IKEV2_UDP_PORT, + hostname, IKEV2_UDP_PORT); + ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); + + peer_cfg = peer_cfg_create(this->current, 2, ike_cfg, CERT_SEND_IF_ASKED, + UNIQUE_REPLACE, 1, /* keyingtries */ + 36000, 0, /* rekey 10h, reauth none */ + 600, 600, /* jitter, over 10min */ + TRUE, 0, /* mobike, DPD */ + host_create_from_string("0.0.0.0", 0) /* virt */, + NULL, FALSE, NULL, NULL); /* pool, mediation */ + + auth = auth_cfg_create(); + auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP); + auth->add(auth, AUTH_RULE_IDENTITY, user); + peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE); + auth = auth_cfg_create(); + auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); + auth->add(auth, AUTH_RULE_IDENTITY, gateway); + peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE); + + child_cfg = child_cfg_create(this->current, &lifetime, NULL /* updown */, + TRUE, MODE_TUNNEL, ACTION_NONE, ACTION_NONE, + FALSE, 0, 0, NULL, NULL); + child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP)); + ts = traffic_selector_create_dynamic(0, 0, 65535); + child_cfg->add_traffic_selector(child_cfg, TRUE, ts); + ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "0.0.0.0", + 0, "255.255.255.255", 65535); + child_cfg->add_traffic_selector(child_cfg, FALSE, ts); + peer_cfg->add_child_cfg(peer_cfg, child_cfg); + /* get an additional reference because initiate consumes one */ + child_cfg->get_ref(child_cfg); + + /* get us an IKE_SA */ + ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager, + peer_cfg); + if (!ike_sa->get_peer_cfg(ike_sa)) + { + ike_sa->set_peer_cfg(ike_sa, peer_cfg); + } + peer_cfg->destroy(peer_cfg); + + /* store the IKE_SA, so we can track its progress */ + this->ike_sa = ike_sa; + this->status = VPN_STATUS_CONNECTING; + this->public.listener.ike_updown = _ike_updown; + this->public.listener.child_state_change = _child_state_change; + charon->bus->add_listener(charon->bus, &this->public.listener); + + if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS) + { + DBG1(DBG_CFG, "failed to initiate tunnel"); + charon->bus->remove_listener(charon->bus, &this->public.listener); + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, + ike_sa); + this->status = VPN_STATUS_CONNECTION_FAILED; + return FALSE; + } + charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + return TRUE; +} + +/** + * Callback for libosso dbus wrapper + */ +static gint dbus_req_handler(const gchar *interface, const gchar *method, + GArray *arguments, private_maemo_service_t *this, + osso_rpc_t *retval) +{ + if (streq(method, "Start")) + { /* void start (void), dummy function to start charon as root */ + return OSSO_OK; + } + else if (streq(method, "Connect")) + { /* bool connect (name, host, cert, user, pass) */ + retval->value.b = initiate_connection(this, arguments); + retval->type = DBUS_TYPE_BOOLEAN; + } + else if (streq(method, "Disconnect")) + { /* void disconnect (void) */ + disconnect(this); + } + else + { + return OSSO_ERROR; + } + return OSSO_OK; +} + +/** + * Main loop to handle D-BUS messages. + */ +static job_requeue_t run(private_maemo_service_t *this) +{ + this->loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(this->loop); + return JOB_REQUEUE_NONE; +} + +METHOD(maemo_service_t, destroy, void, + private_maemo_service_t *this) +{ + if (this->loop) + { + if (g_main_loop_is_running(this->loop)) + { + g_main_loop_quit(this->loop); + } + g_main_loop_unref(this->loop); + } + if (this->context) + { + osso_rpc_unset_cb_f(this->context, + OSSO_CHARON_SERVICE, + OSSO_CHARON_OBJECT, + OSSO_CHARON_IFACE, + (osso_rpc_cb_f*)dbus_req_handler, + this); + osso_deinitialize(this->context); + } + charon->bus->remove_listener(charon->bus, &this->public.listener); + lib->credmgr->remove_set(lib->credmgr, &this->creds->set); + this->creds->destroy(this->creds); + this->current = (g_free(this->current), NULL); + free(this); +} + +/* + * See header + */ +maemo_service_t *maemo_service_create() +{ + osso_return_t result; + private_maemo_service_t *this; + + INIT(this, + .public = { + .listener = { + .ike_updown = _ike_updown, + .child_state_change = _child_state_change, + .child_updown = _child_updown, + .ike_rekey = _ike_rekey, + }, + .destroy = _destroy, + }, + .creds = mem_cred_create(), + ); + + lib->credmgr->add_set(lib->credmgr, &this->creds->set); + + this->context = osso_initialize(OSSO_CHARON_SERVICE, "0.0.1", TRUE, NULL); + if (!this->context) + { + DBG1(DBG_CFG, "failed to initialize OSSO context"); + destroy(this); + return NULL; + } + + result = osso_rpc_set_cb_f(this->context, + OSSO_CHARON_SERVICE, + OSSO_CHARON_OBJECT, + OSSO_CHARON_IFACE, + (osso_rpc_cb_f*)dbus_req_handler, + this); + if (result != OSSO_OK) + { + DBG1(DBG_CFG, "failed to set D-BUS callback (%d)", result); + destroy(this); + return NULL; + } + + this->loop = NULL; + if (!g_thread_supported()) + { + g_thread_init(NULL); + } + + lib->processor->queue_job(lib->processor, + (job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL)); + + return &this->public; +} + diff --git a/src/libcharon/plugins/maemo/maemo_service.h b/src/libcharon/plugins/maemo/maemo_service.h new file mode 100644 index 000000000..b0240cbaa --- /dev/null +++ b/src/libcharon/plugins/maemo/maemo_service.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2010 Tobias Brunner + * 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 maemo_service maemo_service + * @{ @ingroup maemo + */ + +#ifndef MAEMO_SERVICE_H_ +#define MAEMO_SERVICE_H_ + +#include <bus/listeners/listener.h> + +typedef struct maemo_service_t maemo_service_t; + +/** + * Maemo connection management. + */ +struct maemo_service_t { + + /** + * Implements listener_t. + */ + listener_t listener; + + /** + * Destroy a maemo_service_t. + */ + void (*destroy)(maemo_service_t *this); +}; + +/** + * Create an instance of maemo_service_t. + */ +maemo_service_t *maemo_service_create(); + +#endif /** MAEMO_SERVICE_H_ @}*/ diff --git a/src/libcharon/plugins/maemo/org.strongswan.charon.service b/src/libcharon/plugins/maemo/org.strongswan.charon.service new file mode 100644 index 000000000..7dd31ed60 --- /dev/null +++ b/src/libcharon/plugins/maemo/org.strongswan.charon.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.strongswan.charon +Exec=/usr/bin/run-standalone.sh /usr/libexec/ipsec/charon +User=root diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in index c26d325a9..6dcbc99dd 100644 --- a/src/libcharon/plugins/medcli/Makefile.in +++ b/src/libcharon/plugins/medcli/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -167,6 +168,8 @@ 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@ @@ -198,14 +201,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -220,24 +226,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -245,7 +258,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c index 6cbaf36f2..870d87c7e 100644 --- a/src/libcharon/plugins/medcli/medcli_config.c +++ b/src/libcharon/plugins/medcli/medcli_config.c @@ -126,11 +126,11 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam med_cfg = peer_cfg_create( "mediation", 2, ike_cfg, 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(); @@ -163,10 +163,10 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam 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 */ + 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 */ FALSE, med_cfg, /* mediation, med by */ identification_create_from_encoding(ID_KEY_ID, other)); @@ -243,11 +243,11 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) this->current = 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 */ - FALSE, 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 */ + FALSE, NULL, NULL); /* mediation, med by, peer id */ auth = auth_cfg_create(); auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); @@ -364,7 +364,7 @@ static void schedule_autoinit(private_medcli_config_t *this) if (peer_cfg) { /* schedule asynchronous initiation job */ - charon->processor->queue_job(charon->processor, + lib->processor->queue_job(lib->processor, (job_t*)callback_job_create( (callback_job_cb_t)initiate_config, peer_cfg, (void*)peer_cfg->destroy, NULL)); diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in index 4dc9c00d0..f6db7d834 100644 --- a/src/libcharon/plugins/medsrv/Makefile.in +++ b/src/libcharon/plugins/medsrv/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -167,6 +168,8 @@ 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@ @@ -198,14 +201,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -220,24 +226,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -245,7 +258,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/nm/Makefile.in b/src/libcharon/plugins/nm/Makefile.in index 1b3e4c5a6..2f5c20971 100644 --- a/src/libcharon/plugins/nm/Makefile.in +++ b/src/libcharon/plugins/nm/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -166,6 +167,8 @@ 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@ @@ -197,14 +200,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -219,24 +225,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -244,7 +257,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/nm/nm_creds.c b/src/libcharon/plugins/nm/nm_creds.c index 193838e6b..638787019 100644 --- a/src/libcharon/plugins/nm/nm_creds.c +++ b/src/libcharon/plugins/nm/nm_creds.c @@ -51,6 +51,16 @@ struct private_nm_creds_t { char *pass; /** + * Private key decryption password / smartcard pin + */ + char *keypass; + + /** + * private key ID of smartcard key + */ + chunk_t keyid; + + /** * users certificate */ certificate_t *usercert; @@ -239,8 +249,14 @@ static bool shared_enumerate(shared_enumerator_t *this, shared_key_t **key, return FALSE; } *key = this->key; - *me = ID_MATCH_PERFECT; - *other = ID_MATCH_ANY; + if (me) + { + *me = ID_MATCH_PERFECT; + } + if (other) + { + *other = ID_MATCH_ANY; + } this->done = TRUE; return TRUE; } @@ -262,18 +278,39 @@ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this, identification_t *other) { shared_enumerator_t *enumerator; + chunk_t key; - if (!this->pass || !this->user) + switch (type) { - return NULL; - } - if (type != SHARED_EAP && type != SHARED_IKE) - { - return NULL; - } - if (me && !me->equals(me, this->user)) - { - return NULL; + case SHARED_EAP: + case SHARED_IKE: + if (!this->pass || !this->user) + { + return NULL; + } + if (me && !me->equals(me, this->user)) + { + return NULL; + } + key = chunk_create(this->pass, strlen(this->pass)); + break; + case SHARED_PRIVATE_KEY_PASS: + if (!this->keypass) + { + return NULL; + } + key = chunk_create(this->keypass, strlen(this->keypass)); + break; + case SHARED_PIN: + if (!this->keypass || !me || + !chunk_equals(me->get_encoding(me), this->keyid)) + { + return NULL; + } + key = chunk_create(this->keypass, strlen(this->keypass)); + break; + default: + return NULL; } enumerator = malloc_thing(shared_enumerator_t); @@ -282,9 +319,7 @@ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this, enumerator->this = this; enumerator->done = FALSE; this->lock->read_lock(this->lock); - enumerator->key = shared_key_create(type, - chunk_clone(chunk_create(this->pass, - strlen(this->pass)))); + enumerator->key = shared_key_create(type, chunk_clone(key)); return &enumerator->public; } @@ -370,6 +405,30 @@ static void set_username_password(private_nm_creds_t *this, identification_t *id } /** + * Implementation of nm_creds_t.set_key_password + */ +static void set_key_password(private_nm_creds_t *this, char *password) +{ + this->lock->write_lock(this->lock); + free(this->keypass); + this->keypass = password ? strdup(password) : NULL; + 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) +{ + this->lock->write_lock(this->lock); + free(this->keypass); + free(this->keyid.ptr); + this->keypass = pin ? strdup(pin) : NULL; + this->keyid = chunk_clone(keyid); + 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, @@ -396,12 +455,16 @@ static void clear(private_nm_creds_t *this) } DESTROY_IF(this->user); free(this->pass); + free(this->keypass); + free(this->keyid.ptr); DESTROY_IF(this->usercert); DESTROY_IF(this->key); this->key = NULL; this->usercert = NULL; this->pass = NULL; this->user = NULL; + this->keypass = NULL; + this->keyid = chunk_empty; } /** @@ -430,6 +493,8 @@ nm_creds_t *nm_creds_create() 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; @@ -441,6 +506,8 @@ nm_creds_t *nm_creds_create() this->pass = NULL; this->usercert = NULL; this->key = NULL; + this->keypass = NULL; + this->keyid = chunk_empty; return &this->public; } diff --git a/src/libcharon/plugins/nm/nm_creds.h b/src/libcharon/plugins/nm/nm_creds.h index b55cff31e..91f645c7e 100644 --- a/src/libcharon/plugins/nm/nm_creds.h +++ b/src/libcharon/plugins/nm/nm_creds.h @@ -58,6 +58,22 @@ struct nm_creds_t { */ void (*set_username_password)(nm_creds_t *this, identification_t *id, char *password); + + /** + * Set the passphrase to use for private key decryption. + * + * @param password password to use + */ + void (*set_key_password)(nm_creds_t *this, char *password); + + /** + * Set the PIN to unlock a smartcard. + * + * @param keyid keyid of the smartcard key + * @param pin PIN + */ + void (*set_pin)(nm_creds_t *this, chunk_t keyid, char *pin); + /** * Set the certificate and private key to use for client authentication. * @@ -66,6 +82,7 @@ struct nm_creds_t { */ void (*set_cert_and_key)(nm_creds_t *this, certificate_t *cert, private_key_t *key); + /** * Clear the stored credentials. */ diff --git a/src/libcharon/plugins/nm/nm_plugin.c b/src/libcharon/plugins/nm/nm_plugin.c index 250e6f7f9..fd0580bd6 100644 --- a/src/libcharon/plugins/nm/nm_plugin.c +++ b/src/libcharon/plugins/nm/nm_plugin.c @@ -122,7 +122,7 @@ plugin_t *nm_plugin_create() /* bypass file permissions to read from users ssh-agent */ charon->keep_cap(charon, CAP_DAC_OVERRIDE); - charon->processor->queue_job(charon->processor, + lib->processor->queue_job(lib->processor, (job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL)); return &this->public.plugin; diff --git a/src/libcharon/plugins/nm/nm_service.c b/src/libcharon/plugins/nm/nm_service.c index 07318bbbf..72c5bbbb5 100644 --- a/src/libcharon/plugins/nm/nm_service.c +++ b/src/libcharon/plugins/nm/nm_service.c @@ -204,6 +204,59 @@ static bool ike_rekey(listener_t *listener, ike_sa_t *old, ike_sa_t *new) } /** + * Find a certificate for which we have a private key on a smartcard + */ +static identification_t *find_smartcard_key(NMStrongswanPluginPrivate *priv, + char *pin) +{ + enumerator_t *enumerator, *sans; + identification_t *id = NULL; + certificate_t *cert; + x509_t *x509; + private_key_t *key; + chunk_t keyid; + + enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr, + CERT_X509, KEY_ANY, NULL, FALSE); + while (enumerator->enumerate(enumerator, &cert)) + { + x509 = (x509_t*)cert; + + /* there might be a lot of certificates, filter them by usage */ + if ((x509->get_flags(x509) & X509_CLIENT_AUTH) && + !(x509->get_flags(x509) & X509_CA)) + { + keyid = x509->get_subjectKeyIdentifier(x509); + if (keyid.ptr) + { + /* try to find a private key by the certificate keyid */ + priv->creds->set_pin(priv->creds, keyid, pin); + key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, + KEY_ANY, BUILD_PKCS11_KEYID, keyid, BUILD_END); + if (key) + { + /* prefer a more convenient subjectAltName */ + sans = x509->create_subjectAltName_enumerator(x509); + if (!sans->enumerate(sans, &id)) + { + id = cert->get_subject(cert); + } + id = id->clone(id); + sans->destroy(sans); + + DBG1(DBG_CFG, "using smartcard certificate '%Y'", id); + priv->creds->set_cert_and_key(priv->creds, + cert->get_ref(cert), key); + break; + } + } + } + } + enumerator->destroy(enumerator); + return id; +} + +/** * Connect function called from NM via DBUS */ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, @@ -224,7 +277,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, auth_class_t auth_class = AUTH_CLASS_EAP; certificate_t *cert = NULL; x509_t *x509; - bool agent = FALSE; + bool agent = FALSE, smartcard = FALSE; lifetime_cfg_t lifetime = { .time = { .life = 10800 /* 3h */, @@ -279,6 +332,11 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, { auth_class = AUTH_CLASS_PUBKEY; } + else if (streq(str, "smartcard")) + { + auth_class = AUTH_CLASS_PUBKEY; + smartcard = TRUE; + } } /** @@ -338,9 +396,26 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, if (auth_class == AUTH_CLASS_PUBKEY) { + if (smartcard) + { + char *pin; + + pin = (char*)nm_setting_vpn_get_secret(vpn, "password"); + if (pin) + { + user = find_smartcard_key(priv, pin); + } + if (!user) + { + g_set_error(err, NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "no usable smartcard certificate found."); + gateway->destroy(gateway); + return FALSE; + } + } /* ... or certificate/private key authenitcation */ - str = nm_setting_vpn_get_data_item(vpn, "usercert"); - if (str) + else if ((str = nm_setting_vpn_get_data_item(vpn, "usercert"))) { public_key_t *public; private_key_t *private = NULL; @@ -380,16 +455,15 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, str = nm_setting_vpn_get_data_item(vpn, "userkey"); if (!agent && str) { - chunk_t secret; + char *secret; - secret.ptr = (char*)nm_setting_vpn_get_secret(vpn, "password"); - if (secret.ptr) + secret = (char*)nm_setting_vpn_get_secret(vpn, "password"); + if (secret) { - secret.len = strlen(secret.ptr); + priv->creds->set_key_password(priv->creds, secret); } private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, - KEY_RSA, BUILD_FROM_FILE, str, - BUILD_PASSPHRASE, secret, BUILD_END); + KEY_RSA, BUILD_FROM_FILE, str, BUILD_END); if (!private) { g_set_error(err, NM_VPN_PLUGIN_ERROR, @@ -524,17 +598,10 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection, if (path) { private_key_t *key; - chunk_t secret; - secret.ptr = (char*)nm_setting_vpn_get_secret(settings, "password"); - if (secret.ptr) - { - secret.len = strlen(secret.ptr); - } /* try to load/decrypt the private key */ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, - KEY_RSA, BUILD_FROM_FILE, path, - BUILD_PASSPHRASE, secret, BUILD_END); + KEY_RSA, BUILD_FROM_FILE, path, BUILD_END); if (key) { key->destroy(key); @@ -542,6 +609,13 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection, } } } + else if streq(method, "smartcard") + { + if (nm_setting_vpn_get_secret(settings, "password")) + { + return FALSE; + } + } } *setting_name = NM_SETTING_VPN_SETTING_NAME; return TRUE; diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in index 35fb8367f..f24e2d1e7 100644 --- a/src/libcharon/plugins/smp/Makefile.in +++ b/src/libcharon/plugins/smp/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -165,6 +166,8 @@ 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@ @@ -196,14 +199,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -243,7 +256,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/smp/smp.c b/src/libcharon/plugins/smp/smp.c index 64820eb45..60937f23d 100644 --- a/src/libcharon/plugins/smp/smp.c +++ b/src/libcharon/plugins/smp/smp.c @@ -702,7 +702,7 @@ static job_requeue_t dispatch(private_smp_t *this) fdp = malloc_thing(int); *fdp = fd; job = callback_job_create((callback_job_cb_t)process, fdp, free, this->job); - charon->processor->queue_job(charon->processor, (job_t*)job); + lib->processor->queue_job(lib->processor, (job_t*)job); return JOB_REQUEUE_DIRECT; } @@ -761,7 +761,7 @@ plugin_t *smp_plugin_create() } this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + 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 df63d862e..bd85386b2 100644 --- a/src/libcharon/plugins/socket_default/Makefile.in +++ b/src/libcharon/plugins/socket_default/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/socket_default/socket_default_plugin.c b/src/libcharon/plugins/socket_default/socket_default_plugin.c index 45390ddae..b5dea68b6 100644 --- a/src/libcharon/plugins/socket_default/socket_default_plugin.c +++ b/src/libcharon/plugins/socket_default/socket_default_plugin.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2010 Tobias Brunner + * Hochschule fuer Technik Rapperswil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -31,17 +33,13 @@ struct private_socket_default_plugin_t { */ socket_default_plugin_t public; - /** - * Socket instance. - */ - socket_default_socket_t *socket; }; METHOD(plugin_t, destroy, void, private_socket_default_plugin_t *this) { - charon->socket->remove_socket(charon->socket, &this->socket->socket); - this->socket->destroy(this->socket); + charon->socket->remove_socket(charon->socket, + (socket_constructor_t)socket_default_socket_create); free(this); } @@ -53,16 +51,15 @@ plugin_t *socket_default_plugin_create() private_socket_default_plugin_t *this; INIT(this, - .public.plugin.destroy = _destroy, - .socket = socket_default_socket_create(), + .public = { + .plugin = { + .destroy = _destroy, + }, + }, ); - if (!this->socket) - { - free(this); - return NULL; - } - charon->socket->add_socket(charon->socket, &this->socket->socket); + 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 bc998182e..e95646643 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 Tobias Brunner + * Copyright (C) 2006-2010 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -42,11 +42,12 @@ #include <sys/sysctl.h> #endif +#include <hydra.h> #include <daemon.h> #include <threading/thread.h> /* Maximum size of a packet */ -#define MAX_PACKET 5000 +#define MAX_PACKET 10000 /* length of non-esp marker */ #define MARKER_LEN sizeof(u_int32_t) @@ -116,12 +117,17 @@ struct private_socket_default_socket_t { * IPv6 socket for NATT (4500) */ int ipv6_natt; + + /** + * Maximum packet size to receive + */ + int max_packet; }; METHOD(socket_t, receiver, status_t, private_socket_default_socket_t *this, packet_t **packet) { - char buffer[MAX_PACKET]; + char buffer[this->max_packet]; chunk_t data; packet_t *pkt; host_t *source = NULL, *dest = NULL; @@ -195,7 +201,7 @@ METHOD(socket_t, receiver, status_t, msg.msg_name = &src; msg.msg_namelen = sizeof(src); iov.iov_base = buffer; - iov.iov_len = sizeof(buffer); + iov.iov_len = this->max_packet; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = ancillary; @@ -207,6 +213,11 @@ METHOD(socket_t, receiver, status_t, DBG1(DBG_NET, "error reading socket: %s", strerror(errno)); return FAILED; } + if (msg.msg_flags & MSG_TRUNC) + { + DBG1(DBG_NET, "receive buffer too small, packet discarded"); + return FAILED; + } DBG3(DBG_NET, "received packet %b", buffer, bytes_read); if (bytes_read < MARKER_LEN) @@ -351,12 +362,6 @@ METHOD(socket_t, sender, status_t, if (data.len != 1 || data.ptr[0] != 0xFF) { /* add non esp marker to packet */ - if (data.len > MAX_PACKET - MARKER_LEN) - { - DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)", - data.len); - return FAILED; - } marked = chunk_alloc(data.len + MARKER_LEN); memset(marked.ptr, 0, MARKER_LEN); memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len); @@ -521,8 +526,8 @@ static int open_socket(private_socket_default_socket_t *this, } } - if (!charon->kernel_interface->bypass_socket(charon->kernel_interface, - skt, family)) + if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, + skt, family)) { DBG1(DBG_NET, "installing IKE bypass policy failed"); } @@ -541,7 +546,7 @@ static int open_socket(private_socket_default_socket_t *this, return skt; } -METHOD(socket_default_socket_t, destroy, void, +METHOD(socket_t, destroy, void, private_socket_default_socket_t *this) { if (this->ipv4) @@ -575,9 +580,11 @@ socket_default_socket_t *socket_default_socket_create() .socket = { .send = _sender, .receive = _receiver, + .destroy = _destroy, }, - .destroy = _destroy, }, + .max_packet = lib->settings->get_int(lib->settings, + "charon.max_packet", MAX_PACKET), ); #ifdef __APPLE__ diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.h b/src/libcharon/plugins/socket_default/socket_default_socket.h index 755016662..89aa6f435 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.h +++ b/src/libcharon/plugins/socket_default/socket_default_socket.h @@ -35,10 +35,6 @@ struct socket_default_socket_t { */ socket_t socket; - /** - * Destroy a socket_default_socket_t. - */ - void (*destroy)(socket_default_socket_t *this); }; /** diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in index 8a3a15188..8e0790671 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.in +++ b/src/libcharon/plugins/socket_dynamic/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c index 3410fc7a4..a6ff14efd 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2010 Tobias Brunner + * Hochschule fuer Technik Rapperswil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -31,17 +33,13 @@ struct private_socket_dynamic_plugin_t { */ socket_dynamic_plugin_t public; - /** - * Socket instance. - */ - socket_dynamic_socket_t *socket; }; METHOD(plugin_t, destroy, void, private_socket_dynamic_plugin_t *this) { - charon->socket->remove_socket(charon->socket, &this->socket->socket); - this->socket->destroy(this->socket); + charon->socket->remove_socket(charon->socket, + (socket_constructor_t)socket_dynamic_socket_create); free(this); } @@ -53,16 +51,15 @@ plugin_t *socket_dynamic_plugin_create() private_socket_dynamic_plugin_t *this; INIT(this, - .public.plugin.destroy = _destroy, - .socket = socket_dynamic_socket_create(), + .public = { + .plugin = { + .destroy = _destroy, + }, + }, ); - if (!this->socket) - { - free(this); - return NULL; - } - charon->socket->add_socket(charon->socket, &this->socket->socket); + 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 a7db59ce5..74dba82cc 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 Tobias Brunner + * Copyright (C) 2006-2010 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -36,13 +36,14 @@ #include <netinet/udp.h> #include <net/if.h> +#include <hydra.h> #include <daemon.h> #include <threading/thread.h> #include <threading/rwlock.h> #include <utils/hashtable.h> /* Maximum size of a packet */ -#define MAX_PACKET 5000 +#define MAX_PACKET 10000 /* length of non-esp marker */ #define MARKER_LEN sizeof(u_int32_t) @@ -100,6 +101,11 @@ struct private_socket_dynamic_socket_t { * Notification pipe to signal receiver */ int notify[2]; + + /** + * Maximum packet size to receive + */ + int max_packet; }; /** @@ -197,7 +203,7 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this, { host_t *source = NULL, *dest = NULL; ssize_t len; - char buffer[MAX_PACKET]; + char buffer[this->max_packet]; chunk_t data; packet_t *packet; struct msghdr msg; @@ -212,7 +218,7 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this, msg.msg_name = &src; msg.msg_namelen = sizeof(src); iov.iov_base = buffer; - iov.iov_len = sizeof(buffer); + iov.iov_len = this->max_packet; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = ancillary; @@ -224,6 +230,11 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this, DBG1(DBG_NET, "error reading socket: %s", strerror(errno)); return NULL; } + if (msg.msg_flags & MSG_TRUNC) + { + DBG1(DBG_NET, "receive buffer too small, packet discarded"); + return NULL; + } DBG3(DBG_NET, "received packet %b", buffer, len); if (len < MARKER_LEN) @@ -412,8 +423,8 @@ static int open_socket(private_socket_dynamic_socket_t *this, return 0; } - if (!charon->kernel_interface->bypass_socket(charon->kernel_interface, - fd, family)) + if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, + fd, family)) { DBG1(DBG_NET, "installing IKE bypass policy failed"); } @@ -495,12 +506,6 @@ METHOD(socket_t, sender, status_t, !(data.len == 1 && data.ptr[0] == 0xFF)) { /* add non esp marker to packet */ - if (data.len > MAX_PACKET - MARKER_LEN) - { - DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)", - data.len); - return FAILED; - } marked = chunk_alloc(data.len + MARKER_LEN); memset(marked.ptr, 0, MARKER_LEN); memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len); @@ -567,7 +572,7 @@ METHOD(socket_t, sender, status_t, return SUCCESS; } -METHOD(socket_dynamic_socket_t, destroy, void, +METHOD(socket_t, destroy, void, private_socket_dynamic_socket_t *this) { enumerator_t *enumerator; @@ -600,10 +605,12 @@ socket_dynamic_socket_t *socket_dynamic_socket_create() .socket = { .send = _sender, .receive = _receiver, + .destroy = _destroy, }, - .destroy = _destroy, }, .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .max_packet = lib->settings->get_int(lib->settings, + "charon.max_packet", MAX_PACKET), ); if (pipe(this->notify) != 0) diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h index 72551e545..8c93f53d6 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h @@ -35,10 +35,6 @@ struct socket_dynamic_socket_t { */ socket_t socket; - /** - * Destroy a socket_dynamic_socket_t. - */ - void (*destroy)(socket_dynamic_socket_t *this); }; /** diff --git a/src/libcharon/plugins/socket_raw/Makefile.in b/src/libcharon/plugins/socket_raw/Makefile.in index 32bd9e0a1..5f4cba131 100644 --- a/src/libcharon/plugins/socket_raw/Makefile.in +++ b/src/libcharon/plugins/socket_raw/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c index 5b011abcf..17a3a8db7 100644 --- a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c +++ b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2010 Tobias Brunner + * Hochschule fuer Technik Rapperswil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -31,17 +33,13 @@ struct private_socket_raw_plugin_t { */ socket_raw_plugin_t public; - /** - * Raw socket instance. - */ - socket_raw_socket_t *socket; }; METHOD(plugin_t, destroy, void, private_socket_raw_plugin_t *this) { - charon->socket->remove_socket(charon->socket, &this->socket->socket); - this->socket->destroy(this->socket); + charon->socket->remove_socket(charon->socket, + (socket_constructor_t)socket_raw_socket_create); free(this); } @@ -53,16 +51,15 @@ plugin_t *socket_raw_plugin_create() private_socket_raw_plugin_t *this; INIT(this, - .public.plugin.destroy = _destroy, - .socket = socket_raw_socket_create(), + .public = { + .plugin = { + .destroy = _destroy, + }, + }, ); - if (!this->socket) - { - free(this); - return NULL; - } - charon->socket->add_socket(charon->socket, &this->socket->socket); + 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 166870421..f6e87a86f 100644 --- a/src/libcharon/plugins/socket_raw/socket_raw_socket.c +++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.c @@ -1,6 +1,7 @@ /* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger + * Copyright (C) 2006-2010 Tobias Brunner * Copyright (C) 2005-2010 Martin Willi + * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -36,11 +37,12 @@ #include <linux/filter.h> #include <net/if.h> +#include <hydra.h> #include <daemon.h> #include <threading/thread.h> /* Maximum size of a packet */ -#define MAX_PACKET 5000 +#define MAX_PACKET 10000 /* constants for packet handling */ #define IP_LEN sizeof(struct iphdr) @@ -119,12 +121,17 @@ struct private_socket_raw_socket_t { * send socket on nat-t port for IPv6 */ int send6_natt; + + /** + * Maximum packet size to receive + */ + int max_packet; }; METHOD(socket_t, receiver, status_t, private_socket_raw_socket_t *this, packet_t **packet) { - char buffer[MAX_PACKET]; + char buffer[this->max_packet]; chunk_t data; packet_t *pkt; struct udphdr *udp; @@ -161,12 +168,17 @@ METHOD(socket_t, receiver, status_t, struct iphdr *ip; struct sockaddr_in src, dst; - bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0); + bytes_read = recv(this->recv4, buffer, this->max_packet, 0); if (bytes_read < 0) { DBG1(DBG_NET, "error reading from IPv4 socket: %s", strerror(errno)); return FAILED; } + if (bytes_read == this->max_packet) + { + DBG1(DBG_NET, "receive buffer too small, packet discarded"); + return FAILED; + } DBG3(DBG_NET, "received IPv4 packet %b", buffer, bytes_read); /* read source/dest from raw IP/UDP header */ @@ -216,7 +228,7 @@ METHOD(socket_t, receiver, status_t, msg.msg_name = &src; msg.msg_namelen = sizeof(src); iov.iov_base = buffer; - iov.iov_len = sizeof(buffer); + iov.iov_len = this->max_packet; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = ancillary; @@ -343,12 +355,6 @@ METHOD(socket_t, sender, status_t, if (data.len != 1 || data.ptr[0] != 0xFF) { /* add non esp marker to packet */ - if (data.len > MAX_PACKET - MARKER_LEN) - { - DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)", - data.len); - return FAILED; - } marked = chunk_alloc(data.len + MARKER_LEN); memset(marked.ptr, 0, MARKER_LEN); memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len); @@ -492,8 +498,8 @@ static int open_send_socket(private_socket_raw_socket_t *this, } } - if (!charon->kernel_interface->bypass_socket(charon->kernel_interface, - skt, family)) + if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, + skt, family)) { DBG1(DBG_NET, "installing bypass policy on send socket failed"); } @@ -598,8 +604,8 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family) return 0; } - if (!charon->kernel_interface->bypass_socket(charon->kernel_interface, - skt, family)) + if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, + skt, family)) { DBG1(DBG_NET, "installing bypass policy on receive socket failed"); } @@ -607,7 +613,7 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family) return skt; } -METHOD(socket_raw_socket_t, destroy, void, +METHOD(socket_t, destroy, void, private_socket_raw_socket_t *this) { if (this->recv4) @@ -649,9 +655,11 @@ socket_raw_socket_t *socket_raw_socket_create() .socket = { .send = _sender, .receive = _receiver, + .destroy = _destroy, }, - .destroy = _destroy, }, + .max_packet = lib->settings->get_int(lib->settings, + "charon.max_packet", MAX_PACKET), ); this->recv4 = open_recv_socket(this, AF_INET); diff --git a/src/libcharon/plugins/socket_raw/socket_raw_socket.h b/src/libcharon/plugins/socket_raw/socket_raw_socket.h index 94cf666e8..23ff304a8 100644 --- a/src/libcharon/plugins/socket_raw/socket_raw_socket.h +++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.h @@ -41,10 +41,6 @@ struct socket_raw_socket_t { */ socket_t socket; - /** - * Destroy a socket_raw_socket_t. - */ - void (*destroy)(socket_raw_socket_t *this); }; /** diff --git a/src/libcharon/plugins/sql/Makefile.am b/src/libcharon/plugins/sql/Makefile.am index 68b7e8cb2..37b87117c 100644 --- a/src/libcharon/plugins/sql/Makefile.am +++ b/src/libcharon/plugins/sql/Makefile.am @@ -2,9 +2,6 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon -AM_CFLAGS = -rdynamic \ - -DPLUGINS=\""${libstrongswan_plugins}\"" - if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-sql.la else diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in index e32dc7b57..7c4521785 100644 --- a/src/libcharon/plugins/sql/Makefile.in +++ b/src/libcharon/plugins/sql/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -165,6 +166,8 @@ 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@ @@ -196,14 +199,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -243,7 +256,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ @@ -258,9 +274,6 @@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon -AM_CFLAGS = -rdynamic \ - -DPLUGINS=\""${libstrongswan_plugins}\"" - @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-sql.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-sql.la libstrongswan_sql_la_SOURCES = \ diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in index e094200ca..e6e98838b 100644 --- a/src/libcharon/plugins/stroke/Makefile.in +++ b/src/libcharon/plugins/stroke/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -168,6 +169,8 @@ 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@ @@ -199,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 617069432..165212a5e 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -15,6 +15,7 @@ #include "stroke_config.h" +#include <hydra.h> #include <daemon.h> #include <threading/mutex.h> #include <utils/lexparser.h> @@ -199,8 +200,8 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg host = host_create_from_dns(msg->add_conn.other.address, 0, 0); if (host) { - interface = charon->kernel_interface->get_interface( - charon->kernel_interface, host); + interface = hydra->kernel_interface->get_interface( + hydra->kernel_interface, host); host->destroy(host); if (interface) { @@ -215,8 +216,8 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg host = host_create_from_dns(msg->add_conn.me.address, 0, 0); if (host) { - interface = charon->kernel_interface->get_interface( - charon->kernel_interface, host); + interface = hydra->kernel_interface->get_interface( + hydra->kernel_interface, host); host->destroy(host); if (!interface) { @@ -362,7 +363,16 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, } } else - { /* no second authentication round, fine */ + { /* no second authentication round, fine. But load certificates + * for other purposes (EAP-TLS) */ + if (cert) + { + certificate = this->cred->load_peer(this->cred, cert); + if (certificate) + { + certificate->destroy(certificate); + } + } return NULL; } } @@ -502,6 +512,11 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, } cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, identity); } + if (msg->add_conn.aaa_identity) + { + cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, + identification_create_from_string(msg->add_conn.aaa_identity)); + } } else { diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c index f64421551..e0398ba78 100644 --- a/src/libcharon/plugins/stroke/stroke_control.c +++ b/src/libcharon/plugins/stroke/stroke_control.c @@ -354,7 +354,7 @@ static void terminate_srcip(private_stroke_control_t *this, } /* schedule delete asynchronously */ - charon->processor->queue_job(charon->processor, (job_t*) + lib->processor->queue_job(lib->processor, (job_t*) delete_ike_sa_job_create(ike_sa->get_id(ike_sa), TRUE)); } enumerator->destroy(enumerator); diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c index 2816b9bb2..91e71f1f4 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.c +++ b/src/libcharon/plugins/stroke/stroke_cred.c @@ -14,10 +14,15 @@ * for more details. */ +#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> #include "stroke_cred.h" #include "stroke_shared_key.h" @@ -25,6 +30,8 @@ #include <credentials/certificates/x509.h> #include <credentials/certificates/crl.h> #include <credentials/certificates/ac.h> +#include <credentials/sets/mem_cred.h> +#include <credentials/sets/callback_cred.h> #include <utils/linked_list.h> #include <utils/lexparser.h> #include <threading/rwlock.h> @@ -88,7 +95,8 @@ struct private_stroke_cred_t { typedef struct { private_stroke_cred_t *this; identification_t *id; - certificate_type_t type; + certificate_type_t cert; + key_type_t key; } id_data_t; /** @@ -109,15 +117,18 @@ static bool private_filter(id_data_t *data, private_key_t *key; key = *in; - if (data->id == NULL) + if (data->key == KEY_ANY || data->key == key->get_type(key)) { - *out = key; - return TRUE; - } - if (key->has_fingerprint(key, data->id->get_encoding(data->id))) - { - *out = key; - return TRUE; + if (data->id == NULL) + { + *out = key; + return TRUE; + } + if (key->has_fingerprint(key, data->id->get_encoding(data->id))) + { + *out = key; + return TRUE; + } } return FALSE; } @@ -133,6 +144,7 @@ static enumerator_t* create_private_enumerator(private_stroke_cred_t *this, data = malloc_thing(id_data_t); data->this = this; data->id = id; + data->key = type; this->lock->read_lock(this->lock); return enumerator_create_filter(this->private->create_enumerator(this->private), @@ -148,7 +160,7 @@ static bool certs_filter(id_data_t *data, certificate_t **in, certificate_t **ou public_key_t *public; certificate_t *cert = *in; - if (data->type != CERT_ANY && data->type != cert->get_type(cert)) + if (data->cert != CERT_ANY && data->cert != cert->get_type(cert)) { return FALSE; } @@ -161,11 +173,14 @@ static bool certs_filter(id_data_t *data, certificate_t **in, certificate_t **ou public = cert->get_public_key(cert); if (public) { - if (public->has_fingerprint(public, data->id->get_encoding(data->id))) + if (data->key == KEY_ANY || data->key != public->get_type(public)) { - public->destroy(public); - *out = *in; - return TRUE; + if (public->has_fingerprint(public, data->id->get_encoding(data->id))) + { + public->destroy(public); + *out = *in; + return TRUE; + } } public->destroy(public); } @@ -188,7 +203,8 @@ static enumerator_t* create_cert_enumerator(private_stroke_cred_t *this, data = malloc_thing(id_data_t); data->this = this; data->id = id; - data->type = cert; + data->cert = cert; + data->key = key; this->lock->read_lock(this->lock); return enumerator_create_filter(this->certs->create_enumerator(this->certs), @@ -667,47 +683,443 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line) } /** - * Data to pass to passphrase_cb + * Data for passphrase callback */ typedef struct { /** socket we use for prompting */ FILE *prompt; /** private key file */ - char *file; - /** buffer for passphrase */ - char buf[256]; + char *path; + /** number of tries */ + int try; } passphrase_cb_data_t; /** - * Passphrase callback to read from whack fd + * Callback function to receive Passphrases */ -chunk_t passphrase_cb(passphrase_cb_data_t *data, int try) +static shared_key_t* passphrase_cb(passphrase_cb_data_t *data, + shared_key_type_t type, + identification_t *me, identification_t *other, + id_match_t *match_me, id_match_t *match_other) { - chunk_t secret = chunk_empty;; + chunk_t secret; + char buf[256]; - if (try > 5) + if (type != SHARED_ANY && type != SHARED_PRIVATE_KEY_PASS) { - fprintf(data->prompt, "invalid passphrase, too many trials\n"); - return chunk_empty; + return NULL; } - if (try == 1) + + if (data->try > 1) { - fprintf(data->prompt, "Private key '%s' is encrypted\n", data->file); + if (data->try > 5) + { + fprintf(data->prompt, "PIN invalid, giving up.\n"); + return NULL; + } + fprintf(data->prompt, "PIN invalid!\n"); } - else + data->try++; + fprintf(data->prompt, "Private key '%s' is encrypted.\n", data->path); + fprintf(data->prompt, "Passphrase:\n"); + if (fgets(buf, sizeof(buf), data->prompt)) { - fprintf(data->prompt, "invalid passphrase\n"); + secret = chunk_create(buf, strlen(buf)); + if (secret.len > 1) + { /* trim appended \n */ + secret.len--; + if (match_me) + { + *match_me = ID_MATCH_PERFECT; + } + if (match_other) + { + *match_other = ID_MATCH_NONE; + } + return shared_key_create(SHARED_PRIVATE_KEY_PASS, chunk_clone(secret)); + } } - fprintf(data->prompt, "Passphrase:\n"); - if (fgets(data->buf, sizeof(data->buf), data->prompt)) + return NULL; +} + +/** + * Data for PIN callback + */ +typedef struct { + /** socket we use for prompting */ + FILE *prompt; + /** card label */ + char *card; + /** card keyid */ + chunk_t keyid; + /** number of tries */ + int try; +} pin_cb_data_t; + +/** + * Callback function to receive PINs + */ +static shared_key_t* pin_cb(pin_cb_data_t *data, shared_key_type_t type, + identification_t *me, identification_t *other, + id_match_t *match_me, id_match_t *match_other) +{ + chunk_t secret; + char buf[256]; + + if (type != SHARED_ANY && type != SHARED_PIN) + { + return NULL; + } + + if (!me || !chunk_equals(me->get_encoding(me), data->keyid)) + { + return NULL; + } + + if (data->try > 1) + { + fprintf(data->prompt, "PIN invalid, aborting.\n"); + return NULL; + } + data->try++; + fprintf(data->prompt, "Login to '%s' required\n", data->card); + fprintf(data->prompt, "PIN:\n"); + if (fgets(buf, sizeof(buf), data->prompt)) { - secret = chunk_create(data->buf, strlen(data->buf)); - if (secret.len) + secret = chunk_create(buf, strlen(buf)); + if (secret.len > 1) { /* trim appended \n */ secret.len--; + if (match_me) + { + *match_me = ID_MATCH_PERFECT; + } + if (match_other) + { + *match_other = ID_MATCH_NONE; + } + return shared_key_create(SHARED_PIN, chunk_clone(secret)); + } + } + return NULL; +} + +/** + * Load a smartcard with a PIN + */ +static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr, + FILE *prompt) +{ + chunk_t sc = chunk_empty, secret = chunk_empty; + char smartcard[64], keyid[64], module[64], *pos; + private_key_t *key = NULL; + u_int slot; + chunk_t chunk; + shared_key_t *shared; + identification_t *id; + mem_cred_t *mem = NULL; + callback_cred_t *cb = NULL; + pin_cb_data_t pin_data; + enum { + SC_FORMAT_SLOT_MODULE_KEYID, + SC_FORMAT_SLOT_KEYID, + SC_FORMAT_KEYID, + } format; + + err_t ugh = extract_value(&sc, &line); + + if (ugh != NULL) + { + DBG1(DBG_CFG, "line %d: %s", line_nr, ugh); + return FALSE; + } + if (sc.len == 0) + { + DBG1(DBG_CFG, "line %d: expected %%smartcard specifier", line_nr); + return FALSE; + } + snprintf(smartcard, sizeof(smartcard), "%.*s", sc.len, sc.ptr); + smartcard[sizeof(smartcard) - 1] = '\0'; + + /* parse slot and key id. Three formats are supported: + * - %smartcard<slot>@<module>:<keyid> + * - %smartcard<slot>:<keyid> + * - %smartcard:<keyid> + */ + if (sscanf(smartcard, "%%smartcard%u@%s", &slot, module) == 2) + { + pos = strchr(module, ':'); + if (!pos) + { + DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is " + "invalid", line_nr); + return FALSE; + } + *pos = '\0'; + strcpy(keyid, pos + 1); + format = SC_FORMAT_SLOT_MODULE_KEYID; + } + else if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2) + { + format = SC_FORMAT_SLOT_KEYID; + } + else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1) + { + format = SC_FORMAT_KEYID; + } + else + { + DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not" + " supported or invalid", line_nr); + return FALSE; + } + + if (!eat_whitespace(&line)) + { + DBG1(DBG_CFG, "line %d: expected PIN", line_nr); + return FALSE; + } + ugh = extract_secret(&secret, &line); + if (ugh != NULL) + { + DBG1(DBG_CFG, "line %d: malformed PIN: %s", line_nr, ugh); + return FALSE; + } + + chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL); + if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7)) + { + free(secret.ptr); + if (!prompt) + { /* no IO channel to prompt, skip */ + free(chunk.ptr); + return TRUE; + } + /* use callback credential set to prompt for the pin */ + pin_data.prompt = prompt; + pin_data.card = smartcard; + pin_data.keyid = chunk; + pin_data.try = 1; + cb = callback_cred_create_shared((void*)pin_cb, &pin_data); + lib->credmgr->add_local_set(lib->credmgr, &cb->set); + } + else + { + /* provide our pin in a temporary credential set */ + shared = shared_key_create(SHARED_PIN, secret); + id = identification_create_from_encoding(ID_KEY_ID, chunk); + mem = mem_cred_create(); + mem->add_shared(mem, shared, id, NULL); + lib->credmgr->add_local_set(lib->credmgr, &mem->set); + } + + /* unlock: smartcard needs the pin and potentially calls public set */ + this->lock->unlock(this->lock); + switch (format) + { + case SC_FORMAT_SLOT_MODULE_KEYID: + key = lib->creds->create(lib->creds, + CRED_PRIVATE_KEY, KEY_ANY, + BUILD_PKCS11_SLOT, slot, + BUILD_PKCS11_MODULE, module, + BUILD_PKCS11_KEYID, chunk, BUILD_END); + break; + case SC_FORMAT_SLOT_KEYID: + key = lib->creds->create(lib->creds, + CRED_PRIVATE_KEY, KEY_ANY, + BUILD_PKCS11_SLOT, slot, + BUILD_PKCS11_KEYID, chunk, BUILD_END); + break; + case SC_FORMAT_KEYID: + key = lib->creds->create(lib->creds, + CRED_PRIVATE_KEY, KEY_ANY, + BUILD_PKCS11_KEYID, chunk, BUILD_END); + break; + } + this->lock->write_lock(this->lock); + if (mem) + { + lib->credmgr->remove_local_set(lib->credmgr, &mem->set); + mem->destroy(mem); + } + if (cb) + { + lib->credmgr->remove_local_set(lib->credmgr, &cb->set); + cb->destroy(cb); + } + + if (key) + { + DBG1(DBG_CFG, " loaded private key from %.*s", sc.len, sc.ptr); + this->private->insert_last(this->private, key); + } + return TRUE; +} + +/** + * Load a private key + */ +static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr, + FILE *prompt, key_type_t key_type) +{ + char path[PATH_MAX]; + chunk_t filename; + chunk_t secret = chunk_empty; + private_key_t *key; + + err_t ugh = extract_value(&filename, &line); + + if (ugh != NULL) + { + DBG1(DBG_CFG, "line %d: %s", line_nr, ugh); + return FALSE; + } + if (filename.len == 0) + { + DBG1(DBG_CFG, "line %d: empty filename", line_nr); + return FALSE; + } + if (*filename.ptr == '/') + { + /* absolute path name */ + snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr); + } + else + { + /* relative path name */ + snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR, + filename.len, filename.ptr); + } + + /* check for optional passphrase */ + if (eat_whitespace(&line)) + { + ugh = extract_secret(&secret, &line); + if (ugh != NULL) + { + DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh); + return FALSE; + } + } + if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7)) + { + callback_cred_t *cb = NULL; + passphrase_cb_data_t pp_data = { + .prompt = prompt, + .path = path, + .try = 1, + }; + + free(secret.ptr); + if (!prompt) + { + return TRUE; + } + /* use callback credential set to prompt for the passphrase */ + pp_data.prompt = prompt; + pp_data.path = path; + pp_data.try = 1; + cb = callback_cred_create_shared((void*)passphrase_cb, &pp_data); + lib->credmgr->add_local_set(lib->credmgr, &cb->set); + + /* unlock, as the builder might ask for a secret */ + this->lock->unlock(this->lock); + key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type, + BUILD_FROM_FILE, path, BUILD_END); + this->lock->write_lock(this->lock); + + lib->credmgr->remove_local_set(lib->credmgr, &cb->set); + cb->destroy(cb); + } + else + { + mem_cred_t *mem = NULL; + shared_key_t *shared; + + /* provide our pin in a temporary credential set */ + shared = shared_key_create(SHARED_PRIVATE_KEY_PASS, secret); + mem = mem_cred_create(); + mem->add_shared(mem, shared, NULL); + lib->credmgr->add_local_set(lib->credmgr, &mem->set); + + /* unlock, as the builder might ask for a secret */ + this->lock->unlock(this->lock); + key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type, + BUILD_FROM_FILE, path, BUILD_END); + this->lock->write_lock(this->lock); + + lib->credmgr->remove_local_set(lib->credmgr, &mem->set); + mem->destroy(mem); + } + if (key) + { + DBG1(DBG_CFG, " loaded %N private key from '%s'", + key_type_names, key->get_type(key), path); + this->private->insert_last(this->private, key); + } + else + { + DBG1(DBG_CFG, " loading private key from '%s' failed", path); + } + return TRUE; +} + +/** + * Load a shared key + */ +static bool load_shared(private_stroke_cred_t *this, chunk_t line, int line_nr, + shared_key_type_t type, chunk_t ids) +{ + stroke_shared_key_t *shared_key; + chunk_t secret = chunk_empty; + bool any = TRUE; + + err_t ugh = extract_secret(&secret, &line); + if (ugh != NULL) + { + DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh); + return FALSE; + } + shared_key = stroke_shared_key_create(type, secret); + DBG1(DBG_CFG, " loaded %N secret for %s", shared_key_type_names, type, + ids.len > 0 ? (char*)ids.ptr : "%any"); + DBG4(DBG_CFG, " secret: %#B", &secret); + + this->shared->insert_last(this->shared, shared_key); + while (ids.len > 0) + { + chunk_t id; + identification_t *peer_id; + + ugh = extract_value(&id, &ids); + if (ugh != NULL) + { + DBG1(DBG_CFG, "line %d: %s", line_nr, ugh); + return FALSE; + } + if (id.len == 0) + { + continue; + } + + /* NULL terminate the ID string */ + *(id.ptr + id.len) = '\0'; + peer_id = identification_create_from_string(id.ptr); + if (peer_id->get_type(peer_id) == ID_ANY) + { + peer_id->destroy(peer_id); + continue; } + + shared_key->add_owner(shared_key, peer_id); + any = FALSE; + } + if (any) + { + shared_key->add_owner(shared_key, + identification_create_from_encoding(ID_ANY, chunk_empty)); } - return secret; + return TRUE; } /** @@ -716,30 +1128,36 @@ chunk_t passphrase_cb(passphrase_cb_data_t *data, int try) static void load_secrets(private_stroke_cred_t *this, char *file, int level, FILE *prompt) { - size_t bytes; - int line_nr = 0; - chunk_t chunk, src, line; - FILE *fd; + int line_nr = 0, fd; + chunk_t src, line; private_key_t *private; shared_key_t *shared; + struct stat sb; + void *addr; DBG1(DBG_CFG, "loading secrets from '%s'", file); - - fd = fopen(file, "r"); - if (fd == NULL) + fd = open(file, O_RDONLY); + if (fd == -1) { - DBG1(DBG_CFG, "opening secrets file '%s' failed", file); + DBG1(DBG_CFG, "opening secrets file '%s' failed: %s", file, + strerror(errno)); return; } - - /* TODO: do error checks */ - fseek(fd, 0, SEEK_END); - chunk.len = ftell(fd); - rewind(fd); - chunk.ptr = malloc(chunk.len); - bytes = fread(chunk.ptr, 1, chunk.len, fd); - fclose(fd); - src = chunk; + if (fstat(fd, &sb) == -1) + { + DBG1(DBG_LIB, "getting file size of '%s' failed: %s", file, + strerror(errno)); + close(fd); + return; + } + 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", file, strerror(errno)); + close(fd); + return; + } + src = chunk_create(addr, sb.st_size); if (level == 0) { @@ -844,223 +1262,52 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, else { DBG1(DBG_CFG, "line %d: missing ' : ' separator", line_nr); - goto error; + break; } if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line)) { DBG1(DBG_CFG, "line %d: missing token", line_nr); - goto error; + break; } if (match("RSA", &token) || match("ECDSA", &token)) { - char path[PATH_MAX]; - chunk_t filename; - chunk_t secret = chunk_empty; - private_key_t *key = NULL; - key_type_t key_type = match("RSA", &token) ? KEY_RSA : KEY_ECDSA; - - err_t ugh = extract_value(&filename, &line); - - if (ugh != NULL) - { - DBG1(DBG_CFG, "line %d: %s", line_nr, ugh); - goto error; - } - if (filename.len == 0) - { - DBG1(DBG_CFG, "line %d: empty filename", line_nr); - goto error; - } - if (*filename.ptr == '/') - { - /* absolute path name */ - snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr); - } - else - { - /* relative path name */ - snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR, - filename.len, filename.ptr); - } - - /* check for optional passphrase */ - if (eat_whitespace(&line)) - { - ugh = extract_secret(&secret, &line); - if (ugh != NULL) - { - DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh); - goto error; - } - } - if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7)) - { - if (prompt) - { - passphrase_cb_data_t data; - - data.prompt = prompt; - data.file = path; - key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, - key_type, BUILD_FROM_FILE, path, - BUILD_PASSPHRASE_CALLBACK, - passphrase_cb, &data, BUILD_END); - } - } - else - { - key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type, - BUILD_FROM_FILE, path, - BUILD_PASSPHRASE, secret, BUILD_END); - } - if (key) + if (!load_private(this, line, line_nr, prompt, + match("RSA", &token) ? KEY_RSA : KEY_ECDSA)) { - DBG1(DBG_CFG, " loaded %N private key from '%s'", - key_type_names, key->get_type(key), path); - this->private->insert_last(this->private, key); - } - else - { - DBG1(DBG_CFG, " loading private key from '%s' failed", path); + break; } - chunk_clear(&secret); } else if (match("PIN", &token)) { - chunk_t sc = chunk_empty, secret = chunk_empty; - char smartcard[32], keyid[22], pin[32]; - private_key_t *key; - u_int slot; - - err_t ugh = extract_value(&sc, &line); - - if (ugh != NULL) - { - DBG1(DBG_CFG, "line %d: %s", line_nr, ugh); - goto error; - } - if (sc.len == 0) - { - DBG1(DBG_CFG, "line %d: expected %%smartcard specifier", line_nr); - goto error; - } - snprintf(smartcard, sizeof(smartcard), "%.*s", sc.len, sc.ptr); - smartcard[sizeof(smartcard) - 1] = '\0'; - - /* parse slot and key id. only two formats are supported. - * first try %smartcard<slot>:<keyid> */ - if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2) - { - snprintf(smartcard, sizeof(smartcard), "%u:%s", slot, keyid); - } - /* then try %smartcard:<keyid> */ - else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1) - { - snprintf(smartcard, sizeof(smartcard), "%s", keyid); - } - else - { - DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not" - " supported or invalid", line_nr); - goto error; - } - - if (!eat_whitespace(&line)) - { - DBG1(DBG_CFG, "line %d: expected PIN", line_nr); - goto error; - } - ugh = extract_secret(&secret, &line); - if (ugh != NULL) + if (!load_pin(this, line, line_nr, prompt)) { - DBG1(DBG_CFG, "line %d: malformed PIN: %s", line_nr, ugh); - goto error; - } - snprintf(pin, sizeof(pin), "%.*s", secret.len, secret.ptr); - pin[sizeof(pin) - 1] = '\0'; - - /* we assume an RSA key */ - key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, - BUILD_SMARTCARD_KEYID, smartcard, - BUILD_SMARTCARD_PIN, pin, BUILD_END); - - if (key) - { - DBG1(DBG_CFG, " loaded private key from %.*s", sc.len, sc.ptr); - this->private->insert_last(this->private, key); + break; } - memset(pin, 0, sizeof(pin)); - chunk_clear(&secret); } else if ((match("PSK", &token) && (type = SHARED_IKE)) || (match("EAP", &token) && (type = SHARED_EAP)) || (match("NTLM", &token) && (type = SHARED_NT_HASH)) || (match("XAUTH", &token) && (type = SHARED_EAP))) { - stroke_shared_key_t *shared_key; - chunk_t secret = chunk_empty; - bool any = TRUE; - - err_t ugh = extract_secret(&secret, &line); - if (ugh != NULL) - { - DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh); - goto error; - } - shared_key = stroke_shared_key_create(type, secret); - DBG1(DBG_CFG, " loaded %N secret for %s", shared_key_type_names, type, - ids.len > 0 ? (char*)ids.ptr : "%any"); - DBG4(DBG_CFG, " secret: %#B", &secret); - - this->shared->insert_last(this->shared, shared_key); - while (ids.len > 0) + if (!load_shared(this, line, line_nr, type, ids)) { - chunk_t id; - identification_t *peer_id; - - ugh = extract_value(&id, &ids); - if (ugh != NULL) - { - DBG1(DBG_CFG, "line %d: %s", line_nr, ugh); - goto error; - } - if (id.len == 0) - { - continue; - } - - /* NULL terminate the ID string */ - *(id.ptr + id.len) = '\0'; - peer_id = identification_create_from_string(id.ptr); - if (peer_id->get_type(peer_id) == ID_ANY) - { - peer_id->destroy(peer_id); - continue; - } - - shared_key->add_owner(shared_key, peer_id); - any = FALSE; - } - if (any) - { - shared_key->add_owner(shared_key, - identification_create_from_encoding(ID_ANY, chunk_empty)); + break; } } else { DBG1(DBG_CFG, "line %d: token must be either " "RSA, ECDSA, PSK, EAP, XAUTH or PIN", line_nr); - goto error; + break; } } -error: if (level == 0) { this->lock->unlock(this->lock); } - chunk_clear(&chunk); + munmap(addr, sb.st_size); + close(fd); } /** diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index a6de35466..86deea490 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -21,6 +21,7 @@ #include <malloc.h> #endif /* HAVE_MALLINFO */ +#include <hydra.h> #include <daemon.h> #include <utils/linked_list.h> #include <credentials/certificates/x509.h> @@ -422,12 +423,12 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo } #endif /* HAVE_MALLINFO */ fprintf(out, " worker threads: %d idle of %d,", - charon->processor->get_idle_threads(charon->processor), - charon->processor->get_total_threads(charon->processor)); + lib->processor->get_idle_threads(lib->processor), + lib->processor->get_total_threads(lib->processor)); fprintf(out, " job queue load: %d,", - charon->processor->get_job_load(charon->processor)); + lib->processor->get_job_load(lib->processor)); fprintf(out, " scheduled events: %d\n", - charon->scheduler->get_job_load(charon->scheduler)); + lib->scheduler->get_job_load(lib->scheduler)); fprintf(out, " loaded plugins: "); enumerator = lib->plugins->create_plugin_enumerator(lib->plugins); while (enumerator->enumerate(enumerator, &plugin)) @@ -454,8 +455,8 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo } enumerator->destroy(enumerator); - enumerator = charon->kernel_interface->create_address_enumerator( - charon->kernel_interface, FALSE, FALSE); + enumerator = hydra->kernel_interface->create_address_enumerator( + hydra->kernel_interface, FALSE, FALSE); fprintf(out, "Listening IP addresses:\n"); while (enumerator->enumerate(enumerator, (void**)&host)) { @@ -638,7 +639,7 @@ static void list_public_key(public_key_t *public, FILE *out) fprintf(out, " pubkey: %N %d bits%s\n", key_type_names, public->get_type(public), - public->get_keysize(public) * 8, + public->get_keysize(public), private ? ", has private key" : ""); if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid)) { @@ -1026,9 +1027,10 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out) */ static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out) { - bool first = TRUE; + bool first = TRUE, ok; enumerator_t *enumerator = list->create_enumerator(list); certificate_t *cert; + time_t produced, usable, now = time(NULL); while (enumerator->enumerate(enumerator, (void**)&cert)) { @@ -1039,8 +1041,20 @@ static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out) fprintf(out, "\n"); first = FALSE; } - fprintf(out, " signer: \"%Y\"\n", cert->get_issuer(cert)); + + /* check validity */ + ok = cert->get_validity(cert, &now, &produced, &usable); + fprintf(out, " validity: produced at %T\n", &produced, utc); + fprintf(out, " usable till %T, ", &usable, utc); + if (ok) + { + fprintf(out, "ok\n"); + } + else + { + fprintf(out, "expired (%V ago)\n", &now, &usable); + } } enumerator->destroy(enumerator); } @@ -1073,6 +1087,13 @@ static void list_algs(FILE *out) fprintf(out, "%N ", integrity_algorithm_names, integrity); } enumerator->destroy(enumerator); + fprintf(out, "\n aead: "); + enumerator = lib->crypto->create_aead_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &encryption)) + { + fprintf(out, "%N ", encryption_algorithm_names, encryption); + } + enumerator->destroy(enumerator); fprintf(out, "\n hasher: "); enumerator = lib->crypto->create_hasher_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &hash)) @@ -1184,7 +1205,7 @@ static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool, bool on; int found = 0; - fprintf(out, "Leases in pool '%s', usage: %lu/%lu, %lu online\n", + fprintf(out, "Leases in pool '%s', usage: %u/%u, %u online\n", pool, online + offline, size, online); enumerator = this->attribute->create_lease_enumerator(this->attribute, pool); while (enumerator && enumerator->enumerate(enumerator, &id, &lease, &on)) diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 18afa5af4..0a5110fd3 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -24,10 +24,10 @@ #include <unistd.h> #include <errno.h> -#include <processing/jobs/callback_job.h> #include <hydra.h> #include <daemon.h> #include <threading/thread.h> +#include <processing/jobs/callback_job.h> #include "stroke_config.h" #include "stroke_control.h" @@ -180,11 +180,13 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg) pop_end(msg, "left", &msg->add_conn.me); pop_end(msg, "right", &msg->add_conn.other); pop_string(msg, &msg->add_conn.eap_identity); + pop_string(msg, &msg->add_conn.aaa_identity); pop_string(msg, &msg->add_conn.algorithms.ike); pop_string(msg, &msg->add_conn.algorithms.esp); pop_string(msg, &msg->add_conn.ikeme.mediated_by); pop_string(msg, &msg->add_conn.ikeme.peerid); DBG2(DBG_CFG, " eap_identity=%s", msg->add_conn.eap_identity); + 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, " mediation=%s", msg->add_conn.ikeme.mediation ? "yes" : "no"); @@ -353,6 +355,37 @@ static void stroke_purge(private_stroke_socket_t *this, } /** + * Export in-memory credentials + */ +static void stroke_export(private_stroke_socket_t *this, + stroke_msg_t *msg, FILE *out) +{ + pop_string(msg, &msg->export.selector); + + if (msg->purge.flags & EXPORT_X509) + { + enumerator_t *enumerator; + identification_t *id; + certificate_t *cert; + chunk_t encoded; + + id = identification_create_from_string(msg->export.selector); + enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr, + CERT_X509, KEY_ANY, id, FALSE); + while (enumerator->enumerate(enumerator, &cert)) + { + if (cert->get_encoding(cert, CERT_PEM, &encoded)) + { + fprintf(out, "%.*s", encoded.len, encoded.ptr); + free(encoded.ptr); + } + } + enumerator->destroy(enumerator); + id->destroy(id); + } +} + +/** * list pool leases */ static void stroke_leases(private_stroke_socket_t *this, @@ -364,21 +397,6 @@ static void stroke_leases(private_stroke_socket_t *this, this->list->leases(this->list, msg, out); } -debug_t get_group_from_name(char *type) -{ - if (strcaseeq(type, "any")) return DBG_ANY; - else if (strcaseeq(type, "mgr")) return DBG_MGR; - else if (strcaseeq(type, "ike")) return DBG_IKE; - else if (strcaseeq(type, "chd")) return DBG_CHD; - else if (strcaseeq(type, "job")) return DBG_JOB; - else if (strcaseeq(type, "cfg")) return DBG_CFG; - else if (strcaseeq(type, "knl")) return DBG_KNL; - else if (strcaseeq(type, "net")) return DBG_NET; - else if (strcaseeq(type, "enc")) return DBG_ENC; - else if (strcaseeq(type, "lib")) return DBG_LIB; - else return -1; -} - /** * set the verbosity debug output */ @@ -394,7 +412,7 @@ static void stroke_loglevel(private_stroke_socket_t *this, DBG1(DBG_CFG, "received stroke: loglevel %d for %s", msg->loglevel.level, msg->loglevel.type); - group = get_group_from_name(msg->loglevel.type); + group = enum_from_name(debug_names, msg->loglevel.type); if (group < 0) { fprintf(out, "invalid type (%s)!\n", msg->loglevel.type); @@ -525,6 +543,9 @@ static job_requeue_t process(stroke_job_context_t *ctx) case STR_PURGE: stroke_purge(this, msg, out); break; + case STR_EXPORT: + stroke_export(this, msg, out); + break; case STR_LEASES: stroke_leases(this, msg, out); break; @@ -565,7 +586,7 @@ static job_requeue_t receive(private_stroke_socket_t *this) ctx->this = this; job = callback_job_create((callback_job_cb_t)process, ctx, (void*)stroke_job_context_destroy, this->job); - charon->processor->queue_job(charon->processor, (job_t*)job); + lib->processor->queue_job(lib->processor, (job_t*)job); return JOB_REQUEUE_FAIR; } @@ -663,7 +684,7 @@ stroke_socket_t *stroke_socket_create() this->job = callback_job_create((callback_job_cb_t)receive, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); return &this->public; } diff --git a/src/libcharon/plugins/tnc_imc/Makefile.am b/src/libcharon/plugins/tnc_imc/Makefile.am new file mode 100644 index 000000000..ca8869460 --- /dev/null +++ b/src/libcharon/plugins/tnc_imc/Makefile.am @@ -0,0 +1,19 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon `xml2-config --cflags` + +AM_CFLAGS = -rdynamic + +libstrongswan_tnc_imc_la_LIBADD = -ltnc + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-tnc-imc.la +else +plugin_LTLIBRARIES = libstrongswan-tnc-imc.la +endif + +libstrongswan_tnc_imc_la_SOURCES = \ + tnc_imc_plugin.h tnc_imc_plugin.c + +libstrongswan_tnc_imc_la_LDFLAGS = -module -avoid-version + diff --git a/src/libcharon/plugins/kernel_pfroute/Makefile.in b/src/libcharon/plugins/tnc_imc/Makefile.in index f78a97013..9a8794e93 100644 --- a/src/libcharon/plugins/kernel_pfroute/Makefile.in +++ b/src/libcharon/plugins/tnc_imc/Makefile.in @@ -34,7 +34,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/libcharon/plugins/kernel_pfroute +subdir = src/libcharon/plugins/tnc_imc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -73,18 +74,16 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_kernel_pfroute_la_LIBADD = -am_libstrongswan_kernel_pfroute_la_OBJECTS = kernel_pfroute_plugin.lo \ - kernel_pfroute_net.lo -libstrongswan_kernel_pfroute_la_OBJECTS = \ - $(am_libstrongswan_kernel_pfroute_la_OBJECTS) -libstrongswan_kernel_pfroute_la_LINK = $(LIBTOOL) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libstrongswan_kernel_pfroute_la_LDFLAGS) $(LDFLAGS) -o $@ -@MONOLITHIC_FALSE@am_libstrongswan_kernel_pfroute_la_rpath = -rpath \ +libstrongswan_tnc_imc_la_DEPENDENCIES = +am_libstrongswan_tnc_imc_la_OBJECTS = tnc_imc_plugin.lo +libstrongswan_tnc_imc_la_OBJECTS = \ + $(am_libstrongswan_tnc_imc_la_OBJECTS) +libstrongswan_tnc_imc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_tnc_imc_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_tnc_imc_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) -@MONOLITHIC_TRUE@am_libstrongswan_kernel_pfroute_la_rpath = +@MONOLITHIC_TRUE@am_libstrongswan_tnc_imc_la_rpath = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -98,8 +97,8 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libstrongswan_kernel_pfroute_la_SOURCES) -DIST_SOURCES = $(libstrongswan_kernel_pfroute_la_SOURCES) +SOURCES = $(libstrongswan_tnc_imc_la_SOURCES) +DIST_SOURCES = $(libstrongswan_tnc_imc_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -168,6 +167,8 @@ 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@ @@ -199,14 +200,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +225,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +257,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ @@ -258,17 +272,17 @@ 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 \ - -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 `xml2-config --cflags` AM_CFLAGS = -rdynamic -@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-pfroute.la -@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la -libstrongswan_kernel_pfroute_la_SOURCES = \ - kernel_pfroute_plugin.h kernel_pfroute_plugin.c \ - kernel_pfroute_net.h kernel_pfroute_net.c +libstrongswan_tnc_imc_la_LIBADD = -ltnc +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imc.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imc.la +libstrongswan_tnc_imc_la_SOURCES = \ + tnc_imc_plugin.h tnc_imc_plugin.c -libstrongswan_kernel_pfroute_la_LDFLAGS = -module -avoid-version +libstrongswan_tnc_imc_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: @@ -282,9 +296,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfroute/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_imc/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfroute/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_imc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -343,8 +357,8 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libstrongswan-kernel-pfroute.la: $(libstrongswan_kernel_pfroute_la_OBJECTS) $(libstrongswan_kernel_pfroute_la_DEPENDENCIES) - $(libstrongswan_kernel_pfroute_la_LINK) $(am_libstrongswan_kernel_pfroute_la_rpath) $(libstrongswan_kernel_pfroute_la_OBJECTS) $(libstrongswan_kernel_pfroute_la_LIBADD) $(LIBS) +libstrongswan-tnc-imc.la: $(libstrongswan_tnc_imc_la_OBJECTS) $(libstrongswan_tnc_imc_la_DEPENDENCIES) + $(libstrongswan_tnc_imc_la_LINK) $(am_libstrongswan_tnc_imc_la_rpath) $(libstrongswan_tnc_imc_la_OBJECTS) $(libstrongswan_tnc_imc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -352,8 +366,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfroute_net.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfroute_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imc_plugin.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c new file mode 100644 index 000000000..0ce930ba3 --- /dev/null +++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c @@ -0,0 +1,57 @@ +/* + * 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_imc_plugin.h" + +#include <libtnctncc.h> + +#include <daemon.h> + +METHOD(plugin_t, destroy, void, + tnc_imc_plugin_t *this) +{ + libtnc_tncc_Terminate(); + free(this); +} + +/* + * see header file + */ +plugin_t *tnc_imc_plugin_create() +{ + char *tnc_config, *pref_lang; + tnc_imc_plugin_t *this; + + INIT(this, + .plugin = { + .destroy = _destroy, + }, + ); + + pref_lang = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-imc.preferred_language", "en"); + tnc_config = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config"); + + if (libtnc_tncc_Initialize(tnc_config) != TNC_RESULT_SUCCESS) + { + free(this); + DBG1(DBG_TNC, "TNC IMC initialization failed"); + return NULL; + } + + return &this->plugin; +} + diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.h b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.h new file mode 100644 index 000000000..8c5521cb2 --- /dev/null +++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.h @@ -0,0 +1,42 @@ +/* + * 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 tnc_imc tnc_imc + * @ingroup cplugins + * + * @defgroup tnc_imc_plugin tnc_imc_plugin + * @{ @ingroup tnc_imc + */ + +#ifndef TNC_IMC_PLUGIN_H_ +#define TNC_IMC_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct tnc_imc_plugin_t tnc_imc_plugin_t; + +/** + * TNC IMC plugin + */ +struct tnc_imc_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** TNC_IMC_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/tnc_imv/Makefile.am b/src/libcharon/plugins/tnc_imv/Makefile.am new file mode 100644 index 000000000..9c3b47364 --- /dev/null +++ b/src/libcharon/plugins/tnc_imv/Makefile.am @@ -0,0 +1,19 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon `xml2-config --cflags` + +AM_CFLAGS = -rdynamic + +libstrongswan_tnc_imv_la_LIBADD = -ltnc + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-tnc-imv.la +else +plugin_LTLIBRARIES = libstrongswan-tnc-imv.la +endif + +libstrongswan_tnc_imv_la_SOURCES = \ + tnc_imv_plugin.h tnc_imv_plugin.c + +libstrongswan_tnc_imv_la_LDFLAGS = -module -avoid-version + diff --git a/src/libcharon/plugins/kernel_pfkey/Makefile.in b/src/libcharon/plugins/tnc_imv/Makefile.in index 1dda6827b..f89b5e03b 100644 --- a/src/libcharon/plugins/kernel_pfkey/Makefile.in +++ b/src/libcharon/plugins/tnc_imv/Makefile.in @@ -34,7 +34,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/libcharon/plugins/kernel_pfkey +subdir = src/libcharon/plugins/tnc_imv DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -73,18 +74,16 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_kernel_pfkey_la_LIBADD = -am_libstrongswan_kernel_pfkey_la_OBJECTS = kernel_pfkey_plugin.lo \ - kernel_pfkey_ipsec.lo -libstrongswan_kernel_pfkey_la_OBJECTS = \ - $(am_libstrongswan_kernel_pfkey_la_OBJECTS) -libstrongswan_kernel_pfkey_la_LINK = $(LIBTOOL) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libstrongswan_kernel_pfkey_la_LDFLAGS) $(LDFLAGS) -o $@ -@MONOLITHIC_FALSE@am_libstrongswan_kernel_pfkey_la_rpath = -rpath \ +libstrongswan_tnc_imv_la_DEPENDENCIES = +am_libstrongswan_tnc_imv_la_OBJECTS = tnc_imv_plugin.lo +libstrongswan_tnc_imv_la_OBJECTS = \ + $(am_libstrongswan_tnc_imv_la_OBJECTS) +libstrongswan_tnc_imv_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_tnc_imv_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_tnc_imv_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) -@MONOLITHIC_TRUE@am_libstrongswan_kernel_pfkey_la_rpath = +@MONOLITHIC_TRUE@am_libstrongswan_tnc_imv_la_rpath = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -98,8 +97,8 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libstrongswan_kernel_pfkey_la_SOURCES) -DIST_SOURCES = $(libstrongswan_kernel_pfkey_la_SOURCES) +SOURCES = $(libstrongswan_tnc_imv_la_SOURCES) +DIST_SOURCES = $(libstrongswan_tnc_imv_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -168,6 +167,8 @@ 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@ @@ -199,14 +200,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -221,24 +225,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -246,7 +257,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ @@ -258,17 +272,17 @@ 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 \ - -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 `xml2-config --cflags` AM_CFLAGS = -rdynamic -@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-pfkey.la -@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la -libstrongswan_kernel_pfkey_la_SOURCES = \ - kernel_pfkey_plugin.h kernel_pfkey_plugin.c \ - kernel_pfkey_ipsec.h kernel_pfkey_ipsec.c +libstrongswan_tnc_imv_la_LIBADD = -ltnc +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imv.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imv.la +libstrongswan_tnc_imv_la_SOURCES = \ + tnc_imv_plugin.h tnc_imv_plugin.c -libstrongswan_kernel_pfkey_la_LDFLAGS = -module -avoid-version +libstrongswan_tnc_imv_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: @@ -282,9 +296,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfkey/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_imv/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfkey/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_imv/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -343,8 +357,8 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libstrongswan-kernel-pfkey.la: $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_DEPENDENCIES) - $(libstrongswan_kernel_pfkey_la_LINK) $(am_libstrongswan_kernel_pfkey_la_rpath) $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_LIBADD) $(LIBS) +libstrongswan-tnc-imv.la: $(libstrongswan_tnc_imv_la_OBJECTS) $(libstrongswan_tnc_imv_la_DEPENDENCIES) + $(libstrongswan_tnc_imv_la_LINK) $(am_libstrongswan_tnc_imv_la_rpath) $(libstrongswan_tnc_imv_la_OBJECTS) $(libstrongswan_tnc_imv_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -352,8 +366,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfkey_ipsec.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfkey_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imv_plugin.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c new file mode 100644 index 000000000..5b3d3892d --- /dev/null +++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c @@ -0,0 +1,54 @@ +/* + * 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_imv_plugin.h" + +#include <libtnctncs.h> + +#include <daemon.h> + +METHOD(plugin_t, destroy, void, + tnc_imv_plugin_t *this) +{ + libtnc_tncs_Terminate(); + free(this); +} + +/* + * see header file + */ +plugin_t *tnc_imv_plugin_create() +{ + char *tnc_config; + tnc_imv_plugin_t *this; + + INIT(this, + .plugin = { + .destroy = _destroy, + }, + ); + + tnc_config = lib->settings->get_str(lib->settings, + "charon.plugins.tnc-imv.tnc_config", "/etc/tnc_config"); + if (libtnc_tncs_Initialize(tnc_config) != TNC_RESULT_SUCCESS) + { + free(this); + DBG1(DBG_TNC, "TNC IMV initialization failed"); + return NULL; + } + + return &this->plugin; +} + diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.h b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.h new file mode 100644 index 000000000..afeee2ea2 --- /dev/null +++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.h @@ -0,0 +1,42 @@ +/* + * 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 tnc_imv tnc_imv + * @ingroup cplugins + * + * @defgroup tnc_imv_plugin tnc_imv_plugin + * @{ @ingroup tnc_imv + */ + +#ifndef TNC_IMV_PLUGIN_H_ +#define TNC_IMV_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct tnc_imv_plugin_t tnc_imv_plugin_t; + +/** + * TNC IMV plugin + */ +struct tnc_imv_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** TNC_IMV_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/Makefile.am b/src/libcharon/plugins/tnccs_11/Makefile.am new file mode 100644 index 000000000..7ccd0dfee --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/Makefile.am @@ -0,0 +1,21 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \ + `xml2-config --cflags` + +AM_CFLAGS = -rdynamic + +libstrongswan_tnccs_11_la_LIBADD = -ltnc + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-tnccs-11.la +else +plugin_LTLIBRARIES = libstrongswan-tnccs-11.la +libstrongswan_tnccs_11_la_LIBADD += $(top_builddir)/src/libtls/libtls.la +endif + +libstrongswan_tnccs_11_la_SOURCES = \ + tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c + +libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version + diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.in b/src/libcharon/plugins/tnccs_11/Makefile.in index 49cc895bc..200ff7a0a 100644 --- a/src/libcharon/plugins/kernel_netlink/Makefile.in +++ b/src/libcharon/plugins/tnccs_11/Makefile.in @@ -34,7 +34,8 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/libcharon/plugins/kernel_netlink +@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libtls/libtls.la +subdir = src/libcharon/plugins/tnccs_11 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ @@ -44,6 +45,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -73,19 +75,17 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_kernel_netlink_la_LIBADD = -am_libstrongswan_kernel_netlink_la_OBJECTS = kernel_netlink_plugin.lo \ - kernel_netlink_ipsec.lo kernel_netlink_net.lo \ - kernel_netlink_shared.lo -libstrongswan_kernel_netlink_la_OBJECTS = \ - $(am_libstrongswan_kernel_netlink_la_OBJECTS) -libstrongswan_kernel_netlink_la_LINK = $(LIBTOOL) --tag=CC \ +libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__append_1) +am_libstrongswan_tnccs_11_la_OBJECTS = tnccs_11_plugin.lo tnccs_11.lo +libstrongswan_tnccs_11_la_OBJECTS = \ + $(am_libstrongswan_tnccs_11_la_OBJECTS) +libstrongswan_tnccs_11_la_LINK = $(LIBTOOL) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libstrongswan_kernel_netlink_la_LDFLAGS) $(LDFLAGS) -o $@ -@MONOLITHIC_FALSE@am_libstrongswan_kernel_netlink_la_rpath = -rpath \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_tnccs_11_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_tnccs_11_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) -@MONOLITHIC_TRUE@am_libstrongswan_kernel_netlink_la_rpath = +@MONOLITHIC_TRUE@am_libstrongswan_tnccs_11_la_rpath = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -99,8 +99,8 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) -DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) +SOURCES = $(libstrongswan_tnccs_11_la_SOURCES) +DIST_SOURCES = $(libstrongswan_tnccs_11_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -169,6 +169,8 @@ 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@ @@ -200,14 +202,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -222,24 +227,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -247,7 +259,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ @@ -259,21 +274,18 @@ 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 \ - -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon - -AM_CFLAGS = -rdynamic \ --DROUTING_TABLE=${routing_table} \ --DROUTING_TABLE_PRIO=${routing_table_prio} - -@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-netlink.la -@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-netlink.la -libstrongswan_kernel_netlink_la_SOURCES = \ - kernel_netlink_plugin.h kernel_netlink_plugin.c \ - kernel_netlink_ipsec.h kernel_netlink_ipsec.c kernel_netlink_net.h kernel_netlink_net.c \ - kernel_netlink_shared.h kernel_netlink_shared.c - -libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \ + `xml2-config --cflags` + +AM_CFLAGS = -rdynamic +libstrongswan_tnccs_11_la_LIBADD = -ltnc $(am__append_1) +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-11.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-11.la +libstrongswan_tnccs_11_la_SOURCES = \ + tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c + +libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version all: all-am .SUFFIXES: @@ -287,9 +299,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_netlink/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnccs_11/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_netlink/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/tnccs_11/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -348,8 +360,8 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libstrongswan-kernel-netlink.la: $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_DEPENDENCIES) - $(libstrongswan_kernel_netlink_la_LINK) $(am_libstrongswan_kernel_netlink_la_rpath) $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_LIBADD) $(LIBS) +libstrongswan-tnccs-11.la: $(libstrongswan_tnccs_11_la_OBJECTS) $(libstrongswan_tnccs_11_la_DEPENDENCIES) + $(libstrongswan_tnccs_11_la_LINK) $(am_libstrongswan_tnccs_11_la_rpath) $(libstrongswan_tnccs_11_la_OBJECTS) $(libstrongswan_tnccs_11_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -357,10 +369,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_ipsec.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_net.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_plugin.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_shared.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_11.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_11_plugin.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.c b/src/libcharon/plugins/tnccs_11/tnccs_11.c new file mode 100644 index 000000000..704bf64ed --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/tnccs_11.c @@ -0,0 +1,328 @@ +/* + * 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 "tnccs_11.h" + +#include <libtnctncc.h> +#include <libtnctncs.h> + +#include <daemon.h> +#include <debug.h> + +#define TNC_SEND_BUFFER_SIZE 32 + +static chunk_t tnc_send_buffer[TNC_SEND_BUFFER_SIZE]; + +/** + * Buffers TNCCS batch to be sent (TODO make the buffer scalable) + */ +static TNC_Result buffer_batch(u_int32_t id, const char *data, size_t len) +{ + if (id >= TNC_SEND_BUFFER_SIZE) + { + DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be stored in " + "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE); + return TNC_RESULT_FATAL; + } + if (tnc_send_buffer[id].ptr) + { + DBG1(DBG_TNC, "send buffer slot for Connection ID %u is already " + "occupied", id); + return TNC_RESULT_FATAL; + } + tnc_send_buffer[id] = chunk_alloc(len); + memcpy(tnc_send_buffer[id].ptr, data, len); + + return TNC_RESULT_SUCCESS; +} + +/** + * Retrieves TNCCS batch to be sent + */ +static bool retrieve_batch(u_int32_t id, chunk_t *batch) +{ + if (id >= TNC_SEND_BUFFER_SIZE) + { + DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be retrieved from " + "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE); + return FALSE; + } + + *batch = tnc_send_buffer[id]; + return TRUE; +} + +/** + * Frees TNCCS batch that was sent + */ +static void free_batch(u_int32_t id) +{ + if (id < TNC_SEND_BUFFER_SIZE) + { + chunk_free(&tnc_send_buffer[id]); + } +} + +/** + * Define callback functions called by the libtnc library + */ +TNC_Result TNC_TNCC_SendBatch(libtnc_tncc_connection* conn, + const char* messageBuffer, size_t messageLength) +{ + return buffer_batch(conn->connectionID, messageBuffer, messageLength); +} + +TNC_Result TNC_TNCS_SendBatch(libtnc_tncs_connection* conn, + const char* messageBuffer, size_t messageLength) +{ + return buffer_batch(conn->connectionID, messageBuffer, messageLength); +} + +typedef struct private_tnccs_11_t private_tnccs_11_t; + +/** + * Private data of a tnccs_11_t object. + */ +struct private_tnccs_11_t { + + /** + * Public tls_t interface. + */ + tls_t public; + + /** + * TNCC if TRUE, TNCS if FALSE + */ + bool is_server; + + /** + * TNCC Connection to IMCs + */ + libtnc_tncc_connection* tncc_connection; + + /** + * TNCS Connection to IMVs + */ + libtnc_tncs_connection* tncs_connection; +}; + +METHOD(tls_t, process, status_t, + private_tnccs_11_t *this, void *buf, size_t buflen) +{ + u_int32_t conn_id; + + if (this->is_server && !this->tncs_connection) + { + this->tncs_connection = libtnc_tncs_CreateConnection(NULL); + if (!this->tncs_connection) + { + DBG1(DBG_TNC, "TNCS CreateConnection failed"); + return FAILED; + } + DBG1(DBG_TNC, "assigned TNCS Connection ID %u", + this->tncs_connection->connectionID); + if (libtnc_tncs_BeginSession(this->tncs_connection) != TNC_RESULT_SUCCESS) + { + DBG1(DBG_TNC, "TNCS BeginSession failed"); + return FAILED; + } + } + conn_id = this->is_server ? this->tncs_connection->connectionID + : this->tncc_connection->connectionID; + + DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u", + buflen, conn_id); + DBG3(DBG_TNC, "%.*s", buflen, buf); + + if (this->is_server) + { + if (libtnc_tncs_ReceiveBatch(this->tncs_connection, buf, buflen) != + TNC_RESULT_SUCCESS) + { + DBG1(DBG_TNC, "TNCS ReceiveBatch failed"); + return FAILED; + } + } + else + { + if (libtnc_tncc_ReceiveBatch(this->tncc_connection, buf, buflen) != + TNC_RESULT_SUCCESS) + { + DBG1(DBG_TNC, "TNCC ReceiveBatch failed"); + return FAILED; + } + } + return NEED_MORE; +} + +METHOD(tls_t, build, status_t, + private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen) +{ + chunk_t batch; + u_int32_t conn_id; + size_t len; + + if (!this->is_server && !this->tncc_connection) + { + this->tncc_connection = libtnc_tncc_CreateConnection(NULL); + if (!this->tncc_connection) + { + DBG1(DBG_TNC, "TNCC CreateConnection failed"); + return FAILED; + } + DBG1(DBG_TNC, "assigned TNCC Connection ID %u", + this->tncc_connection->connectionID); + if (libtnc_tncc_BeginSession(this->tncc_connection) != TNC_RESULT_SUCCESS) + { + DBG1(DBG_TNC, "TNCC BeginSession failed"); + return FAILED; + } + } + conn_id = this->is_server ? this->tncs_connection->connectionID + : this->tncc_connection->connectionID; + + if (!retrieve_batch(conn_id, &batch)) + { + return FAILED; + } + len = *buflen; + len = min(len, batch.len); + *buflen = len; + if (msglen) + { + *msglen = batch.len; + } + + if (batch.len) + { + DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u", + batch.len, conn_id); + DBG3(DBG_TNC, "%.*s", batch.len, batch.ptr); + memcpy(buf, batch.ptr, len); + free_batch(conn_id); + return ALREADY_DONE; + } + else + { + return INVALID_STATE; + } +} + +METHOD(tls_t, is_server, bool, + private_tnccs_11_t *this) +{ + return this->is_server; +} + +METHOD(tls_t, get_purpose, tls_purpose_t, + private_tnccs_11_t *this) +{ + return TLS_PURPOSE_EAP_TNC; +} + +METHOD(tls_t, is_complete, bool, + private_tnccs_11_t *this) +{ + TNC_IMV_Action_Recommendation rec; + TNC_IMV_Evaluation_Result eval; + char *group; + identification_t *id; + ike_sa_t *ike_sa; + auth_cfg_t *auth; + + if (libtnc_tncs_HaveRecommendation(this->tncs_connection, &rec, &eval) == + TNC_RESULT_SUCCESS) + { + switch (rec) + { + case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: + DBG1(DBG_TNC, "TNC recommendation is allow"); + group = "allow"; + break; + case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: + DBG1(DBG_TNC, "TNC recommendation is isolate"); + group = "isolate"; + break; + case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: + case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION: + default: + DBG1(DBG_TNC, "TNC recommendation is none"); + return FALSE; + } + ike_sa = charon->bus->get_sa(charon->bus); + if (ike_sa) + { + auth = ike_sa->get_auth_cfg(ike_sa, FALSE); + id = identification_create_from_string(group); + auth->add(auth, AUTH_RULE_GROUP, id); + DBG1(DBG_TNC, "added group membership '%s' based on TNC recommendation", group); + } + return TRUE; + } + else + { + return FALSE; + } +} + +METHOD(tls_t, get_eap_msk, chunk_t, + private_tnccs_11_t *this) +{ + return chunk_empty; +} + +METHOD(tls_t, destroy, void, + private_tnccs_11_t *this) +{ + if (this->is_server) + { + if (this->tncs_connection) + { + libtnc_tncs_DeleteConnection(this->tncs_connection); + } + } + else + { + if (this->tncc_connection) + { + libtnc_tncc_DeleteConnection(this->tncc_connection); + } + libtnc_tncc_Terminate(); + } + free(this); +} + +/** + * See header + */ +tls_t *tnccs_11_create(bool is_server) +{ + private_tnccs_11_t *this; + + INIT(this, + .public = { + .process = _process, + .build = _build, + .is_server = _is_server, + .get_purpose = _get_purpose, + .is_complete = _is_complete, + .get_eap_msk = _get_eap_msk, + .destroy = _destroy, + }, + .is_server = is_server, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.h b/src/libcharon/plugins/tnccs_11/tnccs_11.h new file mode 100644 index 000000000..7331fc8cd --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/tnccs_11.h @@ -0,0 +1,36 @@ +/* + * 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_11_h tnccs_11 + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_11_H_ +#define TNCCS_11_H_ + +#include <library.h> + +#include <tls.h> + +/** + * Create an instance of the TNC IF-TNCCS 1.1 protocol handler. + * + * @param is_server TRUE to act as TNC Server, FALSE for TNC Client + * @return TNC_IF_TNCCS 1.1 protocol stack + */ +tls_t *tnccs_11_create(bool is_server); + +#endif /** TNCCS_11_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c new file mode 100644 index 000000000..03905ca37 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c @@ -0,0 +1,47 @@ +/* + * 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 "tnccs_11_plugin.h" +#include "tnccs_11.h" + +#include <daemon.h> + +METHOD(plugin_t, destroy, void, + tnccs_11_plugin_t *this) +{ + charon->tnccs->remove_method(charon->tnccs, + (tnccs_constructor_t)tnccs_11_create); + free(this); +} + +/* + * see header file + */ +plugin_t *tnccs_11_plugin_create() +{ + tnccs_11_plugin_t *this; + + INIT(this, + .plugin = { + .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_11/tnccs_11_plugin.h b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.h new file mode 100644 index 000000000..619a073ad --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.h @@ -0,0 +1,42 @@ +/* + * 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_11 tnccs_11 + * @ingroup cplugins + * + * @defgroup tnccs_11_plugin tnccs_11_plugin + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_11_PLUGIN_H_ +#define TNCCS_11_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct tnccs_11_plugin_t tnccs_11_plugin_t; + +/** + * EAP-TNC plugin + */ +struct tnccs_11_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** TNCCS_11_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/Makefile.am b/src/libcharon/plugins/tnccs_20/Makefile.am new file mode 100644 index 000000000..3018121e3 --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/Makefile.am @@ -0,0 +1,21 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \ + `xml2-config --cflags` + +AM_CFLAGS = -rdynamic + +libstrongswan_tnccs_20_la_LIBADD = -ltnc + +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 +endif + +libstrongswan_tnccs_20_la_SOURCES = \ + tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c + +libstrongswan_tnccs_20_la_LDFLAGS = -module -avoid-version + diff --git a/src/libcharon/plugins/tnccs_20/Makefile.in b/src/libcharon/plugins/tnccs_20/Makefile.in new file mode 100644 index 000000000..6101f91df --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/Makefile.in @@ -0,0 +1,607 @@ +# 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@ +@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libtls/libtls.la +subdir = src/libcharon/plugins/tnccs_20 +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_tnccs_20_la_DEPENDENCIES = $(am__append_1) +am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo +libstrongswan_tnccs_20_la_OBJECTS = \ + $(am_libstrongswan_tnccs_20_la_OBJECTS) +libstrongswan_tnccs_20_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_tnccs_20_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_tnccs_20_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_tnccs_20_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_tnccs_20_la_SOURCES) +DIST_SOURCES = $(libstrongswan_tnccs_20_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@ +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@ +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@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgid = @ipsecgid@ +ipsecgroup = @ipsecgroup@ +ipsecuid = @ipsecuid@ +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@ +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@ +srcdir = @srcdir@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +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/libtls \ + `xml2-config --cflags` + +AM_CFLAGS = -rdynamic +libstrongswan_tnccs_20_la_LIBADD = -ltnc $(am__append_1) +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-20.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-20.la +libstrongswan_tnccs_20_la_SOURCES = \ + tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c + +libstrongswan_tnccs_20_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/tnccs_20/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/tnccs_20/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-tnccs-20.la: $(libstrongswan_tnccs_20_la_OBJECTS) $(libstrongswan_tnccs_20_la_DEPENDENCIES) + $(libstrongswan_tnccs_20_la_LINK) $(am_libstrongswan_tnccs_20_la_rpath) $(libstrongswan_tnccs_20_la_OBJECTS) $(libstrongswan_tnccs_20_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_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/tnccs_20/tnccs_20.c b/src/libcharon/plugins/tnccs_20/tnccs_20.c new file mode 100644 index 000000000..2bd1bc476 --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/tnccs_20.c @@ -0,0 +1,103 @@ +/* + * 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 "tnccs_20.h" + +#include <debug.h> + +static chunk_t tncc_output; + +typedef struct private_tnccs_20_t private_tnccs_20_t; + +/** + * Private data of a tnccs_20_t object. + */ +struct private_tnccs_20_t { + + /** + * Public tls_t interface. + */ + tls_t public; + + /** + * TNCC if TRUE, TNCS if FALSE + */ + bool is_server; +}; + +METHOD(tls_t, process, status_t, + private_tnccs_20_t *this, void *buf, size_t buflen) +{ + return NEED_MORE; +} + +METHOD(tls_t, build, status_t, + private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen) +{ + return ALREADY_DONE; +} + +METHOD(tls_t, is_server, bool, + private_tnccs_20_t *this) +{ + return this->is_server; +} + +METHOD(tls_t, get_purpose, tls_purpose_t, + private_tnccs_20_t *this) +{ + return TLS_PURPOSE_EAP_TNC; +} + +METHOD(tls_t, is_complete, bool, + private_tnccs_20_t *this) +{ + return FALSE; +} + +METHOD(tls_t, get_eap_msk, chunk_t, + private_tnccs_20_t *this) +{ + return chunk_empty; +} + +METHOD(tls_t, destroy, void, + private_tnccs_20_t *this) +{ + free(this); +} + +/** + * See header + */ +tls_t *tnccs_20_create(bool is_server) +{ + private_tnccs_20_t *this; + + INIT(this, + .public = { + .process = _process, + .build = _build, + .is_server = _is_server, + .get_purpose = _get_purpose, + .is_complete = _is_complete, + .get_eap_msk = _get_eap_msk, + .destroy = _destroy, + }, + .is_server = is_server, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20.h b/src/libcharon/plugins/tnccs_20/tnccs_20.h new file mode 100644 index 000000000..400d1dc12 --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/tnccs_20.h @@ -0,0 +1,36 @@ +/* + * 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_20_h tnccs_20 + * @{ @ingroup tnccs_20 + */ + +#ifndef TNCCS_20_H_ +#define TNCCS_20_H_ + +#include <library.h> + +#include <tls.h> + +/** + * Create an instance of the TNC IF-TNCCS 2.0 protocol handler. + * + * @param is_server TRUE to act as TNC Server, FALSE for TNC Client + * @return TNC_IF_TNCCS 2.0 protocol stack + */ +tls_t *tnccs_20_create(bool is_server); + +#endif /** TNCCS_20_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c new file mode 100644 index 000000000..82c78f74c --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c @@ -0,0 +1,47 @@ +/* + * 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 "tnccs_20_plugin.h" +#include "tnccs_20.h" + +#include <daemon.h> + +METHOD(plugin_t, destroy, void, + tnccs_20_plugin_t *this) +{ + charon->tnccs->remove_method(charon->tnccs, + (tnccs_constructor_t)tnccs_20_create); + free(this); +} + +/* + * see header file + */ +plugin_t *tnccs_20_plugin_create() +{ + tnccs_20_plugin_t *this; + + INIT(this, + .plugin = { + .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_20/tnccs_20_plugin.h b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.h new file mode 100644 index 000000000..1c4ecf4c9 --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.h @@ -0,0 +1,42 @@ +/* + * 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_20 tnccs_20 + * @ingroup cplugins + * + * @defgroup tnccs_20_plugin tnccs_20_plugin + * @{ @ingroup tnccs_20 + */ + +#ifndef TNCCS_20_PLUGIN_H_ +#define TNCCS_20_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct tnccs_20_plugin_t tnccs_20_plugin_t; + +/** + * EAP-TNC plugin + */ +struct tnccs_20_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** TNCCS_20_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in index 934ab6080..9cb5f794a 100644 --- a/src/libcharon/plugins/uci/Makefile.in +++ b/src/libcharon/plugins/uci/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -165,6 +166,8 @@ 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@ @@ -196,14 +199,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -243,7 +256,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/uci/uci_control.c b/src/libcharon/plugins/uci/uci_control.c index 3c4928be4..aee2505e3 100644 --- a/src/libcharon/plugins/uci/uci_control.c +++ b/src/libcharon/plugins/uci/uci_control.c @@ -294,7 +294,7 @@ uci_control_t *uci_control_create() { this->job = callback_job_create((callback_job_cb_t)receive, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); + lib->processor->queue_job(lib->processor, (job_t*)this->job); } return &this->public; } diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/unit_tester/Makefile.in index 47850c1c5..47fff7e1d 100644 --- a/src/libcharon/plugins/unit_tester/Makefile.in +++ b/src/libcharon/plugins/unit_tester/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -171,6 +172,8 @@ 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@ @@ -202,14 +205,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -224,24 +230,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -249,7 +262,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/unit_tester/tests/test_cert.c b/src/libcharon/plugins/unit_tester/tests/test_cert.c index 3b00421f8..342194a4c 100644 --- a/src/libcharon/plugins/unit_tester/tests/test_cert.c +++ b/src/libcharon/plugins/unit_tester/tests/test_cert.c @@ -51,7 +51,7 @@ bool test_cert_x509() return FALSE; } - encoding = ca_cert->get_encoding(ca_cert); + ca_cert->get_encoding(ca_cert, CERT_ASN1_DER, &encoding); parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_BLOB_ASN1_DER, encoding, BUILD_END); @@ -81,7 +81,7 @@ bool test_cert_x509() return FALSE; } - encoding = peer_cert->get_encoding(peer_cert); + peer_cert->get_encoding(peer_cert, CERT_ASN1_DER, &encoding); parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_BLOB_ASN1_DER, encoding, BUILD_END); diff --git a/src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c b/src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c index 59da15644..6ba5769b5 100644 --- a/src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c +++ b/src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c @@ -59,12 +59,12 @@ bool test_rsa_gen() return FALSE; } free(sig.ptr); - if (!public->encrypt(public, data, &crypt)) + if (!public->encrypt(public, ENCRYPT_RSA_PKCS1, data, &crypt)) { DBG1(DBG_CFG, "encrypting data with RSA failed"); return FALSE; } - if (!private->decrypt(private, crypt, &plain)) + if (!private->decrypt(private, ENCRYPT_RSA_PKCS1, crypt, &plain)) { DBG1(DBG_CFG, "decrypting data with RSA failed"); return FALSE; @@ -110,7 +110,7 @@ bool test_rsa_load_any() public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, BUILD_BLOB_ASN1_DER, chunk, BUILD_END); - if (!public || public->get_keysize(public) != 256) + if (!public || public->get_keysize(public) != 2048) { return FALSE; } diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in index ce233ad04..e93955d71 100644 --- a/src/libcharon/plugins/updown/Makefile.in +++ b/src/libcharon/plugins/updown/Makefile.in @@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.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) @@ -167,6 +168,8 @@ 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@ @@ -198,14 +201,17 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ +c_plugins = @c_plugins@ 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@ @@ -220,24 +226,31 @@ ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ -libhydra_plugins = @libhydra_plugins@ -libstrongswan_plugins = @libstrongswan_plugins@ 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@ 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@ @@ -245,7 +258,10 @@ 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@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c index ea4a792c2..8e58b1a9b 100644 --- a/src/libcharon/plugins/updown/updown_listener.c +++ b/src/libcharon/plugins/updown/updown_listener.c @@ -18,6 +18,7 @@ #include "updown_listener.h" +#include <hydra.h> #include <daemon.h> #include <config/child_cfg.h> @@ -218,8 +219,8 @@ METHOD(listener_t, child_updown, bool, if (up) { - iface = charon->kernel_interface->get_interface( - charon->kernel_interface, me); + iface = hydra->kernel_interface->get_interface( + hydra->kernel_interface, me); if (iface) { cache_iface(this, child_sa->get_reqid(child_sa), iface); diff --git a/src/libcharon/processing/jobs/acquire_job.h b/src/libcharon/processing/jobs/acquire_job.h index eff79a9b0..2b5bf4805 100644 --- a/src/libcharon/processing/jobs/acquire_job.h +++ b/src/libcharon/processing/jobs/acquire_job.h @@ -15,7 +15,7 @@ /** * @defgroup acquire_job acquire_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef ACQUIRE_JOB_H_ diff --git a/src/libcharon/processing/jobs/callback_job.c b/src/libcharon/processing/jobs/callback_job.c deleted file mode 100644 index 45e49112e..000000000 --- a/src/libcharon/processing/jobs/callback_job.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2009 Tobias Brunner - * Copyright (C) 2007 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 "callback_job.h" - -#include <semaphore.h> - -#include <daemon.h> -#include <threading/thread.h> -#include <threading/condvar.h> -#include <threading/mutex.h> - -typedef struct private_callback_job_t private_callback_job_t; - -/** - * Private data of an callback_job_t Object. - */ -struct private_callback_job_t { - /** - * Public callback_job_t interface. - */ - callback_job_t public; - - /** - * Callback to call on execution - */ - callback_job_cb_t callback; - - /** - * parameter to supply to callback - */ - void *data; - - /** - * cleanup function for data - */ - callback_job_cleanup_t cleanup; - - /** - * thread of the job, if running - */ - thread_t *thread; - - /** - * mutex to access jobs interna - */ - mutex_t *mutex; - - /** - * list of asociated child jobs - */ - linked_list_t *children; - - /** - * parent of this job, or NULL - */ - private_callback_job_t *parent; - - /** - * TRUE if the job got cancelled - */ - bool cancelled; - - /** - * condvar to synchronize the cancellation/destruction of the job - */ - condvar_t *destroyable; - - /** - * semaphore to synchronize the termination of the assigned thread. - * - * separately allocated during cancellation, so that we can wait on it - * without risking that it gets freed too early during destruction. - */ - sem_t *terminated; -}; - -/** - * unregister a child from its parent, if any. - * note: this->mutex has to be locked - */ -static void unregister(private_callback_job_t *this) -{ - if (this->parent) - { - this->parent->mutex->lock(this->parent->mutex); - if (this->parent->cancelled && !this->cancelled) - { - /* if the parent has been cancelled but we have not yet, we do not - * unregister until we got cancelled by the parent. */ - this->parent->mutex->unlock(this->parent->mutex); - this->destroyable->wait(this->destroyable, this->mutex); - this->parent->mutex->lock(this->parent->mutex); - } - this->parent->children->remove(this->parent->children, this, NULL); - this->parent->mutex->unlock(this->parent->mutex); - this->parent = NULL; - } -} - -/** - * Implements job_t.destroy. - */ -static void destroy(private_callback_job_t *this) -{ - this->mutex->lock(this->mutex); - unregister(this); - if (this->cleanup) - { - this->cleanup(this->data); - } - if (this->terminated) - { - sem_post(this->terminated); - } - this->children->destroy(this->children); - this->destroyable->destroy(this->destroyable); - this->mutex->unlock(this->mutex); - this->mutex->destroy(this->mutex); - free(this); -} - -/** - * Implementation of callback_job_t.cancel. - */ -static void cancel(private_callback_job_t *this) -{ - callback_job_t *child; - sem_t *terminated = NULL; - - this->mutex->lock(this->mutex); - this->cancelled = TRUE; - /* terminate children */ - while (this->children->get_first(this->children, (void**)&child) == SUCCESS) - { - this->mutex->unlock(this->mutex); - child->cancel(child); - this->mutex->lock(this->mutex); - } - if (this->thread) - { - /* terminate the thread, if there is currently one executing the job. - * we wait for its termination using a semaphore */ - this->thread->cancel(this->thread); - terminated = this->terminated = malloc_thing(sem_t); - sem_init(terminated, 0, 0); - } - else - { - /* if the job is currently queued, it gets terminated later. - * we can't wait, because it might not get executed at all. - * we also unregister the queued job manually from its parent (the - * others get unregistered during destruction) */ - unregister(this); - } - this->destroyable->signal(this->destroyable); - this->mutex->unlock(this->mutex); - - if (terminated) - { - sem_wait(terminated); - sem_destroy(terminated); - free(terminated); - } -} - -/** - * Implementation of job_t.execute. - */ -static void execute(private_callback_job_t *this) -{ - bool cleanup = FALSE, requeue = FALSE; - - thread_cleanup_push((thread_cleanup_t)destroy, this); - - this->mutex->lock(this->mutex); - this->thread = thread_current(); - this->mutex->unlock(this->mutex); - - while (TRUE) - { - this->mutex->lock(this->mutex); - if (this->cancelled) - { - this->mutex->unlock(this->mutex); - cleanup = TRUE; - break; - } - this->mutex->unlock(this->mutex); - switch (this->callback(this->data)) - { - case JOB_REQUEUE_DIRECT: - continue; - case JOB_REQUEUE_FAIR: - { - requeue = TRUE; - break; - } - case JOB_REQUEUE_NONE: - default: - { - cleanup = TRUE; - break; - } - } - break; - } - this->mutex->lock(this->mutex); - this->thread = NULL; - this->mutex->unlock(this->mutex); - /* manually create a cancellation point to avoid that a cancelled thread - * goes back into the thread pool */ - thread_cancellation_point(); - if (requeue) - { - charon->processor->queue_job(charon->processor, - &this->public.job_interface); - } - thread_cleanup_pop(cleanup); -} - -/* - * Described in header. - */ -callback_job_t *callback_job_create(callback_job_cb_t cb, void *data, - callback_job_cleanup_t cleanup, - callback_job_t *parent) -{ - private_callback_job_t *this = malloc_thing(private_callback_job_t); - - /* interface functions */ - this->public.job_interface.execute = (void (*) (job_t *)) execute; - this->public.job_interface.destroy = (void (*) (job_t *)) destroy; - this->public.cancel = (void(*)(callback_job_t*))cancel; - - /* private variables */ - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - this->callback = cb; - this->data = data; - this->cleanup = cleanup; - this->thread = 0; - this->children = linked_list_create(); - this->parent = (private_callback_job_t*)parent; - this->cancelled = FALSE; - this->destroyable = condvar_create(CONDVAR_TYPE_DEFAULT); - this->terminated = NULL; - - /* register us at parent */ - if (parent) - { - this->parent->mutex->lock(this->parent->mutex); - this->parent->children->insert_last(this->parent->children, this); - this->parent->mutex->unlock(this->parent->mutex); - } - - return &this->public; -} - diff --git a/src/libcharon/processing/jobs/callback_job.h b/src/libcharon/processing/jobs/callback_job.h deleted file mode 100644 index 62da1edd1..000000000 --- a/src/libcharon/processing/jobs/callback_job.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2007 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 callback_job callback_job - * @{ @ingroup jobs - */ - -#ifndef CALLBACK_JOB_H_ -#define CALLBACK_JOB_H_ - -typedef struct callback_job_t callback_job_t; - -#include <library.h> -#include <processing/jobs/job.h> - - -typedef enum job_requeue_t job_requeue_t; - -/** - * Job requeueing policy - * - * The job requeueing policy defines how a job is handled when the callback - * function returns. - */ -enum job_requeue_t { - - /** - * Do not requeue job, destroy it - */ - JOB_REQUEUE_NONE, - - /** - * Reque the job fairly, meaning it has to requeue as any other job - */ - JOB_REQUEUE_FAIR, - - /** - * Reexecute the job directly, without the need of requeueing it - */ - JOB_REQUEUE_DIRECT, -}; - -/** - * The callback function to use for the callback job. - * - * This is the function to use as callback for a callback job. It receives - * a parameter supplied to the callback jobs constructor. - * - * @param data param supplied to job - * @return requeing policy how to requeue the job - */ -typedef job_requeue_t (*callback_job_cb_t)(void *data); - -/** - * Cleanup function to use for data cleanup. - * - * The callback has an optional user argument which receives data. However, - * this data may be cleaned up if it is allocated. This is the function - * to supply to the constructor. - * - * @param data param supplied to job - * @return requeing policy how to requeue the job - */ -typedef void (*callback_job_cleanup_t)(void *data); - -/** - * Class representing an callback Job. - * - * This is a special job which allows a simple callback function to - * be executed by a thread of the thread pool. This allows simple execution - * of asynchronous methods, without to manage threads. - */ -struct callback_job_t { - /** - * The job_t interface. - */ - job_t job_interface; - - /** - * Cancel the job's thread and wait for its termination. This only works - * reliably for jobs that always use JOB_REQUEUE_FAIR or JOB_REQUEUE_DIRECT, - * otherwise the job may already be destroyed when cancel is called. */ - void (*cancel)(callback_job_t *this); -}; - -/** - * Creates a callback job. - * - * The cleanup function is called when the job gets destroyed to destroy - * the associated data. - * If parent is not NULL, the specified job gets an association. Whenever - * the parent gets cancelled (or runs out), all of its children are cancelled, - * too. - * - * @param cb callback to call from the processor - * @param data user data to supply to callback - * @param cleanup destructor for data on destruction, or NULL - * @param parent parent of this job - * @return callback_job_t object - */ -callback_job_t *callback_job_create(callback_job_cb_t cb, void *data, - callback_job_cleanup_t cleanup, - callback_job_t *parent); - -#endif /** CALLBACK_JOB_H_ @}*/ diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h index 662a7b7c7..fc0e2b518 100644 --- a/src/libcharon/processing/jobs/delete_child_sa_job.h +++ b/src/libcharon/processing/jobs/delete_child_sa_job.h @@ -15,7 +15,7 @@ /** * @defgroup delete_child_sa_job delete_child_sa_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef DELETE_CHILD_SA_JOB_H_ diff --git a/src/libcharon/processing/jobs/delete_ike_sa_job.h b/src/libcharon/processing/jobs/delete_ike_sa_job.h index f641deea3..ae06b9cfc 100644 --- a/src/libcharon/processing/jobs/delete_ike_sa_job.h +++ b/src/libcharon/processing/jobs/delete_ike_sa_job.h @@ -16,7 +16,7 @@ /** * @defgroup delete_child_sa_job delete_child_sa_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef DELETE_IKE_SA_JOB_H_ diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c index 13fc5e3d0..1371000eb 100644 --- a/src/libcharon/processing/jobs/inactivity_job.c +++ b/src/libcharon/processing/jobs/inactivity_job.c @@ -87,7 +87,7 @@ METHOD(job_t, execute, void, } else { - charon->scheduler->schedule_job(charon->scheduler, + lib->scheduler->schedule_job(lib->scheduler, &this->public.job_interface, this->timeout - diff); rescheduled = TRUE; } @@ -136,9 +136,11 @@ inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout, private_inactivity_job_t *this; INIT(this, - .public.job_interface = { - .execute = _execute, - .destroy = _destroy, + .public = { + .job_interface = { + .execute = _execute, + .destroy = _destroy, + }, }, .reqid = reqid, .timeout = timeout, diff --git a/src/libcharon/processing/jobs/inactivity_job.h b/src/libcharon/processing/jobs/inactivity_job.h index 9c9daced8..890f7704b 100644 --- a/src/libcharon/processing/jobs/inactivity_job.h +++ b/src/libcharon/processing/jobs/inactivity_job.h @@ -15,7 +15,7 @@ /** * @defgroup inactivity_job inactivity_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef INACTIVITY_JOB_H_ diff --git a/src/libcharon/processing/jobs/initiate_mediation_job.h b/src/libcharon/processing/jobs/initiate_mediation_job.h index fddb1dd7b..d105de2b9 100644 --- a/src/libcharon/processing/jobs/initiate_mediation_job.h +++ b/src/libcharon/processing/jobs/initiate_mediation_job.h @@ -15,7 +15,7 @@ /** * @defgroup initiate_mediation_job initiate_mediation_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef INITIATE_MEDIATION_JOB_H_ diff --git a/src/libcharon/processing/jobs/job.h b/src/libcharon/processing/jobs/job.h deleted file mode 100644 index 0f1c16ebe..000000000 --- a/src/libcharon/processing/jobs/job.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 job job - * @{ @ingroup jobs - */ - -#ifndef JOB_H_ -#define JOB_H_ - -typedef struct job_t job_t; - -#include <library.h> - -/** - * Job-Interface as it is stored in the job queue. - */ -struct job_t { - - /** - * Execute a job. - * - * The processing facility executes a job using this method. Jobs are - * one-shot, they destroy themself after execution, so don't use a job - * once it has been executed. - */ - void (*execute) (job_t *this); - - /** - * Destroy a job. - * - * Is only called whenever a job was not executed (e.g. due daemon shutdown). - * After execution, jobs destroy themself. - */ - void (*destroy) (job_t *job); -}; - -#endif /** JOB_H_ @}*/ diff --git a/src/libcharon/processing/jobs/mediation_job.h b/src/libcharon/processing/jobs/mediation_job.h index 0574c65eb..41485cbc6 100644 --- a/src/libcharon/processing/jobs/mediation_job.h +++ b/src/libcharon/processing/jobs/mediation_job.h @@ -15,7 +15,7 @@ /** * @defgroup mediation_job mediation_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef MEDIATION_JOB_H_ diff --git a/src/libcharon/processing/jobs/migrate_job.h b/src/libcharon/processing/jobs/migrate_job.h index de313d517..09679c734 100644 --- a/src/libcharon/processing/jobs/migrate_job.h +++ b/src/libcharon/processing/jobs/migrate_job.h @@ -15,7 +15,7 @@ /** * @defgroup migrate_job migrate_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef MIGRATE_JOB_H_ diff --git a/src/libcharon/processing/jobs/process_message_job.h b/src/libcharon/processing/jobs/process_message_job.h index 5e3f44d1f..2c42aa577 100644 --- a/src/libcharon/processing/jobs/process_message_job.h +++ b/src/libcharon/processing/jobs/process_message_job.h @@ -16,7 +16,7 @@ /** * @defgroup process_message_job process_message_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef PROCESS_MESSAGE_JOB_H_ diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.h b/src/libcharon/processing/jobs/rekey_child_sa_job.h index 62887d6b9..fcbe65a06 100644 --- a/src/libcharon/processing/jobs/rekey_child_sa_job.h +++ b/src/libcharon/processing/jobs/rekey_child_sa_job.h @@ -15,7 +15,7 @@ /** * @defgroup rekey_child_sa_job rekey_child_sa_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef REKEY_CHILD_SA_JOB_H_ diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.h b/src/libcharon/processing/jobs/rekey_ike_sa_job.h index a5c1028aa..3e3e13d00 100644 --- a/src/libcharon/processing/jobs/rekey_ike_sa_job.h +++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.h @@ -15,7 +15,7 @@ /** * @defgroup rekey_ike_sa_job rekey_ike_sa_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef REKEY_IKE_SA_JOB_H_ diff --git a/src/libcharon/processing/jobs/retransmit_job.h b/src/libcharon/processing/jobs/retransmit_job.h index c8c13479b..c4545534b 100644 --- a/src/libcharon/processing/jobs/retransmit_job.h +++ b/src/libcharon/processing/jobs/retransmit_job.h @@ -16,7 +16,7 @@ /** * @defgroup retransmit_job retransmit_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef RETRANSMIT_JOB_H_ diff --git a/src/libcharon/processing/jobs/roam_job.h b/src/libcharon/processing/jobs/roam_job.h index 55bdf2b28..acfb8bed8 100644 --- a/src/libcharon/processing/jobs/roam_job.h +++ b/src/libcharon/processing/jobs/roam_job.h @@ -15,7 +15,7 @@ /** * @defgroup roam_job roam_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef ROAM_JOB_H_ diff --git a/src/libcharon/processing/jobs/send_dpd_job.h b/src/libcharon/processing/jobs/send_dpd_job.h index 8078a38bc..bd2728b9a 100644 --- a/src/libcharon/processing/jobs/send_dpd_job.h +++ b/src/libcharon/processing/jobs/send_dpd_job.h @@ -15,7 +15,7 @@ /** * @defgroup send_dpd_job send_dpd_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef SEND_DPD_JOB_H_ diff --git a/src/libcharon/processing/jobs/send_keepalive_job.h b/src/libcharon/processing/jobs/send_keepalive_job.h index cda83cd7e..acf6d11aa 100644 --- a/src/libcharon/processing/jobs/send_keepalive_job.h +++ b/src/libcharon/processing/jobs/send_keepalive_job.h @@ -15,7 +15,7 @@ /** * @defgroup send_keepalive_job send_keepalive_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef SEND_KEEPALIVE_JOB_H_ diff --git a/src/libcharon/processing/jobs/update_sa_job.h b/src/libcharon/processing/jobs/update_sa_job.h index 11d1ac9b6..e2344fcc4 100644 --- a/src/libcharon/processing/jobs/update_sa_job.h +++ b/src/libcharon/processing/jobs/update_sa_job.h @@ -15,7 +15,7 @@ /** * @defgroup update_sa_job update_sa_job - * @{ @ingroup jobs + * @{ @ingroup cjobs */ #ifndef UPDATE_SA_JOB_H_ diff --git a/src/libcharon/processing/processor.c b/src/libcharon/processing/processor.c deleted file mode 100644 index d5774af26..000000000 --- a/src/libcharon/processing/processor.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2005-2007 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "processor.h" - -#include <daemon.h> -#include <threading/thread.h> -#include <threading/condvar.h> -#include <threading/mutex.h> -#include <utils/linked_list.h> - - -typedef struct private_processor_t private_processor_t; - -/** - * Private data of processor_t class. - */ -struct private_processor_t { - /** - * Public processor_t interface. - */ - processor_t public; - - /** - * Number of running threads - */ - u_int total_threads; - - /** - * Desired number of threads - */ - u_int desired_threads; - - /** - * Number of threads waiting for work - */ - u_int idle_threads; - - /** - * All threads managed in the pool (including threads that have been - * cancelled, this allows to join them during destruction) - */ - linked_list_t *threads; - - /** - * The jobs are stored in a linked list - */ - linked_list_t *list; - - /** - * access to linked_list is locked through this mutex - */ - mutex_t *mutex; - - /** - * Condvar to wait for new jobs - */ - condvar_t *job_added; - - /** - * Condvar to wait for terminated threads - */ - condvar_t *thread_terminated; -}; - -static void process_jobs(private_processor_t *this); - -/** - * restart a terminated thread - */ -static void restart(private_processor_t *this) -{ - thread_t *thread; - - DBG2(DBG_JOB, "terminated worker thread, ID: %u", thread_current_id()); - - /* respawn thread if required */ - this->mutex->lock(this->mutex); - if (this->desired_threads < this->total_threads || - (thread = thread_create((thread_main_t)process_jobs, this)) == NULL) - { - this->total_threads--; - this->thread_terminated->signal(this->thread_terminated); - } - else - { - this->threads->insert_last(this->threads, thread); - } - this->mutex->unlock(this->mutex); -} - -/** - * Process queued jobs, called by the worker threads - */ -static void process_jobs(private_processor_t *this) -{ - /* worker threads are not cancellable by default */ - thread_cancelability(FALSE); - - DBG2(DBG_JOB, "started worker thread, ID: %u", thread_current_id()); - - this->mutex->lock(this->mutex); - while (this->desired_threads >= this->total_threads) - { - job_t *job; - - if (this->list->get_count(this->list) == 0) - { - this->idle_threads++; - this->job_added->wait(this->job_added, this->mutex); - this->idle_threads--; - continue; - } - this->list->remove_first(this->list, (void**)&job); - this->mutex->unlock(this->mutex); - /* terminated threads are restarted, so we have a constant pool */ - thread_cleanup_push((thread_cleanup_t)restart, this); - job->execute(job); - thread_cleanup_pop(FALSE); - this->mutex->lock(this->mutex); - } - this->mutex->unlock(this->mutex); - restart(this); -} - -/** - * Implementation of processor_t.get_total_threads. - */ -static u_int get_total_threads(private_processor_t *this) -{ - u_int count; - this->mutex->lock(this->mutex); - count = this->total_threads; - this->mutex->unlock(this->mutex); - return count; -} - -/** - * Implementation of processor_t.get_idle_threads. - */ -static u_int get_idle_threads(private_processor_t *this) -{ - u_int count; - this->mutex->lock(this->mutex); - count = this->idle_threads; - this->mutex->unlock(this->mutex); - return count; -} - -/** - * implements processor_t.get_job_load - */ -static u_int get_job_load(private_processor_t *this) -{ - u_int load; - this->mutex->lock(this->mutex); - load = this->list->get_count(this->list); - this->mutex->unlock(this->mutex); - return load; -} - -/** - * implements function processor_t.queue_job - */ -static void queue_job(private_processor_t *this, job_t *job) -{ - this->mutex->lock(this->mutex); - this->list->insert_last(this->list, job); - this->job_added->signal(this->job_added); - this->mutex->unlock(this->mutex); -} - -/** - * Implementation of processor_t.set_threads. - */ -static void set_threads(private_processor_t *this, u_int count) -{ - this->mutex->lock(this->mutex); - if (count > this->total_threads) - { /* increase thread count */ - int i; - thread_t *current; - - this->desired_threads = count; - DBG1(DBG_JOB, "spawning %d worker threads", count - this->total_threads); - for (i = this->total_threads; i < count; i++) - { - current = thread_create((thread_main_t)process_jobs, this); - if (current) - { - this->threads->insert_last(this->threads, current); - this->total_threads++; - } - } - } - else if (count < this->total_threads) - { /* decrease thread count */ - this->desired_threads = count; - } - this->job_added->broadcast(this->job_added); - this->mutex->unlock(this->mutex); -} - -/** - * Implementation of processor_t.destroy. - */ -static void destroy(private_processor_t *this) -{ - thread_t *current; - set_threads(this, 0); - this->mutex->lock(this->mutex); - while (this->total_threads > 0) - { - this->job_added->broadcast(this->job_added); - this->thread_terminated->wait(this->thread_terminated, this->mutex); - } - while (this->threads->remove_first(this->threads, - (void**)¤t) == SUCCESS) - { - current->join(current); - } - this->mutex->unlock(this->mutex); - this->thread_terminated->destroy(this->thread_terminated); - this->job_added->destroy(this->job_added); - this->mutex->destroy(this->mutex); - this->list->destroy_offset(this->list, offsetof(job_t, destroy)); - this->threads->destroy(this->threads); - free(this); -} - -/* - * Described in header. - */ -processor_t *processor_create(size_t pool_size) -{ - private_processor_t *this = malloc_thing(private_processor_t); - - this->public.get_total_threads = (u_int(*)(processor_t*))get_total_threads; - this->public.get_idle_threads = (u_int(*)(processor_t*))get_idle_threads; - this->public.get_job_load = (u_int(*)(processor_t*))get_job_load; - this->public.queue_job = (void(*)(processor_t*, job_t*))queue_job; - this->public.set_threads = (void(*)(processor_t*, u_int))set_threads; - this->public.destroy = (void(*)(processor_t*))destroy; - - this->list = linked_list_create(); - this->threads = linked_list_create(); - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - this->job_added = condvar_create(CONDVAR_TYPE_DEFAULT); - this->thread_terminated = condvar_create(CONDVAR_TYPE_DEFAULT); - this->total_threads = 0; - this->desired_threads = 0; - this->idle_threads = 0; - - return &this->public; -} - diff --git a/src/libcharon/processing/processor.h b/src/libcharon/processing/processor.h deleted file mode 100644 index 5bf8cf573..000000000 --- a/src/libcharon/processing/processor.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2005-2007 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 processor processor - * @{ @ingroup processing - */ - -#ifndef PROCESSOR_H_ -#define PROCESSOR_H_ - -typedef struct processor_t processor_t; - -#include <stdlib.h> - -#include <library.h> -#include <processing/jobs/job.h> - -/** - * The processor uses threads to process queued jobs. - */ -struct processor_t { - - /** - * Get the total number of threads used by the processor. - * - * @return size of thread pool - */ - u_int (*get_total_threads) (processor_t *this); - - /** - * Get the number of threads currently waiting. - * - * @return number of idle threads - */ - u_int (*get_idle_threads) (processor_t *this); - - /** - * Get the number of queued jobs. - * - * @returns number of items in queue - */ - u_int (*get_job_load) (processor_t *this); - - /** - * Adds a job to the queue. - * - * This function is non blocking and adds a job_t to the queue. - * - * @param job job to add to the queue - */ - void (*queue_job) (processor_t *this, job_t *job); - - /** - * Set the number of threads to use in the processor. - * - * If the number of threads is smaller than number of currently running - * threads, thread count is decreased. Use 0 to disable the processor. - * This call blocks if it decreases thread count until threads have - * terminated, so make sure there are not too many blocking jobs. - * - * @param count number of threads to allocate - */ - void (*set_threads)(processor_t *this, u_int count); - - /** - * Destroy a processor object. - */ - void (*destroy) (processor_t *processor); -}; - -/** - * Create the thread pool without any threads. - * - * Use the set_threads method to start processing jobs. - * - * @return processor_t object - */ -processor_t *processor_create(); - -#endif /** PROCESSOR_H_ @}*/ diff --git a/src/libcharon/processing/scheduler.c b/src/libcharon/processing/scheduler.c deleted file mode 100644 index 345af502a..000000000 --- a/src/libcharon/processing/scheduler.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 <stdlib.h> - -#include "scheduler.h" - -#include <daemon.h> -#include <processing/processor.h> -#include <processing/jobs/callback_job.h> -#include <threading/thread.h> -#include <threading/condvar.h> -#include <threading/mutex.h> - -/* the initial size of the heap */ -#define HEAP_SIZE_DEFAULT 64 - -typedef struct event_t event_t; - -/** - * Event containing a job and a schedule time - */ -struct event_t { - /** - * Time to fire the event. - */ - timeval_t time; - - /** - * Every event has its assigned job. - */ - job_t *job; -}; - -/** - * destroy an event and its job - */ -static void event_destroy(event_t *event) -{ - event->job->destroy(event->job); - free(event); -} - -typedef struct private_scheduler_t private_scheduler_t; - -/** - * Private data of a scheduler_t object. - */ -struct private_scheduler_t { - - /** - * Public part of a scheduler_t object. - */ - scheduler_t public; - - /** - * Job which queues scheduled jobs to the processor. - */ - callback_job_t *job; - - /** - * The heap in which the events are stored. - */ - event_t **heap; - - /** - * The size of the heap. - */ - u_int heap_size; - - /** - * The number of scheduled events. - */ - u_int event_count; - - /** - * Exclusive access to list - */ - mutex_t *mutex; - - /** - * Condvar to wait for next job. - */ - condvar_t *condvar; -}; - -/** - * Comparse two timevals, return >0 if a > b, <0 if a < b and =0 if equal - */ -static int timeval_cmp(timeval_t *a, timeval_t *b) -{ - if (a->tv_sec > b->tv_sec) - { - return 1; - } - if (a->tv_sec < b->tv_sec) - { - return -1; - } - if (a->tv_usec > b->tv_usec) - { - return 1; - } - if (a->tv_usec < b->tv_usec) - { - return -1; - } - return 0; -} - -/** - * Returns the top event without removing it. Returns NULL if the heap is empty. - */ -static event_t *peek_event(private_scheduler_t *this) -{ - return this->event_count > 0 ? this->heap[1] : NULL; -} - -/** - * Removes the top event from the heap and returns it. Returns NULL if the heap - * is empty. - */ -static event_t *remove_event(private_scheduler_t *this) -{ - event_t *event, *top; - if (!this->event_count) - { - return NULL; - } - - /* store the value to return */ - event = this->heap[1]; - /* move the bottom event to the top */ - top = this->heap[1] = this->heap[this->event_count]; - - if (--this->event_count > 1) - { - /* seep down the top event */ - u_int position = 1; - while ((position << 1) <= this->event_count) - { - u_int child = position << 1; - - if ((child + 1) <= this->event_count && - timeval_cmp(&this->heap[child + 1]->time, - &this->heap[child]->time) < 0) - { - /* the "right" child is smaller */ - child++; - } - - if (timeval_cmp(&top->time, &this->heap[child]->time) <= 0) - { - /* the top event fires before the smaller of the two children, - * stop */ - break; - } - - /* swap with the smaller child */ - this->heap[position] = this->heap[child]; - position = child; - } - this->heap[position] = top; - } - return event; -} - -/** - * Get events from the queue and pass it to the processor - */ -static job_requeue_t schedule(private_scheduler_t * this) -{ - timeval_t now; - event_t *event; - bool timed = FALSE, oldstate; - - this->mutex->lock(this->mutex); - - time_monotonic(&now); - - if ((event = peek_event(this)) != NULL) - { - if (timeval_cmp(&now, &event->time) >= 0) - { - remove_event(this); - this->mutex->unlock(this->mutex); - DBG2(DBG_JOB, "got event, queuing job for execution"); - charon->processor->queue_job(charon->processor, event->job); - free(event); - return JOB_REQUEUE_DIRECT; - } - timersub(&event->time, &now, &now); - if (now.tv_sec) - { - DBG2(DBG_JOB, "next event in %ds %dms, waiting", - now.tv_sec, now.tv_usec/1000); - } - else - { - DBG2(DBG_JOB, "next event in %dms, waiting", now.tv_usec/1000); - } - timed = TRUE; - } - thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex); - oldstate = thread_cancelability(TRUE); - - if (timed) - { - this->condvar->timed_wait_abs(this->condvar, this->mutex, event->time); - } - else - { - DBG2(DBG_JOB, "no events, waiting"); - this->condvar->wait(this->condvar, this->mutex); - } - thread_cancelability(oldstate); - thread_cleanup_pop(TRUE); - return JOB_REQUEUE_DIRECT; -} - -/** - * Implements scheduler_t.get_job_load - */ -static u_int get_job_load(private_scheduler_t *this) -{ - int count; - this->mutex->lock(this->mutex); - count = this->event_count; - this->mutex->unlock(this->mutex); - return count; -} - -/** - * Implements scheduler_t.schedule_job_tv. - */ -static void schedule_job_tv(private_scheduler_t *this, job_t *job, timeval_t tv) -{ - event_t *event; - u_int position; - - event = malloc_thing(event_t); - event->job = job; - event->time = tv; - - this->mutex->lock(this->mutex); - - this->event_count++; - if (this->event_count > this->heap_size) - { - /* double the size of the heap */ - this->heap_size <<= 1; - this->heap = (event_t**)realloc(this->heap, - (this->heap_size + 1) * sizeof(event_t*)); - } - /* "put" the event to the bottom */ - position = this->event_count; - - /* then bubble it up */ - while (position > 1 && timeval_cmp(&this->heap[position >> 1]->time, - &event->time) > 0) - { - /* parent has to be fired after the new event, move up */ - this->heap[position] = this->heap[position >> 1]; - position >>= 1; - } - this->heap[position] = event; - - this->condvar->signal(this->condvar); - this->mutex->unlock(this->mutex); -} - -/** - * Implements scheduler_t.schedule_job. - */ -static void schedule_job(private_scheduler_t *this, job_t *job, u_int32_t s) -{ - timeval_t tv; - - time_monotonic(&tv); - tv.tv_sec += s; - - schedule_job_tv(this, job, tv); -} - -/** - * Implements scheduler_t.schedule_job_ms. - */ -static void schedule_job_ms(private_scheduler_t *this, job_t *job, u_int32_t ms) -{ - timeval_t tv, add; - - time_monotonic(&tv); - add.tv_sec = ms / 1000; - add.tv_usec = (ms % 1000) * 1000; - - timeradd(&tv, &add, &tv); - - schedule_job_tv(this, job, tv); -} - -/** - * Implementation of scheduler_t.destroy. - */ -static void destroy(private_scheduler_t *this) -{ - event_t *event; - this->job->cancel(this->job); - this->condvar->destroy(this->condvar); - this->mutex->destroy(this->mutex); - while ((event = remove_event(this)) != NULL) - { - event_destroy(event); - } - free(this->heap); - free(this); -} - -/* - * Described in header. - */ -scheduler_t * scheduler_create() -{ - private_scheduler_t *this = malloc_thing(private_scheduler_t); - - this->public.get_job_load = (u_int (*) (scheduler_t *this)) get_job_load; - this->public.schedule_job = (void (*) (scheduler_t *this, job_t *job, u_int32_t s)) schedule_job; - this->public.schedule_job_ms = (void (*) (scheduler_t *this, job_t *job, u_int32_t ms)) schedule_job_ms; - this->public.schedule_job_tv = (void (*) (scheduler_t *this, job_t *job, timeval_t tv)) schedule_job_tv; - this->public.destroy = (void(*)(scheduler_t*)) destroy; - - /* Note: the root of the heap is at index 1 */ - this->event_count = 0; - this->heap_size = HEAP_SIZE_DEFAULT; - this->heap = (event_t**)calloc(this->heap_size + 1, sizeof(event_t*)); - - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT); - - this->job = callback_job_create((callback_job_cb_t)schedule, this, NULL, NULL); - charon->processor->queue_job(charon->processor, (job_t*)this->job); - - return &this->public; -} - diff --git a/src/libcharon/processing/scheduler.h b/src/libcharon/processing/scheduler.h deleted file mode 100644 index 5f5d2a563..000000000 --- a/src/libcharon/processing/scheduler.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2009 Tobias Brunner - * Copyright (C) 2005-2007 Martin Willi - * Copyright (C) 2005 Jan Hutter - * 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 scheduler scheduler - * @{ @ingroup processing - */ - -#ifndef SCHEDULER_H_ -#define SCHEDULER_H_ - -typedef struct scheduler_t scheduler_t; - -#include <library.h> -#include <processing/jobs/job.h> - -/** - * The scheduler queues timed events which are then passed to the processor. - * - * The scheduler is implemented as a heap. A heap is a special kind of tree- - * based data structure that satisfies the following property: if B is a child - * node of A, then key(A) >= (or <=) key(B). So either the element with the - * greatest (max-heap) or the smallest (min-heap) key is the root of the heap. - * We use a min-heap whith the key being the absolute unix time at which an - * event is scheduled. So the root is always the event that will fire next. - * - * An earlier implementation of the scheduler used a sorted linked list to store - * the events. That had the advantage that removing the next event was extremely - * fast, also, adding an event scheduled before or after all other events was - * equally fast (all in O(1)). The problem was, though, that adding an event - * in-between got slower, as the number of events grew larger (O(n)). - * For each connection there could be several events: IKE-rekey, NAT-keepalive, - * retransmissions, expire (half-open), and others. So a gateway that probably - * has to handle thousands of concurrent connnections has to be able to queue a - * large number of events as fast as possible. Locking makes this even worse, to - * provide thread-safety, no events can be processed, while an event is queued, - * so making the insertion fast is even more important. - * - * That's the advantage of the heap. Adding an element to the heap can be - * achieved in O(log n) - on the other hand, removing the root node also - * requires O(log n) operations. Consider 10000 queued events. Inserting a new - * event in the list implementation required up to 10000 comparisons. In the - * heap implementation, the worst case is about 13.3 comparisons. That's a - * drastic improvement. - * - * The implementation itself uses a binary tree mapped to a one-based array to - * store the elements. This reduces storage overhead and simplifies navigation: - * the children of the node at position n are at position 2n and 2n+1 (likewise - * the parent node of the node at position n is at position [n/2]). Thus, - * navigating up and down the tree is reduced to simple index computations. - * - * Adding an element to the heap works as follows: The heap is always filled - * from left to right, until a row is full, then the next row is filled. Mapped - * to an array this gets as simple as putting the new element to the first free - * position. In a one-based array that position equals the number of elements - * currently stored in the heap. Then the heap property has to be restored, i.e. - * the new element has to be "bubbled up" the tree until the parent node's key - * is smaller or the element got the new root of the tree. - * - * Removing the next event from the heap works similarly. The event itself is - * the root node and stored at position 1 of the array. After removing it, the - * root has to be replaced and the heap property has to be restored. This is - * done by moving the bottom element (last row, rightmost element) to the root - * and then "seep it down" by swapping it with child nodes until none of the - * children has a smaller key or it is again a leaf node. - */ -struct scheduler_t { - - /** - * Adds a event to the queue, using a relative time offset in s. - * - * @param job job to schedule - * @param time relative time to schedule job, in s - */ - void (*schedule_job) (scheduler_t *this, job_t *job, u_int32_t s); - - /** - * Adds a event to the queue, using a relative time offset in ms. - * - * @param job job to schedule - * @param time relative time to schedule job, in ms - */ - void (*schedule_job_ms) (scheduler_t *this, job_t *job, u_int32_t ms); - - /** - * Adds a event to the queue, using an absolut time. - * - * The passed timeval should be calculated based on the time_monotonic() - * function. - * - * @param job job to schedule - * @param time absolut time to schedule job - */ - void (*schedule_job_tv) (scheduler_t *this, job_t *job, timeval_t tv); - - /** - * Returns number of jobs scheduled. - * - * @return number of scheduled jobs - */ - u_int (*get_job_load) (scheduler_t *this); - - /** - * Destroys a scheduler object. - */ - void (*destroy) (scheduler_t *this); -}; - -/** - * Create a scheduler. - * - * @return scheduler_t object - */ -scheduler_t *scheduler_create(void); - -#endif /** SCHEDULER_H_ @}*/ diff --git a/src/libcharon/sa/authenticators/eap/eap_manager.c b/src/libcharon/sa/authenticators/eap/eap_manager.c index f795183f0..bc2c4a617 100644 --- a/src/libcharon/sa/authenticators/eap/eap_manager.c +++ b/src/libcharon/sa/authenticators/eap/eap_manager.c @@ -68,12 +68,9 @@ struct private_eap_manager_t { rwlock_t *lock; }; -/** - * Implementation of eap_manager_t.add_method. - */ -static void add_method(private_eap_manager_t *this, eap_type_t type, - u_int32_t vendor, eap_role_t role, - eap_constructor_t constructor) +METHOD(eap_manager_t, add_method, void, + private_eap_manager_t *this, eap_type_t type, u_int32_t vendor, + eap_role_t role, eap_constructor_t constructor) { eap_entry_t *entry = malloc_thing(eap_entry_t); @@ -87,10 +84,8 @@ static void add_method(private_eap_manager_t *this, eap_type_t type, this->lock->unlock(this->lock); } -/** - * Implementation of eap_manager_t.remove_method. - */ -static void remove_method(private_eap_manager_t *this, eap_constructor_t constructor) +METHOD(eap_manager_t, remove_method, void, + private_eap_manager_t *this, eap_constructor_t constructor) { enumerator_t *enumerator; eap_entry_t *entry; @@ -109,13 +104,9 @@ static void remove_method(private_eap_manager_t *this, eap_constructor_t constru this->lock->unlock(this->lock); } -/** - * Implementation of eap_manager_t.create_instance. - */ -static eap_method_t* create_instance(private_eap_manager_t *this, - eap_type_t type, u_int32_t vendor, - eap_role_t role, identification_t *server, - identification_t *peer) +METHOD(eap_manager_t, create_instance, eap_method_t*, + private_eap_manager_t *this, eap_type_t type, u_int32_t vendor, + eap_role_t role, identification_t *server, identification_t *peer) { enumerator_t *enumerator; eap_entry_t *entry; @@ -140,10 +131,8 @@ static eap_method_t* create_instance(private_eap_manager_t *this, return method; } -/** - * Implementation of 2008_t.destroy - */ -static void destroy(private_eap_manager_t *this) +METHOD(eap_manager_t, destroy, void, + private_eap_manager_t *this) { this->methods->destroy_function(this->methods, free); this->lock->destroy(this->lock); @@ -151,19 +140,22 @@ static void destroy(private_eap_manager_t *this) } /* - * see header file + * See header */ eap_manager_t *eap_manager_create() { - private_eap_manager_t *this = malloc_thing(private_eap_manager_t); - - this->public.add_method = (void(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, eap_constructor_t constructor))add_method; - this->public.remove_method = (void(*)(eap_manager_t*, eap_constructor_t constructor))remove_method; - this->public.create_instance = (eap_method_t*(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, identification_t*,identification_t*))create_instance; - this->public.destroy = (void(*)(eap_manager_t*))destroy; - - this->methods = linked_list_create(); - this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); + private_eap_manager_t *this; + + INIT(this, + .public = { + .add_method = _add_method, + .remove_method = _remove_method, + .create_instance = _create_instance, + .destroy = _destroy, + }, + .methods = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); return &this->public; } diff --git a/src/libcharon/sa/authenticators/eap/eap_method.c b/src/libcharon/sa/authenticators/eap/eap_method.c index ad7b92cfa..0fa4a00c5 100644 --- a/src/libcharon/sa/authenticators/eap/eap_method.c +++ b/src/libcharon/sa/authenticators/eap/eap_method.c @@ -15,55 +15,8 @@ #include "eap_method.h" -/* - * See header - */ -eap_type_t eap_type_from_string(char *name) -{ - int i; - static struct { - char *name; - eap_type_t type; - } types[] = { - {"identity", EAP_IDENTITY}, - {"md5", EAP_MD5}, - {"otp", EAP_OTP}, - {"gtc", EAP_GTC}, - {"sim", EAP_SIM}, - {"aka", EAP_AKA}, - {"mschapv2", EAP_MSCHAPV2}, - {"radius", EAP_RADIUS}, - }; - - for (i = 0; i < countof(types); i++) - { - if (strcaseeq(name, types[i].name)) - { - return types[i].type; - } - } - return 0; -} - -ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE, - "EAP_REQUEST", - "EAP_RESPONSE", - "EAP_SUCCESS", - "EAP_FAILURE", -); - -ENUM(eap_code_short_names, EAP_REQUEST, EAP_FAILURE, - "REQ", - "RES", - "SUCC", - "FAIL", -); - ENUM(eap_role_names, EAP_SERVER, EAP_PEER, "EAP_SERVER", "EAP_PEER", ); - - - diff --git a/src/libcharon/sa/authenticators/eap/eap_method.h b/src/libcharon/sa/authenticators/eap/eap_method.h index df354edb4..9961039ff 100644 --- a/src/libcharon/sa/authenticators/eap/eap_method.h +++ b/src/libcharon/sa/authenticators/eap/eap_method.h @@ -23,10 +23,10 @@ typedef struct eap_method_t eap_method_t; typedef enum eap_role_t eap_role_t; -typedef enum eap_code_t eap_code_t; #include <library.h> #include <utils/identification.h> +#include <eap/eap.h> #include <encoding/payloads/eap_payload.h> /** @@ -42,34 +42,6 @@ enum eap_role_t { extern enum_name_t *eap_role_names; /** - * Lookup the EAP method type from a string. - * - * @param name EAP method name (such as "md5", "aka") - * @return method type, 0 if unkown - */ -eap_type_t eap_type_from_string(char *name); - -/** - * EAP code, type of an EAP message - */ -enum eap_code_t { - EAP_REQUEST = 1, - EAP_RESPONSE = 2, - EAP_SUCCESS = 3, - EAP_FAILURE = 4, -}; - -/** - * enum names for eap_code_t. - */ -extern enum_name_t *eap_code_names; - -/** - * short string enum names for eap_code_t. - */ -extern enum_name_t *eap_code_short_names; - -/** * Interface of an EAP method for server and client side. * * An EAP method initiates an EAP exchange and processes requests and diff --git a/src/libcharon/sa/authenticators/eap_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c index 3c0f3c358..8b22fd1d7 100644 --- a/src/libcharon/sa/authenticators/eap_authenticator.c +++ b/src/libcharon/sa/authenticators/eap_authenticator.c @@ -99,22 +99,30 @@ struct private_eap_authenticator_t { static eap_method_t *load_method(private_eap_authenticator_t *this, eap_type_t type, u_int32_t vendor, eap_role_t role) { - identification_t *server, *peer; + identification_t *server, *peer, *aaa; + auth_cfg_t *auth; if (role == EAP_SERVER) { server = this->ike_sa->get_my_id(this->ike_sa); peer = this->ike_sa->get_other_id(this->ike_sa); + auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); } else { server = this->ike_sa->get_other_id(this->ike_sa); peer = this->ike_sa->get_my_id(this->ike_sa); + auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); } if (this->eap_identity) { peer = this->eap_identity; } + aaa = auth->get(auth, AUTH_RULE_AAA_IDENTITY); + if (aaa) + { + server = aaa; + } return charon->eap->create_instance(charon->eap, type, vendor, role, server, peer); } @@ -458,11 +466,8 @@ static void build_auth(private_eap_authenticator_t *this, message_t *message, chunk_free(&auth_data); } -/** - * Implementation of authenticator_t.process for a server - */ -static status_t process_server(private_eap_authenticator_t *this, - message_t *message) +METHOD(authenticator_t, process_server, status_t, + private_eap_authenticator_t *this, message_t *message) { eap_payload_t *eap_payload; @@ -492,11 +497,8 @@ static status_t process_server(private_eap_authenticator_t *this, return NEED_MORE; } -/** - * Implementation of authenticator_t.build for a server - */ -static status_t build_server(private_eap_authenticator_t *this, - message_t *message) +METHOD(authenticator_t, build_server, status_t, + private_eap_authenticator_t *this, message_t *message) { if (this->eap_payload) { @@ -519,11 +521,8 @@ static status_t build_server(private_eap_authenticator_t *this, return FAILED; } -/** - * Implementation of authenticator_t.process for a client - */ -static status_t process_client(private_eap_authenticator_t *this, - message_t *message) +METHOD(authenticator_t, process_client, status_t, + private_eap_authenticator_t *this, message_t *message) { eap_payload_t *eap_payload; @@ -603,11 +602,8 @@ static status_t process_client(private_eap_authenticator_t *this, return FAILED; } -/** - * Implementation of authenticator_t.build for a client - */ -static status_t build_client(private_eap_authenticator_t *this, - message_t *message) +METHOD(authenticator_t, build_client, status_t, + private_eap_authenticator_t *this, message_t *message) { if (this->eap_payload) { @@ -623,20 +619,16 @@ static status_t build_client(private_eap_authenticator_t *this, return NEED_MORE; } -/** - * Implementation of authenticator_t.is_mutual. - */ -static bool is_mutual(private_eap_authenticator_t *this) +METHOD(authenticator_t, is_mutual, bool, + private_eap_authenticator_t *this) { /* we don't know yet, but insist on it after EAP is complete */ this->require_mutual = TRUE; return TRUE; } -/** - * Implementation of authenticator_t.destroy. - */ -static void destroy(private_eap_authenticator_t *this) +METHOD(authenticator_t, destroy, void, + private_eap_authenticator_t *this) { DESTROY_IF(this->method); DESTROY_IF(this->eap_payload); @@ -652,25 +644,23 @@ eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_nonce, chunk_t received_init, chunk_t sent_init) { - private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t); - - this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build_client; - this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_client; - this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))is_mutual; - this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy; - - this->ike_sa = ike_sa; - this->received_init = received_init; - this->received_nonce = received_nonce; - this->sent_init = sent_init; - this->sent_nonce = sent_nonce; - this->msk = chunk_empty; - this->method = NULL; - this->eap_payload = NULL; - this->eap_complete = FALSE; - this->auth_complete = FALSE; - this->eap_identity = NULL; - this->require_mutual = FALSE; + private_eap_authenticator_t *this; + + INIT(this, + .public = { + .authenticator = { + .build = _build_client, + .process = _process_client, + .is_mutual = _is_mutual, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .received_init = received_init, + .received_nonce = received_nonce, + .sent_init = sent_init, + .sent_nonce = sent_nonce, + ); return &this->public; } @@ -682,25 +672,23 @@ eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_nonce, chunk_t received_init, chunk_t sent_init) { - private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t); - - this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *messageh))build_server; - this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_server; - this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))is_mutual; - this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy; - - this->ike_sa = ike_sa; - this->received_init = received_init; - this->received_nonce = received_nonce; - this->sent_init = sent_init; - this->sent_nonce = sent_nonce; - this->msk = chunk_empty; - this->method = NULL; - this->eap_payload = NULL; - this->eap_complete = FALSE; - this->auth_complete = FALSE; - this->eap_identity = NULL; - this->require_mutual = FALSE; + private_eap_authenticator_t *this; + + INIT(this, + .public = { + .authenticator = { + .build = _build_server, + .process = _process_server, + .is_mutual = _is_mutual, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .received_init = received_init, + .received_nonce = received_nonce, + .sent_init = sent_init, + .sent_nonce = sent_nonce, + ); return &this->public; } diff --git a/src/libcharon/sa/authenticators/pubkey_authenticator.c b/src/libcharon/sa/authenticators/pubkey_authenticator.c index 3c67f6db6..54b4338bb 100644 --- a/src/libcharon/sa/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/authenticators/pubkey_authenticator.c @@ -84,15 +84,15 @@ static status_t build(private_pubkey_authenticator_t *this, message_t *message) /* we try to deduct the signature scheme from the keysize */ switch (private->get_keysize(private)) { - case 32: + case 256: scheme = SIGN_ECDSA_256; auth_method = AUTH_ECDSA_256; break; - case 48: + case 384: scheme = SIGN_ECDSA_384; auth_method = AUTH_ECDSA_384; break; - case 66: + case 521: scheme = SIGN_ECDSA_521; auth_method = AUTH_ECDSA_521; break; diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index bd41cba56..b6ef31da0 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 Tobias Brunner + * Copyright (C) 2006-2010 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005 Jan Hutter @@ -23,6 +23,7 @@ #include <string.h> #include <time.h> +#include <hydra.h> #include <daemon.h> ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING, @@ -179,170 +180,144 @@ struct private_child_sa_t { }; /** - * Implementation of child_sa_t.get_name + * convert an IKEv2 specific protocol identifier to the IP protocol identifier. */ -static char *get_name(private_child_sa_t *this) +static inline u_int8_t proto_ike2ip(protocol_id_t protocol) +{ + switch (protocol) + { + case PROTO_ESP: + return IPPROTO_ESP; + case PROTO_AH: + return IPPROTO_AH; + default: + return protocol; + } +} + +METHOD(child_sa_t, get_name, char*, + private_child_sa_t *this) { return this->config->get_name(this->config); } -/** - * Implements child_sa_t.get_reqid - */ -static u_int32_t get_reqid(private_child_sa_t *this) +METHOD(child_sa_t, get_reqid, u_int32_t, + private_child_sa_t *this) { return this->reqid; } -/** - * Implements child_sa_t.get_config - */ -static child_cfg_t* get_config(private_child_sa_t *this) +METHOD(child_sa_t, get_config, child_cfg_t*, + private_child_sa_t *this) { return this->config; } -/** - * Implements child_sa_t.set_state - */ -static void set_state(private_child_sa_t *this, child_sa_state_t state) +METHOD(child_sa_t, set_state, void, + private_child_sa_t *this, child_sa_state_t state) { charon->bus->child_state_change(charon->bus, &this->public, state); this->state = state; } -/** - * Implements child_sa_t.get_state - */ -static child_sa_state_t get_state(private_child_sa_t *this) +METHOD(child_sa_t, get_state, child_sa_state_t, + private_child_sa_t *this) { return this->state; } -/** - * Implements child_sa_t.get_spi - */ -u_int32_t get_spi(private_child_sa_t *this, bool inbound) +METHOD(child_sa_t, get_spi, u_int32_t, + private_child_sa_t *this, bool inbound) { return inbound ? this->my_spi : this->other_spi; } -/** - * Implements child_sa_t.get_cpi - */ -u_int16_t get_cpi(private_child_sa_t *this, bool inbound) +METHOD(child_sa_t, get_cpi, u_int16_t, + private_child_sa_t *this, bool inbound) { return inbound ? this->my_cpi : this->other_cpi; } -/** - * Implements child_sa_t.get_protocol - */ -protocol_id_t get_protocol(private_child_sa_t *this) +METHOD(child_sa_t, get_protocol, protocol_id_t, + private_child_sa_t *this) { return this->protocol; } -/** - * Implementation of child_sa_t.set_protocol - */ -static void set_protocol(private_child_sa_t *this, protocol_id_t protocol) +METHOD(child_sa_t, set_protocol, void, + private_child_sa_t *this, protocol_id_t protocol) { this->protocol = protocol; } -/** - * Implementation of child_sa_t.get_mode - */ -static ipsec_mode_t get_mode(private_child_sa_t *this) +METHOD(child_sa_t, get_mode, ipsec_mode_t, + private_child_sa_t *this) { return this->mode; } -/** - * Implementation of child_sa_t.set_mode - */ -static void set_mode(private_child_sa_t *this, ipsec_mode_t mode) +METHOD(child_sa_t, set_mode, void, + private_child_sa_t *this, ipsec_mode_t mode) { this->mode = mode; } -/** - * Implementation of child_sa_t.has_encap - */ -static bool has_encap(private_child_sa_t *this) +METHOD(child_sa_t, has_encap, bool, + private_child_sa_t *this) { return this->encap; } -/** - * Implementation of child_sa_t.get_ipcomp - */ -static ipcomp_transform_t get_ipcomp(private_child_sa_t *this) +METHOD(child_sa_t, get_ipcomp, ipcomp_transform_t, + private_child_sa_t *this) { return this->ipcomp; } -/** - * Implementation of child_sa_t.set_ipcomp. - */ -static void set_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp) +METHOD(child_sa_t, set_ipcomp, void, + private_child_sa_t *this, ipcomp_transform_t ipcomp) { this->ipcomp = ipcomp; } -/** - * Implementation of child_sa_t.set_close_action. - */ -static void set_close_action(private_child_sa_t *this, action_t action) +METHOD(child_sa_t, set_close_action, void, + private_child_sa_t *this, action_t action) { this->close_action = action; } -/** - * Implementation of child_sa_t.get_close_action. - */ -static action_t get_close_action(private_child_sa_t *this) +METHOD(child_sa_t, get_close_action, action_t, + private_child_sa_t *this) { return this->close_action; } -/** - * Implementation of child_sa_t.set_dpd_action. - */ -static void set_dpd_action(private_child_sa_t *this, action_t action) +METHOD(child_sa_t, set_dpd_action, void, + private_child_sa_t *this, action_t action) { this->dpd_action = action; } -/** - * Implementation of child_sa_t.get_dpd_action. - */ -static action_t get_dpd_action(private_child_sa_t *this) +METHOD(child_sa_t, get_dpd_action, action_t, + private_child_sa_t *this) { return this->dpd_action; } -/** - * Implementation of child_sa_t.get_proposal - */ -static proposal_t* get_proposal(private_child_sa_t *this) +METHOD(child_sa_t, get_proposal, proposal_t*, + private_child_sa_t *this) { return this->proposal; } -/** - * Implementation of child_sa_t.set_proposal - */ -static void set_proposal(private_child_sa_t *this, proposal_t *proposal) +METHOD(child_sa_t, set_proposal, void, + private_child_sa_t *this, proposal_t *proposal) { this->proposal = proposal->clone(proposal); } -/** - * Implementation of child_sa_t.get_traffic_selectors. - */ -static linked_list_t *get_traffic_selectors(private_child_sa_t *this, bool local) +METHOD(child_sa_t, get_traffic_selectors, linked_list_t*, + private_child_sa_t *this, bool local) { return local ? this->my_ts : this->other_ts; } @@ -365,11 +340,9 @@ struct policy_enumerator_t { traffic_selector_t *ts; }; -/** - * enumerator function of create_policy_enumerator() - */ -static bool policy_enumerate(policy_enumerator_t *this, - traffic_selector_t **my_out, traffic_selector_t **other_out) +METHOD(enumerator_t, policy_enumerate, bool, + policy_enumerator_t *this, traffic_selector_t **my_out, + traffic_selector_t **other_out) { traffic_selector_t *other_ts; @@ -399,29 +372,29 @@ static bool policy_enumerate(policy_enumerator_t *this, return FALSE; } -/** - * destroy function of create_policy_enumerator() - */ -static void policy_destroy(policy_enumerator_t *this) +METHOD(enumerator_t, policy_destroy, void, + policy_enumerator_t *this) { this->mine->destroy(this->mine); this->other->destroy(this->other); free(this); } -/** - * Implementation of child_sa_t.create_policy_enumerator - */ -static enumerator_t* create_policy_enumerator(private_child_sa_t *this) +METHOD(child_sa_t, create_policy_enumerator, enumerator_t*, + private_child_sa_t *this) { - policy_enumerator_t *e = malloc_thing(policy_enumerator_t); - - e->public.enumerate = (void*)policy_enumerate; - e->public.destroy = (void*)policy_destroy; - e->mine = this->my_ts->create_enumerator(this->my_ts); - e->other = this->other_ts->create_enumerator(this->other_ts); - e->list = this->other_ts; - e->ts = NULL; + policy_enumerator_t *e; + + INIT(e, + .public = { + .enumerate = (void*)_policy_enumerate, + .destroy = _policy_destroy, + }, + .mine = this->my_ts->create_enumerator(this->my_ts), + .other = this->other_ts->create_enumerator(this->other_ts), + .list = this->other_ts, + .ts = NULL, + ); return &e->public; } @@ -441,10 +414,10 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound) { if (this->my_spi) { - status = charon->kernel_interface->query_sa(charon->kernel_interface, - this->other_addr, this->my_addr, - this->my_spi, this->protocol, - this->mark_in, &bytes); + status = hydra->kernel_interface->query_sa(hydra->kernel_interface, + this->other_addr, this->my_addr, this->my_spi, + proto_ike2ip(this->protocol), this->mark_in, + &bytes); if (status == SUCCESS) { if (bytes > this->my_usebytes) @@ -460,10 +433,10 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound) { if (this->other_spi) { - status = charon->kernel_interface->query_sa(charon->kernel_interface, - this->my_addr, this->other_addr, - this->other_spi, this->protocol, - this->mark_out, &bytes); + status = hydra->kernel_interface->query_sa(hydra->kernel_interface, + this->my_addr, this->other_addr, this->other_spi, + proto_ike2ip(this->protocol), this->mark_out, + &bytes); if (status == SUCCESS) { if (bytes > this->other_usebytes) @@ -494,14 +467,14 @@ static void update_usetime(private_child_sa_t *this, bool inbound) if (inbound) { - if (charon->kernel_interface->query_policy(charon->kernel_interface, + if (hydra->kernel_interface->query_policy(hydra->kernel_interface, other_ts, my_ts, POLICY_IN, this->mark_in, &in) == SUCCESS) { last_use = max(last_use, in); } if (this->mode != MODE_TRANSPORT) { - if (charon->kernel_interface->query_policy(charon->kernel_interface, + if (hydra->kernel_interface->query_policy(hydra->kernel_interface, other_ts, my_ts, POLICY_FWD, this->mark_in, &fwd) == SUCCESS) { last_use = max(last_use, fwd); @@ -510,7 +483,7 @@ static void update_usetime(private_child_sa_t *this, bool inbound) } else { - if (charon->kernel_interface->query_policy(charon->kernel_interface, + if (hydra->kernel_interface->query_policy(hydra->kernel_interface, my_ts, other_ts, POLICY_OUT, this->mark_out, &out) == SUCCESS) { last_use = max(last_use, out); @@ -533,11 +506,8 @@ static void update_usetime(private_child_sa_t *this, bool inbound) } } -/** - * Implementation of child_sa_t.get_usestats - */ -static void get_usestats(private_child_sa_t *this, bool inbound, - time_t *time, u_int64_t *bytes) +METHOD(child_sa_t, get_usestats, void, + private_child_sa_t *this, bool inbound, time_t *time, u_int64_t *bytes) { if (update_usebytes(this, inbound) != FAILED) { @@ -556,48 +526,41 @@ static void get_usestats(private_child_sa_t *this, bool inbound, } } -/** - * Implementation of child_sa_t.get_lifetime - */ -static time_t get_lifetime(private_child_sa_t *this, bool hard) +METHOD(child_sa_t, get_lifetime, time_t, + private_child_sa_t *this, bool hard) { return hard ? this->expire_time : this->rekey_time; } -/** - * Implementation of child_sa_t.alloc_spi - */ -static u_int32_t alloc_spi(private_child_sa_t *this, protocol_id_t protocol) +METHOD(child_sa_t, alloc_spi, u_int32_t, + private_child_sa_t *this, protocol_id_t protocol) { - if (charon->kernel_interface->get_spi(charon->kernel_interface, - this->other_addr, this->my_addr, protocol, - this->reqid, &this->my_spi) == SUCCESS) + if (hydra->kernel_interface->get_spi(hydra->kernel_interface, + this->other_addr, this->my_addr, + proto_ike2ip(protocol), this->reqid, + &this->my_spi) == SUCCESS) { return this->my_spi; } return 0; } -/** - * Implementation of child_sa_t.alloc_cpi - */ -static u_int16_t alloc_cpi(private_child_sa_t *this) +METHOD(child_sa_t, alloc_cpi, u_int16_t, + private_child_sa_t *this) { - if (charon->kernel_interface->get_cpi(charon->kernel_interface, - this->other_addr, this->my_addr, this->reqid, - &this->my_cpi) == SUCCESS) + if (hydra->kernel_interface->get_cpi(hydra->kernel_interface, + this->other_addr, this->my_addr, + this->reqid, &this->my_cpi) == SUCCESS) { return this->my_cpi; } return 0; } -/** - * Implementation of child_sa_t.install - */ -static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ, - u_int32_t spi, u_int16_t cpi, bool inbound, - linked_list_t *my_ts, linked_list_t *other_ts) +METHOD(child_sa_t, install, status_t, + private_child_sa_t *this, chunk_t encr, chunk_t integ, u_int32_t spi, + u_int16_t cpi, bool inbound, linked_list_t *my_ts, + linked_list_t *other_ts) { u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size; traffic_selector_t *src_ts = NULL, *dst_ts = NULL; @@ -674,8 +637,8 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ, } } - status = charon->kernel_interface->add_sa(charon->kernel_interface, - src, dst, spi, this->protocol, this->reqid, + status = hydra->kernel_interface->add_sa(hydra->kernel_interface, + src, dst, spi, proto_ike2ip(this->protocol), this->reqid, inbound ? this->mark_in : this->mark_out, lifetime, enc_alg, encr, int_alg, integ, this->mode, this->ipcomp, cpi, this->encap, update, src_ts, dst_ts); @@ -685,11 +648,9 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ, return status; } -/** - * Implementation of child_sa_t.add_policies - */ -static status_t add_policies(private_child_sa_t *this, - linked_list_t *my_ts_list, linked_list_t *other_ts_list) +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) { enumerator_t *enumerator; traffic_selector_t *my_ts, *other_ts; @@ -712,26 +673,55 @@ static status_t add_policies(private_child_sa_t *this, if (this->config->install_policy(this->config)) { + ipsec_sa_cfg_t my_sa = { + .mode = this->mode, + .reqid = this->reqid, + .ipcomp = { + .transform = this->ipcomp, + }, + }, other_sa = my_sa; + + my_sa.ipcomp.cpi = this->my_cpi; + other_sa.ipcomp.cpi = this->other_cpi; + + if (this->protocol == PROTO_ESP) + { + my_sa.esp.use = TRUE; + my_sa.esp.spi = this->my_spi; + other_sa.esp.use = TRUE; + other_sa.esp.spi = this->other_spi; + } + else + { + my_sa.ah.use = TRUE; + my_sa.ah.spi = this->my_spi; + other_sa.ah.use = TRUE; + other_sa.ah.spi = this->other_spi; + } + /* 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 |= charon->kernel_interface->add_policy(charon->kernel_interface, - this->my_addr, this->other_addr, my_ts, other_ts, POLICY_OUT, - this->other_spi, this->protocol, this->reqid, this->mark_out, - this->mode, this->ipcomp, this->other_cpi, routed); - - status |= charon->kernel_interface->add_policy(charon->kernel_interface, - this->other_addr, this->my_addr, other_ts, my_ts, POLICY_IN, - this->my_spi, this->protocol, this->reqid, this->mark_in, - this->mode, this->ipcomp, this->my_cpi, routed); + 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) { - status |= charon->kernel_interface->add_policy(charon->kernel_interface, - this->other_addr, this->my_addr, other_ts, my_ts, POLICY_FWD, - this->my_spi, this->protocol, this->reqid, this->mark_in, - this->mode, this->ipcomp, this->my_cpi, routed); + 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); } if (status != SUCCESS) @@ -749,11 +739,9 @@ static status_t add_policies(private_child_sa_t *this, return status; } -/** - * Implementation of child_sa_t.update. - */ -static status_t update(private_child_sa_t *this, host_t *me, host_t *other, - host_t *vip, bool encap) +METHOD(child_sa_t, update, status_t, + private_child_sa_t *this, host_t *me, host_t *other, host_t *vip, + bool encap) { child_sa_state_t old; bool transport_proxy_mode; @@ -775,8 +763,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other, /* update our (initator) SA */ if (this->my_spi) { - if (charon->kernel_interface->update_sa(charon->kernel_interface, - this->my_spi, this->protocol, + if (hydra->kernel_interface->update_sa(hydra->kernel_interface, + this->my_spi, proto_ike2ip(this->protocol), this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0, this->other_addr, this->my_addr, other, me, this->encap, encap, this->mark_in) == NOT_SUPPORTED) @@ -788,8 +776,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other, /* update his (responder) SA */ if (this->other_spi) { - if (charon->kernel_interface->update_sa(charon->kernel_interface, - this->other_spi, this->protocol, + if (hydra->kernel_interface->update_sa(hydra->kernel_interface, + this->other_spi, proto_ike2ip(this->protocol), this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0, this->my_addr, this->other_addr, me, other, this->encap, encap, this->mark_out) == NOT_SUPPORTED) @@ -801,6 +789,32 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other, if (this->config->install_policy(this->config)) { + ipsec_sa_cfg_t my_sa = { + .mode = this->mode, + .reqid = this->reqid, + .ipcomp = { + .transform = this->ipcomp, + }, + }, other_sa = my_sa; + + my_sa.ipcomp.cpi = this->my_cpi; + other_sa.ipcomp.cpi = this->other_cpi; + + if (this->protocol == PROTO_ESP) + { + my_sa.esp.use = TRUE; + my_sa.esp.spi = this->my_spi; + other_sa.esp.use = TRUE; + other_sa.esp.spi = this->other_spi; + } + else + { + my_sa.ah.use = TRUE; + my_sa.ah.spi = this->my_spi; + other_sa.ah.use = TRUE; + other_sa.ah.spi = this->other_spi; + } + /* update policies */ if (!me->ip_equals(me, this->my_addr) || !other->ip_equals(other, this->other_addr)) @@ -813,13 +827,13 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other, while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { /* remove old policies first */ - charon->kernel_interface->del_policy(charon->kernel_interface, + hydra->kernel_interface->del_policy(hydra->kernel_interface, my_ts, other_ts, POLICY_OUT, this->mark_out, FALSE); - charon->kernel_interface->del_policy(charon->kernel_interface, + hydra->kernel_interface->del_policy(hydra->kernel_interface, other_ts, my_ts, POLICY_IN, this->mark_in, FALSE); if (this->mode != MODE_TRANSPORT) { - charon->kernel_interface->del_policy(charon->kernel_interface, + hydra->kernel_interface->del_policy(hydra->kernel_interface, other_ts, my_ts, POLICY_FWD, this->mark_in, FALSE); } @@ -839,25 +853,22 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other, * correctly */ if (vip) { - charon->kernel_interface->del_ip(charon->kernel_interface, vip); - charon->kernel_interface->add_ip(charon->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 */ - charon->kernel_interface->add_policy(charon->kernel_interface, - me, other, my_ts, other_ts, POLICY_OUT, this->other_spi, - this->protocol, this->reqid, this->mark_out, this->mode, - this->ipcomp, this->other_cpi, FALSE); - charon->kernel_interface->add_policy(charon->kernel_interface, - other, me, other_ts, my_ts, POLICY_IN, this->my_spi, - this->protocol, this->reqid, this->mark_in, this->mode, - this->ipcomp, this->my_cpi, FALSE); + 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) { - charon->kernel_interface->add_policy(charon->kernel_interface, - other, me, other_ts, my_ts, POLICY_FWD, this->my_spi, - this->protocol, this->reqid, this->mark_in, this->mode, - this->ipcomp, this->my_cpi, FALSE); + hydra->kernel_interface->add_policy(hydra->kernel_interface, + other, me, other_ts, my_ts, POLICY_FWD, POLICY_IPSEC, + &my_sa, this->mark_in, FALSE); } } enumerator->destroy(enumerator); @@ -885,10 +896,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other, return SUCCESS; } -/** - * Implementation of child_sa_t.destroy. - */ -static void destroy(private_child_sa_t *this) +METHOD(child_sa_t, destroy, void, + private_child_sa_t *this) { enumerator_t *enumerator; traffic_selector_t *my_ts, *other_ts; @@ -905,15 +914,17 @@ static void destroy(private_child_sa_t *this) { this->protocol = PROTO_ESP; } - charon->kernel_interface->del_sa(charon->kernel_interface, + hydra->kernel_interface->del_sa(hydra->kernel_interface, this->other_addr, this->my_addr, this->my_spi, - this->protocol, this->my_cpi, this->mark_in); + proto_ike2ip(this->protocol), this->my_cpi, + this->mark_in); } if (this->other_spi) { - charon->kernel_interface->del_sa(charon->kernel_interface, + hydra->kernel_interface->del_sa(hydra->kernel_interface, this->my_addr, this->other_addr, this->other_spi, - this->protocol, this->other_cpi, this->mark_out); + proto_ike2ip(this->protocol), this->other_cpi, + this->mark_out); } if (this->config->install_policy(this->config)) @@ -922,14 +933,14 @@ static void destroy(private_child_sa_t *this) enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { - charon->kernel_interface->del_policy(charon->kernel_interface, - my_ts, other_ts, POLICY_OUT, this->mark_out, unrouted); - charon->kernel_interface->del_policy(charon->kernel_interface, - other_ts, my_ts, POLICY_IN, this->mark_in, unrouted); + 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) { - charon->kernel_interface->del_policy(charon->kernel_interface, - other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted); + hydra->kernel_interface->del_policy(hydra->kernel_interface, + other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted); } } enumerator->destroy(enumerator); @@ -944,75 +955,66 @@ static void destroy(private_child_sa_t *this) free(this); } -/* +/** * Described in header. */ child_sa_t * child_sa_create(host_t *me, host_t* other, child_cfg_t *config, u_int32_t rekey, bool encap) { static u_int32_t reqid = 0; - private_child_sa_t *this = malloc_thing(private_child_sa_t); - - /* public functions */ - this->public.get_name = (char*(*)(child_sa_t*))get_name; - this->public.get_reqid = (u_int32_t(*)(child_sa_t*))get_reqid; - this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config; - this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state; - this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state; - this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi; - this->public.get_cpi = (u_int16_t(*)(child_sa_t*, bool))get_cpi; - this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol; - this->public.set_protocol = (void(*)(child_sa_t*, protocol_id_t protocol))set_protocol; - this->public.get_mode = (ipsec_mode_t(*)(child_sa_t*))get_mode; - this->public.set_mode = (void(*)(child_sa_t*, ipsec_mode_t mode))set_mode; - this->public.get_proposal = (proposal_t*(*)(child_sa_t*))get_proposal; - this->public.set_proposal = (void(*)(child_sa_t*, proposal_t *proposal))set_proposal; - this->public.get_lifetime = (time_t(*)(child_sa_t*, bool))get_lifetime; - this->public.get_usestats = (void(*)(child_sa_t*,bool,time_t*,u_int64_t*))get_usestats; - this->public.has_encap = (bool(*)(child_sa_t*))has_encap; - this->public.get_ipcomp = (ipcomp_transform_t(*)(child_sa_t*))get_ipcomp; - this->public.set_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t))set_ipcomp; - this->public.get_close_action = (action_t(*)(child_sa_t*))get_close_action; - this->public.set_close_action = (void(*)(child_sa_t*,action_t))set_close_action; - this->public.get_dpd_action = (action_t(*)(child_sa_t*))get_dpd_action; - this->public.set_dpd_action = (void(*)(child_sa_t*,action_t))set_dpd_action; - this->public.alloc_spi = (u_int32_t(*)(child_sa_t*, protocol_id_t protocol))alloc_spi; - this->public.alloc_cpi = (u_int16_t(*)(child_sa_t*))alloc_cpi; - this->public.install = (status_t(*)(child_sa_t*, chunk_t encr, chunk_t integ, u_int32_t spi, u_int16_t cpi, bool inbound, linked_list_t *my_ts_list, linked_list_t *other_ts_list))install; - this->public.update = (status_t (*)(child_sa_t*,host_t*,host_t*,host_t*,bool))update; - this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*))add_policies; - this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors; - this->public.create_policy_enumerator = (enumerator_t*(*)(child_sa_t*))create_policy_enumerator; - this->public.destroy = (void(*)(child_sa_t*))destroy; - - /* private data */ - this->my_addr = me->clone(me); - this->other_addr = other->clone(other); - this->my_spi = 0; - this->other_spi = 0; - this->my_cpi = 0; - this->other_cpi = 0; - this->encap = encap; - this->ipcomp = IPCOMP_NONE; - this->state = CHILD_CREATED; - this->my_usetime = 0; - this->other_usetime = 0; - this->my_usebytes = 0; - this->other_usebytes = 0; - this->my_ts = linked_list_create(); - this->other_ts = linked_list_create(); - this->protocol = PROTO_NONE; - this->mode = MODE_TUNNEL; - this->close_action = config->get_close_action(config); - this->dpd_action = config->get_dpd_action(config); - this->proposal = NULL; - this->rekey_time = 0; - this->expire_time = 0; + private_child_sa_t *this; + + INIT(this, + .public = { + .get_name = _get_name, + .get_reqid = _get_reqid, + .get_config = _get_config, + .get_state = _get_state, + .set_state = _set_state, + .get_spi = _get_spi, + .get_cpi = _get_cpi, + .get_protocol = _get_protocol, + .set_protocol = _set_protocol, + .get_mode = _get_mode, + .set_mode = _set_mode, + .get_proposal = _get_proposal, + .set_proposal = _set_proposal, + .get_lifetime = _get_lifetime, + .get_usestats = _get_usestats, + .has_encap = _has_encap, + .get_ipcomp = _get_ipcomp, + .set_ipcomp = _set_ipcomp, + .get_close_action = _get_close_action, + .set_close_action = _set_close_action, + .get_dpd_action = _get_dpd_action, + .set_dpd_action = _set_dpd_action, + .alloc_spi = _alloc_spi, + .alloc_cpi = _alloc_cpi, + .install = _install, + .update = _update, + .add_policies = _add_policies, + .get_traffic_selectors = _get_traffic_selectors, + .create_policy_enumerator = _create_policy_enumerator, + .destroy = _destroy, + }, + .my_addr = me->clone(me), + .other_addr = other->clone(other), + .encap = encap, + .ipcomp = IPCOMP_NONE, + .state = CHILD_CREATED, + .my_ts = linked_list_create(), + .other_ts = linked_list_create(), + .protocol = PROTO_NONE, + .mode = MODE_TUNNEL, + .close_action = config->get_close_action(config), + .dpd_action = config->get_dpd_action(config), + .reqid = config->get_reqid(config), + .mark_in = config->get_mark(config, TRUE), + .mark_out = config->get_mark(config, FALSE), + ); + this->config = config; config->get_ref(config); - this->reqid = config->get_reqid(config); - this->mark_in = config->get_mark(config, TRUE); - this->mark_out = config->get_mark(config, FALSE); if (!this->reqid) { diff --git a/src/libcharon/sa/connect_manager.c b/src/libcharon/sa/connect_manager.c index b78ba070d..1fb286863 100644 --- a/src/libcharon/sa/connect_manager.c +++ b/src/libcharon/sa/connect_manager.c @@ -932,7 +932,7 @@ static void update_checklist_state(private_connect_manager_t *this, callback_data_t *data = callback_data_create(this, checklist->connect_id); job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiator_finish, data, (callback_job_cleanup_t)callback_data_destroy, NULL); - charon->scheduler->schedule_job_ms(charon->scheduler, job, ME_WAIT_TO_FINISH); + lib->scheduler->schedule_job_ms(lib->scheduler, job, ME_WAIT_TO_FINISH); checklist->is_finishing = TRUE; } @@ -1031,7 +1031,7 @@ static void queue_retransmission(private_connect_manager_t *this, check_list_t * DBG2(DBG_IKE, "scheduling retransmission %d of pair '%d' in %dms", retransmission, pair->id, rto); - charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)job, rto); + lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)job, rto); } /** @@ -1064,7 +1064,7 @@ static void send_check(private_connect_manager_t *this, check_list_t *checklist, DBG2(DBG_IKE, "send ME_CONNECTAUTH %#B", &check->auth); packet_t *packet; - if (message->generate(message, NULL, NULL, &packet) == SUCCESS) + if (message->generate(message, NULL, &packet) == SUCCESS) { charon->sender->send(charon->sender, packet->clone(packet)); @@ -1170,7 +1170,7 @@ static void schedule_checks(private_connect_manager_t *this, check_list_t *check { callback_data_t *data = callback_data_create(this, checklist->connect_id); checklist->sender = (job_t*)callback_job_create((callback_job_cb_t)sender, data, (callback_job_cleanup_t)callback_data_destroy, NULL); - charon->scheduler->schedule_job_ms(charon->scheduler, checklist->sender, time); + lib->scheduler->schedule_job_ms(lib->scheduler, checklist->sender, time); } /** @@ -1222,7 +1222,7 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli initiate_data_t *data = initiate_data_create(checklist, initiated); job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiate_mediated, data, (callback_job_cleanup_t)initiate_data_destroy, NULL); - charon->processor->queue_job(charon->processor, job); + lib->processor->queue_job(lib->processor, job); return; } else @@ -1357,7 +1357,7 @@ static void process_request(private_connect_manager_t *this, check_t *check, */ static void process_check(private_connect_manager_t *this, message_t *message) { - if (message->parse_body(message, NULL, NULL) != SUCCESS) + if (message->parse_body(message, NULL) != SUCCESS) { DBG1(DBG_IKE, "%N %s with message ID %d processing failed", exchange_type_names, message->get_exchange_type(message), @@ -1477,7 +1477,7 @@ static void check_and_initiate(private_connect_manager_t *this, { job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa, waiting_sa); - charon->processor->queue_job(charon->processor, job); + lib->processor->queue_job(lib->processor, job); } iterator->destroy(iterator); diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 7536662ca..a4e4028ab 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -24,8 +24,8 @@ #include "ike_sa.h" #include <library.h> -#include <daemon.h> #include <hydra.h> +#include <daemon.h> #include <utils/linked_list.h> #include <utils/lexparser.h> #include <sa/task_manager.h> @@ -470,8 +470,8 @@ METHOD(ike_sa_t, send_keepalive, void, diff = 0; } job = send_keepalive_job_create(this->ike_sa_id); - charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, - this->keepalive_interval - diff); + lib->scheduler->schedule_job(lib->scheduler, (job_t*)job, + this->keepalive_interval - diff); } METHOD(ike_sa_t, get_ike_cfg, ike_cfg_t*, @@ -605,7 +605,7 @@ METHOD(ike_sa_t, send_dpd, status_t, } /* recheck in "interval" seconds */ job = (job_t*)send_dpd_job_create(this->ike_sa_id); - charon->scheduler->schedule_job(charon->scheduler, job, delay - diff); + lib->scheduler->schedule_job(lib->scheduler, job, delay - diff); return SUCCESS; } @@ -644,7 +644,7 @@ METHOD(ike_sa_t, set_state, void, { this->stats[STAT_REKEY] = t + this->stats[STAT_ESTABLISHED]; job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE); - charon->scheduler->schedule_job(charon->scheduler, job, t); + lib->scheduler->schedule_job(lib->scheduler, job, t); DBG1(DBG_IKE, "scheduling rekeying in %ds", t); } t = this->peer_cfg->get_reauth_time(this->peer_cfg); @@ -653,7 +653,7 @@ METHOD(ike_sa_t, set_state, void, { this->stats[STAT_REAUTH] = t + this->stats[STAT_ESTABLISHED]; job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE); - charon->scheduler->schedule_job(charon->scheduler, job, t); + lib->scheduler->schedule_job(lib->scheduler, job, t); DBG1(DBG_IKE, "scheduling reauthentication in %ds", t); } t = this->peer_cfg->get_over_time(this->peer_cfg); @@ -675,7 +675,7 @@ METHOD(ike_sa_t, set_state, void, this->stats[STAT_DELETE] += t; t = this->stats[STAT_DELETE] - this->stats[STAT_ESTABLISHED]; job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE); - charon->scheduler->schedule_job(charon->scheduler, job, t); + lib->scheduler->schedule_job(lib->scheduler, job, t); DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t); } @@ -688,8 +688,8 @@ METHOD(ike_sa_t, set_state, void, { /* 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); - charon->scheduler->schedule_job(charon->scheduler, job, - HALF_OPEN_IKE_SA_TIMEOUT); + lib->scheduler->schedule_job(lib->scheduler, job, + HALF_OPEN_IKE_SA_TIMEOUT); break; } default: @@ -730,14 +730,14 @@ METHOD(ike_sa_t, set_virtual_ip, void, if (local) { DBG1(DBG_IKE, "installing new virtual IP %H", ip); - if (charon->kernel_interface->add_ip(charon->kernel_interface, ip, - this->my_host) == SUCCESS) + if (hydra->kernel_interface->add_ip(hydra->kernel_interface, ip, + this->my_host) == SUCCESS) { if (this->my_virtual_ip) { DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip); - charon->kernel_interface->del_ip(charon->kernel_interface, - this->my_virtual_ip); + hydra->kernel_interface->del_ip(hydra->kernel_interface, + this->my_virtual_ip); } DESTROY_IF(this->my_virtual_ip); this->my_virtual_ip = ip->clone(ip); @@ -810,6 +810,20 @@ METHOD(ike_sa_t, get_pending_updates, u_int32_t, return this->pending_updates; } +METHOD(ike_sa_t, float_ports, void, + private_ike_sa_t *this) +{ + /* do not switch if we have a custom port from MOBIKE/NAT */ + if (this->my_host->get_port(this->my_host) == IKEV2_UDP_PORT) + { + this->my_host->set_port(this->my_host, IKEV2_NATT_PORT); + } + if (this->other_host->get_port(this->other_host) == IKEV2_UDP_PORT) + { + this->other_host->set_port(this->other_host, IKEV2_NATT_PORT); + } +} + METHOD(ike_sa_t, update_hosts, void, private_ike_sa_t *this, host_t *me, host_t *other) { @@ -843,10 +857,8 @@ METHOD(ike_sa_t, update_hosts, void, if (!other->equals(other, this->other_host)) { - /* update others adress if we are NOT NATed, - * and allow port changes if we are NATed */ - if (!has_condition(this, COND_NAT_HERE) || - other->ip_equals(other, this->other_host)) + /* update others adress if we are NOT NATed */ + if (!has_condition(this, COND_NAT_HERE)) { set_other_host(this, other->clone(other)); update = TRUE; @@ -882,8 +894,7 @@ METHOD(ike_sa_t, generate_message, status_t, this->stats[STAT_OUTBOUND] = time_monotonic(NULL); message->set_ike_sa_id(message, this->ike_sa_id); return message->generate(message, - this->keymat->get_crypter(this->keymat, FALSE), - this->keymat->get_signer(this->keymat, FALSE), packet); + this->keymat->get_aead(this->keymat, FALSE), packet); } /** @@ -1049,8 +1060,8 @@ static void resolve_hosts(private_ike_sa_t *this) !this->other_host->is_anyaddr(this->other_host)) { host->destroy(host); - host = charon->kernel_interface->get_source_addr( - charon->kernel_interface, this->other_host, NULL); + host = hydra->kernel_interface->get_source_addr( + hydra->kernel_interface, this->other_host, NULL); if (host) { host->set_port(host, this->ike_cfg->get_my_port(this->ike_cfg)); @@ -1150,7 +1161,7 @@ METHOD(ike_sa_t, initiate, status_t, { /* mediated connection, initiate mediation process */ job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id); - charon->processor->queue_job(charon->processor, job); + lib->processor->queue_job(lib->processor, job); return SUCCESS; } #endif /* ME */ @@ -1173,8 +1184,7 @@ METHOD(ike_sa_t, process_message, status_t, is_request = message->get_request(message); status = message->parse_body(message, - this->keymat->get_crypter(this->keymat, TRUE), - this->keymat->get_signer(this->keymat, TRUE)); + this->keymat->get_aead(this->keymat, TRUE)); if (status != SUCCESS) { @@ -1229,15 +1239,12 @@ METHOD(ike_sa_t, process_message, status_t, } else { - host_t *me, *other; - - me = message->get_destination(message); - other = message->get_source(message); - /* if this IKE_SA is virgin, we check for a config */ if (this->ike_cfg == NULL) { job_t *job; + host_t *me = message->get_destination(message), + *other = message->get_source(message); this->ike_cfg = charon->backends->get_ike_cfg(charon->backends, me, other); if (this->ike_cfg == NULL) @@ -1250,20 +1257,12 @@ 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); - charon->scheduler->schedule_job(charon->scheduler, job, - HALF_OPEN_IKE_SA_TIMEOUT); + lib->scheduler->schedule_job(lib->scheduler, job, + HALF_OPEN_IKE_SA_TIMEOUT); } this->stats[STAT_INBOUND] = time_monotonic(NULL); - /* check if message is trustworthy, and update host information */ - if (this->state == IKE_CREATED || this->state == IKE_CONNECTING || - message->get_exchange_type(message) != IKE_SA_INIT) - { - if (!supports_extension(this, EXT_MOBIKE)) - { /* with MOBIKE, we do no implicit updates */ - update_hosts(this, me, other); - } - } - status = this->task_manager->process_message(this->task_manager, message); + status = this->task_manager->process_message(this->task_manager, + message); if (message->get_exchange_type(message) == IKE_AUTH && this->state == IKE_ESTABLISHED && lib->settings->get_bool(lib->settings, @@ -1697,7 +1696,7 @@ METHOD(ike_sa_t, set_auth_lifetime, void, { DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, starting reauthentication", lifetime); - charon->processor->queue_job(charon->processor, + 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 || @@ -1706,7 +1705,7 @@ METHOD(ike_sa_t, set_auth_lifetime, void, this->stats[STAT_REAUTH] = reauth_time; DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication" " in %ds", lifetime, lifetime - reduction); - charon->scheduler->schedule_job(charon->scheduler, + lib->scheduler->schedule_job(lib->scheduler, (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), lifetime - reduction); } @@ -1718,10 +1717,65 @@ METHOD(ike_sa_t, set_auth_lifetime, void, } } +/** + * Check if the current combination of source and destination address is still + * valid. + */ +static bool is_current_path_valid(private_ike_sa_t *this) +{ + bool valid = FALSE; + host_t *src; + src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, + this->other_host, this->my_host); + if (src) + { + if (src->ip_equals(src, this->my_host)) + { + valid = TRUE; + } + src->destroy(src); + } + return valid; +} + +/** + * Check if we have any path avialable for this IKE SA. + */ +static bool is_any_path_valid(private_ike_sa_t *this) +{ + bool valid = FALSE; + enumerator_t *enumerator; + host_t *src, *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 = 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) + { + break; + } + } + enumerator->destroy(enumerator); + } + if (src) + { + valid = TRUE; + src->destroy(src); + } + return valid; +} + METHOD(ike_sa_t, roam, status_t, private_ike_sa_t *this, bool address) { - host_t *src; ike_mobike_t *mobike; switch (this->state) @@ -1734,81 +1788,61 @@ METHOD(ike_sa_t, roam, status_t, default: break; } - /* responder just updates the peer about changed address config */ - if (!this->ike_sa_id->is_initiator(this->ike_sa_id)) + + /* keep existing path if possible */ + if (is_current_path_valid(this)) { + DBG2(DBG_IKE, "keeping connection path %H - %H", + this->my_host, this->other_host); + set_condition(this, COND_STALE, FALSE); + if (supports_extension(this, EXT_MOBIKE) && address) - { + { /* if any addresses changed, send an updated list */ DBG1(DBG_IKE, "sending address list update using MOBIKE"); mobike = ike_mobike_create(&this->public, TRUE); - this->task_manager->queue_task(this->task_manager, (task_t*)mobike); + mobike->addresses(mobike); + this->task_manager->queue_task(this->task_manager, + (task_t*)mobike); return this->task_manager->initiate(this->task_manager); } return SUCCESS; } - /* keep existing path if possible */ - src = charon->kernel_interface->get_source_addr(charon->kernel_interface, - this->other_host, this->my_host); - if (src) + if (!is_any_path_valid(this)) { - if (src->ip_equals(src, this->my_host)) - { - DBG2(DBG_IKE, "keeping connection path %H - %H", - src, this->other_host); - src->destroy(src); - set_condition(this, COND_STALE, FALSE); - return SUCCESS; - } - src->destroy(src); - - } - else - { - /* check if we find a route at all */ - enumerator_t *enumerator; - host_t *addr; - - src = charon->kernel_interface->get_source_addr(charon->kernel_interface, - this->other_host, NULL); - if (!src) - { - enumerator = this->additional_addresses->create_enumerator( - this->additional_addresses); - while (enumerator->enumerate(enumerator, &addr)) - { - DBG1(DBG_IKE, "looking for a route to %H ...", addr); - src = charon->kernel_interface->get_source_addr( - charon->kernel_interface, addr, NULL); - if (src) - { - break; - } - } - enumerator->destroy(enumerator); - } - if (!src) - { - DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred", - this->other_host); - set_condition(this, COND_STALE, TRUE); - return SUCCESS; - } - src->destroy(src); + DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred", + this->other_host); + set_condition(this, COND_STALE, TRUE); + return SUCCESS; } set_condition(this, COND_STALE, FALSE); /* update addresses with mobike, if supported ... */ if (supports_extension(this, EXT_MOBIKE)) { - DBG1(DBG_IKE, "requesting address change using MOBIKE"); + if (!has_condition(this, COND_ORIGINAL_INITIATOR)) + { /* responder updates the peer about changed address config */ + DBG1(DBG_IKE, "sending address list update using MOBIKE, " + "implicitly requesting an address change"); + address = TRUE; + } + else + { + DBG1(DBG_IKE, "requesting address change using MOBIKE"); + } mobike = ike_mobike_create(&this->public, TRUE); mobike->roam(mobike, address); this->task_manager->queue_task(this->task_manager, (task_t*)mobike); return this->task_manager->initiate(this->task_manager); } - DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change"); + /* ... reauth if not */ + if (!has_condition(this, COND_ORIGINAL_INITIATOR)) + { /* responder does not reauthenticate */ + set_condition(this, COND_STALE, TRUE); + return SUCCESS; + } + DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change"); return reauth(this); } @@ -1907,9 +1941,9 @@ METHOD(ike_sa_t, inherit, status_t, this->stats[STAT_DELETE] = this->stats[STAT_REAUTH] + delete; DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, " "lifetime reduced to %ds", reauth, delete); - charon->scheduler->schedule_job(charon->scheduler, + lib->scheduler->schedule_job(lib->scheduler, (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), reauth); - charon->scheduler->schedule_job(charon->scheduler, + lib->scheduler->schedule_job(lib->scheduler, (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), delete); } /* we have to initate here, there may be new tasks to handle */ @@ -1946,8 +1980,8 @@ METHOD(ike_sa_t, destroy, void, if (this->my_virtual_ip) { - charon->kernel_interface->del_ip(charon->kernel_interface, - this->my_virtual_ip); + hydra->kernel_interface->del_ip(hydra->kernel_interface, + this->my_virtual_ip); this->my_virtual_ip->destroy(this->my_virtual_ip); } if (this->other_virtual_ip) @@ -2025,6 +2059,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) .get_other_host = _get_other_host, .set_other_host = _set_other_host, .set_message_id = _set_message_id, + .float_ports = _float_ports, .update_hosts = _update_hosts, .get_my_id = _get_my_id, .set_my_id = _set_my_id, diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 34842a573..c0007e27d 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -329,6 +329,14 @@ struct ike_sa_t { void (*set_other_host) (ike_sa_t *this, host_t *other); /** + * Float to port 4500 (e.g. if a NAT is detected). + * + * The port of either endpoint is changed only if it is currently + * set to the default value of 500. + */ + void (*float_ports)(ike_sa_t *this); + + /** * Update the IKE_SAs host. * * Hosts may be NULL to use current host. diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index c71c3b297..fa94bb86d 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -1613,6 +1613,9 @@ static void flush(private_ike_sa_manager_t *this) enumerator->destroy(enumerator); charon->bus->set_sa(charon->bus, NULL); unlock_all_segments(this); + + this->rng->destroy(this->rng); + this->hasher->destroy(this->hasher); } /** @@ -1652,8 +1655,6 @@ static void destroy(private_ike_sa_manager_t *this) free(this->half_open_segments); free(this->connected_peers_segments); - this->rng->destroy(this->rng); - this->hasher->destroy(this->hasher); free(this); } diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h index 38f5454e1..f4eabf808 100644 --- a/src/libcharon/sa/ike_sa_manager.h +++ b/src/libcharon/sa/ike_sa_manager.h @@ -199,6 +199,8 @@ struct ike_sa_manager_t { * Delete all existing IKE_SAs and destroy them immediately. * * Threads will be driven out, so all SAs can be deleted cleanly. + * To a flush(), an immediate call to destroy() is mandatory; no other + * method may be used. */ void (*flush)(ike_sa_manager_t *this); diff --git a/src/libcharon/sa/keymat.c b/src/libcharon/sa/keymat.c index 837cbe428..878ad124f 100644 --- a/src/libcharon/sa/keymat.c +++ b/src/libcharon/sa/keymat.c @@ -36,24 +36,14 @@ struct private_keymat_t { bool initiator; /** - * inbound signer (verify) + * inbound AEAD */ - signer_t *signer_in; + aead_t *aead_in; /** - * outbound signer (sign) + * outbound AEAD */ - signer_t *signer_out; - - /** - * inbound crypter (decrypt) - */ - crypter_t *crypter_in; - - /** - * outbound crypter (encrypt) - */ - crypter_t *crypter_out; + aead_t *aead_out; /** * General purpose PRF @@ -134,30 +124,135 @@ static int lookup_keylen(keylen_entry_t *list, int algo) return 0; } +METHOD(keymat_t, create_dh, diffie_hellman_t*, + private_keymat_t *this, diffie_hellman_group_t group) +{ + return lib->crypto->create_dh(lib->crypto, group);; +} + /** - * Implementation of keymat_t.create_dh + * Derive IKE keys for a combined AEAD algorithm */ -static diffie_hellman_t* create_dh(private_keymat_t *this, - diffie_hellman_group_t group) +static bool derive_ike_aead(private_keymat_t *this, u_int16_t alg, + u_int16_t key_size, prf_plus_t *prf_plus) { - return lib->crypto->create_dh(lib->crypto, group);; + aead_t *aead_i, *aead_r; + chunk_t key; + + /* SK_ei/SK_er used for encryption */ + aead_i = lib->crypto->create_aead(lib->crypto, alg, key_size / 8); + aead_r = lib->crypto->create_aead(lib->crypto, alg, key_size / 8); + if (aead_i == NULL || aead_r == NULL) + { + DBG1(DBG_IKE, "%N %N (key size %d) not supported!", + transform_type_names, ENCRYPTION_ALGORITHM, + encryption_algorithm_names, alg, key_size); + return FALSE; + } + key_size = aead_i->get_key_size(aead_i); + + prf_plus->allocate_bytes(prf_plus, key_size, &key); + DBG4(DBG_IKE, "Sk_ei secret %B", &key); + aead_i->set_key(aead_i, key); + chunk_clear(&key); + + prf_plus->allocate_bytes(prf_plus, key_size, &key); + DBG4(DBG_IKE, "Sk_er secret %B", &key); + aead_r->set_key(aead_r, key); + chunk_clear(&key); + + if (this->initiator) + { + this->aead_in = aead_r; + this->aead_out = aead_i; + } + else + { + this->aead_in = aead_i; + this->aead_out = aead_r; + } + return TRUE; } /** - * Implementation of keymat_t.derive_keys + * Derive IKE keys for traditional encryption and MAC algorithms */ -static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal, - diffie_hellman_t *dh, chunk_t nonce_i, - chunk_t nonce_r, ike_sa_id_t *id, - pseudo_random_function_t rekey_function, - chunk_t rekey_skd) +static bool derive_ike_traditional(private_keymat_t *this, u_int16_t enc_alg, + u_int16_t enc_size, u_int16_t int_alg, prf_plus_t *prf_plus) { - chunk_t skeyseed, key, secret, full_nonce, fixed_nonce, prf_plus_seed; - chunk_t spi_i, spi_r; crypter_t *crypter_i, *crypter_r; signer_t *signer_i, *signer_r; + size_t key_size; + chunk_t key; + + /* SK_ai/SK_ar used for integrity protection */ + signer_i = lib->crypto->create_signer(lib->crypto, int_alg); + signer_r = lib->crypto->create_signer(lib->crypto, int_alg); + if (signer_i == NULL || signer_r == NULL) + { + DBG1(DBG_IKE, "%N %N not supported!", + transform_type_names, INTEGRITY_ALGORITHM, + integrity_algorithm_names, int_alg); + return FALSE; + } + key_size = signer_i->get_key_size(signer_i); + + prf_plus->allocate_bytes(prf_plus, key_size, &key); + DBG4(DBG_IKE, "Sk_ai secret %B", &key); + signer_i->set_key(signer_i, key); + chunk_clear(&key); + + prf_plus->allocate_bytes(prf_plus, key_size, &key); + DBG4(DBG_IKE, "Sk_ar secret %B", &key); + signer_r->set_key(signer_r, key); + chunk_clear(&key); + + /* SK_ei/SK_er used for encryption */ + crypter_i = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8); + crypter_r = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8); + if (crypter_i == NULL || crypter_r == NULL) + { + DBG1(DBG_IKE, "%N %N (key size %d) not supported!", + transform_type_names, ENCRYPTION_ALGORITHM, + encryption_algorithm_names, enc_alg, key_size); + signer_i->destroy(signer_i); + signer_r->destroy(signer_r); + return FALSE; + } + key_size = crypter_i->get_key_size(crypter_i); + + prf_plus->allocate_bytes(prf_plus, key_size, &key); + DBG4(DBG_IKE, "Sk_ei secret %B", &key); + crypter_i->set_key(crypter_i, key); + chunk_clear(&key); + + prf_plus->allocate_bytes(prf_plus, key_size, &key); + DBG4(DBG_IKE, "Sk_er secret %B", &key); + crypter_r->set_key(crypter_r, key); + chunk_clear(&key); + + if (this->initiator) + { + this->aead_in = aead_create(crypter_r, signer_r); + this->aead_out = aead_create(crypter_i, signer_i); + } + else + { + this->aead_in = aead_create(crypter_i, signer_i); + this->aead_out = aead_create(crypter_r, signer_r); + } + return TRUE; +} + +METHOD(keymat_t, derive_ike_keys, bool, + private_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh, + chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, + pseudo_random_function_t rekey_function, chunk_t rekey_skd) +{ + chunk_t skeyseed, key, secret, full_nonce, fixed_nonce, prf_plus_seed; + chunk_t spi_i, spi_r; prf_plus_t *prf_plus; - u_int16_t alg, key_size; + u_int16_t alg, key_size, int_alg; prf_t *rekey_prf = NULL; spi_i = chunk_alloca(sizeof(u_int64_t)); @@ -195,6 +290,9 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal, /* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does * not and therefore fixed key semantics apply to XCBC for key * derivation. */ + case PRF_CAMELLIA128_XCBC: + /* draft-kanno-ipsecme-camellia-xcbc refers to rfc 4434, we + * assume fixed key length. */ key_size = this->prf->get_key_size(this->prf)/2; nonce_i.len = min(nonce_i.len, key_size); nonce_r.len = min(nonce_r.len, key_size); @@ -255,50 +353,6 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal, prf_plus->allocate_bytes(prf_plus, key_size, &this->skd); DBG4(DBG_IKE, "Sk_d secret %B", &this->skd); - /* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */ - if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL)) - { - DBG1(DBG_IKE, "no %N selected", - transform_type_names, INTEGRITY_ALGORITHM); - prf_plus->destroy(prf_plus); - DESTROY_IF(rekey_prf); - return FALSE; - } - signer_i = lib->crypto->create_signer(lib->crypto, alg); - signer_r = lib->crypto->create_signer(lib->crypto, alg); - if (signer_i == NULL || signer_r == NULL) - { - DBG1(DBG_IKE, "%N %N not supported!", - transform_type_names, INTEGRITY_ALGORITHM, - integrity_algorithm_names ,alg); - prf_plus->destroy(prf_plus); - DESTROY_IF(rekey_prf); - return FALSE; - } - key_size = signer_i->get_key_size(signer_i); - - prf_plus->allocate_bytes(prf_plus, key_size, &key); - DBG4(DBG_IKE, "Sk_ai secret %B", &key); - signer_i->set_key(signer_i, key); - chunk_clear(&key); - - prf_plus->allocate_bytes(prf_plus, key_size, &key); - DBG4(DBG_IKE, "Sk_ar secret %B", &key); - signer_r->set_key(signer_r, key); - chunk_clear(&key); - - if (this->initiator) - { - this->signer_in = signer_r; - this->signer_out = signer_i; - } - else - { - this->signer_in = signer_i; - this->signer_out = signer_r; - } - - /* SK_ei/SK_er used for encryption => crypter_in/crypter_out */ if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &key_size)) { DBG1(DBG_IKE, "no %N selected", @@ -307,38 +361,33 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal, DESTROY_IF(rekey_prf); return FALSE; } - crypter_i = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8); - crypter_r = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8); - if (crypter_i == NULL || crypter_r == NULL) - { - DBG1(DBG_IKE, "%N %N (key size %d) not supported!", - transform_type_names, ENCRYPTION_ALGORITHM, - encryption_algorithm_names, alg, key_size); - prf_plus->destroy(prf_plus); - DESTROY_IF(rekey_prf); - return FALSE; - } - key_size = crypter_i->get_key_size(crypter_i); - prf_plus->allocate_bytes(prf_plus, key_size, &key); - DBG4(DBG_IKE, "Sk_ei secret %B", &key); - crypter_i->set_key(crypter_i, key); - chunk_clear(&key); - - prf_plus->allocate_bytes(prf_plus, key_size, &key); - DBG4(DBG_IKE, "Sk_er secret %B", &key); - crypter_r->set_key(crypter_r, key); - chunk_clear(&key); - - if (this->initiator) + if (encryption_algorithm_is_aead(alg)) { - this->crypter_in = crypter_r; - this->crypter_out = crypter_i; + if (!derive_ike_aead(this, alg, key_size, prf_plus)) + { + prf_plus->destroy(prf_plus); + DESTROY_IF(rekey_prf); + return FALSE; + } } else { - this->crypter_in = crypter_i; - this->crypter_out = crypter_r; + if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, + &int_alg, NULL)) + { + DBG1(DBG_IKE, "no %N selected", + transform_type_names, INTEGRITY_ALGORITHM); + prf_plus->destroy(prf_plus); + DESTROY_IF(rekey_prf); + return FALSE; + } + if (!derive_ike_traditional(this, alg, key_size, int_alg, prf_plus)) + { + prf_plus->destroy(prf_plus); + DESTROY_IF(rekey_prf); + return FALSE; + } } /* SK_pi/SK_pr used for authentication => stored for later */ @@ -371,14 +420,10 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal, return TRUE; } -/** - * Implementation of keymat_t.derive_child_keys - */ -static bool derive_child_keys(private_keymat_t *this, - proposal_t *proposal, diffie_hellman_t *dh, - chunk_t nonce_i, chunk_t nonce_r, - chunk_t *encr_i, chunk_t *integ_i, - chunk_t *encr_r, chunk_t *integ_r) +METHOD(keymat_t, derive_child_keys, bool, + private_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh, + chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, + chunk_t *encr_r, chunk_t *integ_r) { u_int16_t enc_alg, int_alg, enc_size = 0, int_size = 0; chunk_t seed, secret = chunk_empty; @@ -480,37 +525,22 @@ static bool derive_child_keys(private_keymat_t *this, return TRUE; } -/** - * Implementation of keymat_t.get_skd - */ -static pseudo_random_function_t get_skd(private_keymat_t *this, chunk_t *skd) +METHOD(keymat_t, get_skd, pseudo_random_function_t, + private_keymat_t *this, chunk_t *skd) { *skd = this->skd; return this->prf_alg; } -/** - * Implementation of keymat_t.get_signer - */ -static signer_t* get_signer(private_keymat_t *this, bool in) -{ - return in ? this->signer_in : this->signer_out; -} - -/** - * Implementation of keymat_t.get_crypter - */ -static crypter_t* get_crypter(private_keymat_t *this, bool in) +METHOD(keymat_t, get_aead, aead_t*, + private_keymat_t *this, bool in) { - return in ? this->crypter_in : this->crypter_out; + return in ? this->aead_in : this->aead_out; } -/** - * Implementation of keymat_t.get_auth_octets - */ -static chunk_t get_auth_octets(private_keymat_t *this, bool verify, - chunk_t ike_sa_init, chunk_t nonce, - identification_t *id) +METHOD(keymat_t, get_auth_octets, chunk_t, + private_keymat_t *this, bool verify, chunk_t ike_sa_init, + chunk_t nonce, identification_t *id) { chunk_t chunk, idx, octets; chunk_t skp; @@ -538,12 +568,9 @@ static chunk_t get_auth_octets(private_keymat_t *this, bool verify, #define IKEV2_KEY_PAD "Key Pad for IKEv2" #define IKEV2_KEY_PAD_LENGTH 17 -/** - * Implementation of keymat_t.get_psk_sig - */ -static chunk_t get_psk_sig(private_keymat_t *this, bool verify, - chunk_t ike_sa_init, chunk_t nonce, chunk_t secret, - identification_t *id) +METHOD(keymat_t, get_psk_sig, chunk_t, + private_keymat_t *this, bool verify, chunk_t ike_sa_init, + chunk_t nonce, chunk_t secret, identification_t *id) { chunk_t key_pad, key, sig, octets; @@ -567,15 +594,11 @@ static chunk_t get_psk_sig(private_keymat_t *this, bool verify, return sig; } -/** - * Implementation of keymat_t.destroy. - */ -static void destroy(private_keymat_t *this) +METHOD(keymat_t, destroy, void, + private_keymat_t *this) { - DESTROY_IF(this->signer_in); - DESTROY_IF(this->signer_out); - DESTROY_IF(this->crypter_in); - DESTROY_IF(this->crypter_out); + DESTROY_IF(this->aead_in); + DESTROY_IF(this->aead_out); DESTROY_IF(this->prf); chunk_clear(&this->skd); chunk_clear(&this->skp_verify); @@ -588,29 +611,22 @@ static void destroy(private_keymat_t *this) */ keymat_t *keymat_create(bool initiator) { - private_keymat_t *this = malloc_thing(private_keymat_t); - - this->public.create_dh = (diffie_hellman_t*(*)(keymat_t*, diffie_hellman_group_t group))create_dh; - this->public.derive_ike_keys = (bool(*)(keymat_t*, proposal_t *proposal, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, pseudo_random_function_t,chunk_t))derive_ike_keys; - this->public.derive_child_keys = (bool(*)(keymat_t*, proposal_t *proposal, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r))derive_child_keys; - this->public.get_skd = (pseudo_random_function_t(*)(keymat_t*, chunk_t *skd))get_skd; - this->public.get_signer = (signer_t*(*)(keymat_t*, bool in))get_signer; - this->public.get_crypter = (crypter_t*(*)(keymat_t*, bool in))get_crypter; - this->public.get_auth_octets = (chunk_t(*)(keymat_t *, bool verify, chunk_t ike_sa_init, chunk_t nonce, identification_t *id))get_auth_octets; - this->public.get_psk_sig = (chunk_t(*)(keymat_t*, bool verify, chunk_t ike_sa_init, chunk_t nonce, chunk_t secret, identification_t *id))get_psk_sig; - this->public.destroy = (void(*)(keymat_t*))destroy; - - this->initiator = initiator; - - this->signer_in = NULL; - this->signer_out = NULL; - this->crypter_in = NULL; - this->crypter_out = NULL; - this->prf = NULL; - this->prf_alg = PRF_UNDEFINED; - this->skd = chunk_empty; - this->skp_verify = chunk_empty; - this->skp_build = chunk_empty; + private_keymat_t *this; + + INIT(this, + .public = { + .create_dh = _create_dh, + .derive_ike_keys = _derive_ike_keys, + .derive_child_keys = _derive_child_keys, + .get_skd = _get_skd, + .get_aead = _get_aead, + .get_auth_octets = _get_auth_octets, + .get_psk_sig = _get_psk_sig, + .destroy = _destroy, + }, + .initiator = initiator, + .prf_alg = PRF_UNDEFINED, + ); return &this->public; } diff --git a/src/libcharon/sa/keymat.h b/src/libcharon/sa/keymat.h index e51709e8d..4f01aa411 100644 --- a/src/libcharon/sa/keymat.h +++ b/src/libcharon/sa/keymat.h @@ -24,8 +24,7 @@ #include <library.h> #include <utils/identification.h> #include <crypto/prfs/prf.h> -#include <crypto/crypters/crypter.h> -#include <crypto/signers/signer.h> +#include <crypto/aead.h> #include <config/proposal.h> #include <sa/ike_sa_id.h> @@ -99,21 +98,13 @@ struct keymat_t { */ pseudo_random_function_t (*get_skd)(keymat_t *this, chunk_t *skd); - /** - * Get a signer to sign/verify IKE messages. - * - * @param in TRUE for inbound (verify), FALSE for outbound (sign) - * @return signer - */ - signer_t* (*get_signer)(keymat_t *this, bool in); - /* - * Get a crypter to en-/decrypt IKE messages. + * Get a AEAD transform to en-/decrypt and sign/verify IKE messages. * * @param in TRUE for inbound (decrypt), FALSE for outbound (encrypt) * @return crypter */ - crypter_t* (*get_crypter)(keymat_t *this, bool in); + aead_t* (*get_aead)(keymat_t *this, bool in); /** * Generate octets to use for authentication procedure (RFC4306 2.15). diff --git a/src/libcharon/sa/mediation_manager.c b/src/libcharon/sa/mediation_manager.c index 035f49053..2fbab7c7c 100644 --- a/src/libcharon/sa/mediation_manager.c +++ b/src/libcharon/sa/mediation_manager.c @@ -241,7 +241,7 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe (void**)&requester) == SUCCESS) { job_t *job = (job_t*)mediation_callback_job_create(requester, peer_id); - charon->processor->queue_job(charon->processor, job); + lib->processor->queue_job(lib->processor, job); requester->destroy(requester); } diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c index a68826440..18703ce36 100644 --- a/src/libcharon/sa/task_manager.c +++ b/src/libcharon/sa/task_manager.c @@ -274,7 +274,7 @@ METHOD(task_manager_t, retransmit, status_t, this->initiating.retransmitted++; job = (job_t*)retransmit_job_create(this->initiating.mid, this->ike_sa->get_id(this->ike_sa)); - charon->scheduler->schedule_job_ms(charon->scheduler, job, timeout); + lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout); } return SUCCESS; } @@ -883,11 +883,21 @@ METHOD(task_manager_t, process_message, status_t, private_task_manager_t *this, message_t *msg) { u_int32_t mid = msg->get_message_id(msg); + host_t *me = msg->get_destination(msg), *other = msg->get_source(msg); if (msg->get_request(msg)) { if (mid == this->responding.mid) { + if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED || + this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING || + msg->get_exchange_type(msg) != IKE_SA_INIT) + { /* only do host updates based on verified messages */ + if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) + { /* with MOBIKE, we do no implicit updates */ + this->ike_sa->update_hosts(this->ike_sa, me, other); + } + } charon->bus->message(charon->bus, msg, TRUE); if (process_request(this, msg) != SUCCESS) { @@ -920,6 +930,15 @@ METHOD(task_manager_t, process_message, status_t, { if (mid == this->initiating.mid) { + if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED || + this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING || + msg->get_exchange_type(msg) != IKE_SA_INIT) + { /* only do host updates based on verified messages */ + if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) + { /* with MOBIKE, we do no implicit updates */ + this->ike_sa->update_hosts(this->ike_sa, me, other); + } + } charon->bus->message(charon->bus, msg, TRUE); if (process_response(this, msg) != SUCCESS) { diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c index 3de27ee3f..57beedba9 100644 --- a/src/libcharon/sa/tasks/child_create.c +++ b/src/libcharon/sa/tasks/child_create.c @@ -261,7 +261,7 @@ static void schedule_inactivity_timeout(private_child_create_t *this) { close_ike = lib->settings->get_bool(lib->settings, "charon.inactivity_close_ike", FALSE); - charon->scheduler->schedule_job(charon->scheduler, (job_t*) + lib->scheduler->schedule_job(lib->scheduler, (job_t*) inactivity_job_create(this->child_sa->get_reqid(this->child_sa), timeout, close_ike), timeout); } @@ -871,7 +871,7 @@ static void handle_child_sa_failure(private_child_create_t *this, /* we delay the delete for 100ms, as the IKE_AUTH response must arrive * first */ DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure"); - charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*) + lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*) delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE), 100); } diff --git a/src/libcharon/sa/tasks/child_delete.c b/src/libcharon/sa/tasks/child_delete.c index b0cd30e1e..45e97e4cd 100644 --- a/src/libcharon/sa/tasks/child_delete.c +++ b/src/libcharon/sa/tasks/child_delete.c @@ -117,11 +117,10 @@ static void build_payloads(private_child_delete_t *this, message_t *message) */ static void process_payloads(private_child_delete_t *this, message_t *message) { - enumerator_t *payloads; - iterator_t *spis; + enumerator_t *payloads, *spis; payload_t *payload; delete_payload_t *delete_payload; - u_int32_t *spi; + u_int32_t spi; protocol_id_t protocol; child_sa_t *child_sa; @@ -136,19 +135,19 @@ static void process_payloads(private_child_delete_t *this, message_t *message) { continue; } - spis = delete_payload->create_spi_iterator(delete_payload); - while (spis->iterate(spis, (void**)&spi)) + spis = delete_payload->create_spi_enumerator(delete_payload); + while (spis->enumerate(spis, &spi)) { child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, - *spi, FALSE); + spi, FALSE); if (child_sa == NULL) { DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x, " - "but no such SA", protocol_id_names, protocol, ntohl(*spi)); + "but no such SA", protocol_id_names, protocol, ntohl(spi)); continue; } DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x", - protocol_id_names, protocol, ntohl(*spi)); + protocol_id_names, protocol, ntohl(spi)); switch (child_sa->get_state(child_sa)) { @@ -161,7 +160,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message) if (!this->initiator) { this->ike_sa->destroy_child_sa(this->ike_sa, - protocol, *spi); + protocol, spi); continue; } case CHILD_INSTALLED: diff --git a/src/libcharon/sa/tasks/child_rekey.c b/src/libcharon/sa/tasks/child_rekey.c index fb3452efd..fdaaea4b8 100644 --- a/src/libcharon/sa/tasks/child_rekey.c +++ b/src/libcharon/sa/tasks/child_rekey.c @@ -75,6 +75,15 @@ struct private_child_rekey_t { * colliding task, may be delete or rekey */ task_t *collision; + + /** + * Indicate that peer destroyed the redundant child from collision. + * This happens if a peer's delete notification for the redundant + * child gets processed before the rekey job. If so, we must not + * touch the child created in the collision since it points to + * memory already freed. + */ + bool other_child_destroyed; }; /** @@ -239,9 +248,13 @@ static child_sa_t *handle_collision(private_child_rekey_t *this) DBG1(DBG_IKE, "CHILD_SA rekey collision won, " "deleting rekeyed child"); to_delete = this->child_sa; - /* 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); + /* don't touch child other created, it has already been deleted */ + if (!this->other_child_destroyed) + { + /* 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); + } } else { @@ -286,7 +299,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) DBG1(DBG_IKE, "peer seems to not support CHILD_SA rekeying, " "starting reauthentication"); this->child_sa->set_state(this->child_sa, CHILD_INSTALLED); - charon->processor->queue_job(charon->processor, + lib->processor->queue_job(lib->processor, (job_t*)rekey_ike_sa_job_create( this->ike_sa->get_id(this->ike_sa), TRUE)); return SUCCESS; @@ -316,7 +329,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) DBG1(DBG_IKE, "CHILD_SA rekeying failed, " "trying again in %d seconds", retry); this->child_sa->set_state(this->child_sa, CHILD_INSTALLED); - charon->scheduler->schedule_job(charon->scheduler, job, retry); + lib->scheduler->schedule_job(lib->scheduler, job, retry); } return SUCCESS; } @@ -380,6 +393,13 @@ static void collide(private_child_rekey_t *this, task_t *other) else if (other->get_type(other) == CHILD_DELETE) { child_delete_t *del = (child_delete_t*)other; + if (del->get_child(del) == this->child_create->get_child(this->child_create)) + { + /* peer deletes redundant child created in collision */ + this->other_child_destroyed = TRUE; + other->destroy(other); + return; + } if (del == NULL || del->get_child(del) != this->child_sa) { /* not the same child => no collision */ @@ -466,6 +486,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t 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 a954782f2..b440ec811 100644 --- a/src/libcharon/sa/tasks/ike_auth.c +++ b/src/libcharon/sa/tasks/ike_auth.c @@ -481,9 +481,8 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) { this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH); } - if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) && - message->get_notify(message, EAP_ONLY_AUTHENTICATION)) - { /* EAP-only has no official notify, accept only from strongSwan */ + if (message->get_notify(message, EAP_ONLY_AUTHENTICATION)) + { this->ike_sa->enable_extension(this->ike_sa, EXT_EAP_ONLY_AUTHENTICATION); } @@ -538,6 +537,11 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) { cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id)); } + id = (identification_t*)cand->get(cand, AUTH_RULE_AAA_IDENTITY); + if (id) + { + cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, id->clone(id)); + } } /* verify authentication data */ @@ -821,7 +825,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) break; default: { - if (type < 16383) + if (type <= 16383) { DBG1(DBG_IKE, "received %N notify error", notify_type_names, type); diff --git a/src/libcharon/sa/tasks/ike_init.c b/src/libcharon/sa/tasks/ike_init.c index 38fb572f4..dd4a5f5c0 100644 --- a/src/libcharon/sa/tasks/ike_init.c +++ b/src/libcharon/sa/tasks/ike_init.c @@ -468,7 +468,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message) } default: { - if (type < 16383) + if (type <= 16383) { DBG1(DBG_IKE, "received %N notify error", notify_type_names, type); diff --git a/src/libcharon/sa/tasks/ike_me.c b/src/libcharon/sa/tasks/ike_me.c index 2d2847ae0..1de6ae8fc 100644 --- a/src/libcharon/sa/tasks/ike_me.c +++ b/src/libcharon/sa/tasks/ike_me.c @@ -17,6 +17,7 @@ #include <string.h> +#include <hydra.h> #include <daemon.h> #include <config/peer_cfg.h> #include <encoding/payloads/id_payload.h> @@ -134,8 +135,8 @@ static void gather_and_add_endpoints(private_ike_me_t *this, message_t *message) host = this->ike_sa->get_my_host(this->ike_sa); port = host->get_port(host); - enumerator = charon->kernel_interface->create_address_enumerator( - charon->kernel_interface, FALSE, FALSE); + enumerator = hydra->kernel_interface->create_address_enumerator( + hydra->kernel_interface, FALSE, FALSE); while (enumerator->enumerate(enumerator, (void**)&addr)) { host = addr->clone(addr); @@ -454,6 +455,9 @@ static status_t process_i(private_ike_me_t *this, message_t *message) DBG1(DBG_IKE, "server did not return a ME_MEDIATION, aborting"); return FAILED; } + /* if we are on a mediation connection we switch to port 4500 even + * if no NAT is detected. */ + this->ike_sa->float_ports(this->ike_sa); return NEED_MORE; } case IKE_AUTH: @@ -689,7 +693,7 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message) job_t *job = (job_t*)mediation_job_create(this->peer_id, this->ike_sa->get_other_id(this->ike_sa), this->connect_id, this->connect_key, this->remote_endpoints, this->response); - charon->processor->queue_job(charon->processor, job); + lib->processor->queue_job(lib->processor, job); break; } default: diff --git a/src/libcharon/sa/tasks/ike_mobike.c b/src/libcharon/sa/tasks/ike_mobike.c index a62886f02..5b12eaaac 100644 --- a/src/libcharon/sa/tasks/ike_mobike.c +++ b/src/libcharon/sa/tasks/ike_mobike.c @@ -17,6 +17,7 @@ #include <string.h> +#include <hydra.h> #include <daemon.h> #include <sa/tasks/ike_natd.h> #include <encoding/payloads/notify_payload.h> @@ -70,6 +71,11 @@ struct private_ike_mobike_t { * include address list update */ bool address; + + /** + * additional addresses got updated + */ + bool addresses_updated; }; /** @@ -153,6 +159,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message) 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->addresses_updated = TRUE; break; } case UPDATE_SA_ADDRESSES: @@ -163,6 +170,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message) case NO_ADDITIONAL_ADDRESSES: { flush_additional_addresses(this); + this->addresses_updated = TRUE; break; } case NAT_DETECTION_SOURCE_IP: @@ -193,8 +201,8 @@ static void build_address_list(private_ike_mobike_t *this, message_t *message) int added = 0; me = this->ike_sa->get_my_host(this->ike_sa); - enumerator = charon->kernel_interface->create_address_enumerator( - charon->kernel_interface, FALSE, FALSE); + enumerator = hydra->kernel_interface->create_address_enumerator( + hydra->kernel_interface, FALSE, FALSE); while (enumerator->enumerate(enumerator, (void**)&host)) { if (me->ip_equals(me, host)) @@ -269,32 +277,23 @@ static void update_children(private_ike_mobike_t *this) } /** - * Apply port of old address if it equals new, port otherwise + * Apply the port of the old host, if its ip equals the new, use port otherwise. */ -static void apply_port(private_ike_mobike_t *this, host_t *host, host_t *old, - u_int16_t port) +static void apply_port(host_t *host, host_t *old, u_int16_t port) { if (host->ip_equals(host, old)) { - host->set_port(host, old->get_port(old)); + port = old->get_port(old); } - else + else if (port == IKEV2_UDP_PORT) { - if (port == IKEV2_UDP_PORT) - { - host->set_port(host, IKEV2_NATT_PORT); - } - else - { - host->set_port(host, port); - } + port = IKEV2_NATT_PORT; } + host->set_port(host, port); } -/** - * Implementation of ike_mobike_t.transmit - */ -static void transmit(private_ike_mobike_t *this, packet_t *packet) +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; @@ -310,11 +309,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet) other_old = this->ike_sa->get_other_host(this->ike_sa); ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); - me = charon->kernel_interface->get_source_addr( - charon->kernel_interface, other_old, NULL); + me = hydra->kernel_interface->get_source_addr( + hydra->kernel_interface, other_old, NULL); if (me) { - apply_port(this, me, me_old, ike_cfg->get_my_port(ike_cfg)); + 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); @@ -324,8 +323,8 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet) iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa); while (iterator->iterate(iterator, (void**)&other)) { - me = charon->kernel_interface->get_source_addr( - charon->kernel_interface, other, NULL); + me = hydra->kernel_interface->get_source_addr( + hydra->kernel_interface, other, NULL); if (me) { if (me->get_family(me) != other->get_family(other)) @@ -334,9 +333,9 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet) continue; } /* reuse port for an active address, 4500 otherwise */ - apply_port(this, me, me_old, ike_cfg->get_my_port(ike_cfg)); + apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg)); other = other->clone(other); - apply_port(this, other, other_old, ike_cfg->get_other_port(ike_cfg)); + apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg)); DBG1(DBG_IKE, "checking path %#H - %#H", me, other); copy = packet->clone(packet); copy->set_source(copy, me); @@ -347,12 +346,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet) iterator->destroy(iterator); } -/** - * Implementation of task_t.process for initiator - */ -static status_t build_i(private_ike_mobike_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_mobike_t *this, message_t *message) { - if (message->get_message_id(message) == 1) + if (message->get_exchange_type(message) == IKE_AUTH && + message->get_message_id(message) == 1) { /* only in first IKE_AUTH */ message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty); build_address_list(this, message); @@ -363,7 +361,7 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message) /* we check if the existing address is still valid */ old = message->get_source(message); - new = charon->kernel_interface->get_source_addr(charon->kernel_interface, + new = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, message->get_destination(message), old); if (new) { @@ -379,11 +377,12 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message) } if (this->update) { - message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty); + message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, + chunk_empty); build_cookie(this, message); update_children(this); } - if (this->address) + if (this->address && !this->check) { build_address_list(this, message); } @@ -395,12 +394,11 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_mobike_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_mobike_t *this, message_t *message) { - if (message->get_message_id(message) == 1) + if (message->get_exchange_type(message) == IKE_AUTH && + message->get_message_id(message) == 1) { /* only first IKE_AUTH */ process_payloads(this, message); } @@ -421,14 +419,25 @@ static status_t process_r(private_ike_mobike_t *this, message_t *message) { this->natd->task.process(&this->natd->task, message); } + if (this->addresses_updated && this->ike_sa->has_condition(this->ike_sa, + COND_ORIGINAL_INITIATOR)) + { + host_t *other = message->get_source(message); + host_t *other_old = this->ike_sa->get_other_host(this->ike_sa); + if (!other->equals(other, other_old)) + { + DBG1(DBG_IKE, "remote address changed from %H to %H", other_old, + other); + this->ike_sa->set_other_host(this->ike_sa, other->clone(other)); + this->update = TRUE; + } + } } return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_mobike_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_mobike_t *this, message_t *message) { if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) @@ -460,10 +469,8 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_mobike_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_mobike_t *this, message_t *message) { if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) @@ -536,14 +543,22 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message) } if (this->update) { - /* start the update with the same task */ - this->check = FALSE; - this->address = FALSE; - if (this->natd) - { - this->natd->task.destroy(&this->natd->task); + /* use the same task to ... */ + if (!this->ike_sa->has_condition(this->ike_sa, + COND_ORIGINAL_INITIATOR)) + { /*... send an updated list of addresses as responder */ + update_children(this); + this->update = FALSE; + } + else + { /* ... send the update as original initiator */ + if (this->natd) + { + this->natd->task.destroy(&this->natd->task); + } + this->natd = ike_natd_create(this->ike_sa, this->initiator); } - this->natd = ike_natd_create(this->ike_sa, this->initiator); + this->check = FALSE; this->ike_sa->set_pending_updates(this->ike_sa, 1); return NEED_MORE; } @@ -553,51 +568,48 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of ike_mobike_t.roam. - */ -static void roam(private_ike_mobike_t *this, bool address) +METHOD(ike_mobike_t, addresses, void, + private_ike_mobike_t *this) +{ + this->address = TRUE; + this->ike_sa->set_pending_updates(this->ike_sa, + this->ike_sa->get_pending_updates(this->ike_sa) + 1); +} + +METHOD(ike_mobike_t, roam, void, + private_ike_mobike_t *this, bool address) { this->check = TRUE; this->address = address; this->ike_sa->set_pending_updates(this->ike_sa, - this->ike_sa->get_pending_updates(this->ike_sa) + 1); + this->ike_sa->get_pending_updates(this->ike_sa) + 1); } -/** - * Implementation of ike_mobike_t.dpd - */ -static void dpd(private_ike_mobike_t *this) +METHOD(ike_mobike_t, dpd, void, + private_ike_mobike_t *this) { if (!this->natd) { this->natd = ike_natd_create(this->ike_sa, this->initiator); } - this->address = FALSE; this->ike_sa->set_pending_updates(this->ike_sa, - this->ike_sa->get_pending_updates(this->ike_sa) + 1); + this->ike_sa->get_pending_updates(this->ike_sa) + 1); } -/** - * Implementation of ike_mobike_t.is_probing. - */ -static bool is_probing(private_ike_mobike_t *this) +METHOD(ike_mobike_t, is_probing, bool, + private_ike_mobike_t *this) { return this->check; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_mobike_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_mobike_t *this) { return IKE_MOBIKE; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_mobike_t *this, ike_sa_t *ike_sa) { chunk_free(&this->cookie2); this->ike_sa = ike_sa; @@ -607,10 +619,8 @@ static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa) } } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_mobike_t *this) +METHOD(task_t, destroy, void, + private_ike_mobike_t *this) { chunk_free(&this->cookie2); if (this->natd) @@ -625,35 +635,36 @@ static void destroy(private_ike_mobike_t *this) */ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_mobike_t *this = malloc_thing(private_ike_mobike_t); - - this->public.roam = (void(*)(ike_mobike_t*,bool))roam; - this->public.dpd = (void(*)(ike_mobike_t*))dpd; - this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit; - this->public.is_probing = (bool(*)(ike_mobike_t*))is_probing; - 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_mobike_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + .addresses = _addresses, + .roam = _roam, + .dpd = _dpd, + .transmit = _transmit, + .is_probing = _is_probing, + }, + .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->update = FALSE; - this->check = FALSE; - this->address = TRUE; - this->cookie2 = chunk_empty; - this->natd = NULL; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_mobike.h b/src/libcharon/sa/tasks/ike_mobike.h index 05b2224d1..16611939e 100644 --- a/src/libcharon/sa/tasks/ike_mobike.h +++ b/src/libcharon/sa/tasks/ike_mobike.h @@ -46,6 +46,11 @@ struct ike_mobike_t { task_t task; /** + * Use the task to update the list of additional addresses. + */ + void (*addresses)(ike_mobike_t *this); + + /** * Use the task to roam to other addresses. * * @param address TRUE to include address list update diff --git a/src/libcharon/sa/tasks/ike_natd.c b/src/libcharon/sa/tasks/ike_natd.c index 9ea20ba36..7839b52eb 100644 --- a/src/libcharon/sa/tasks/ike_natd.c +++ b/src/libcharon/sa/tasks/ike_natd.c @@ -18,6 +18,7 @@ #include <string.h> +#include <hydra.h> #include <daemon.h> #include <config/peer_cfg.h> #include <crypto/hashers/hasher.h> @@ -265,41 +266,15 @@ static status_t process_i(private_ike_natd_t *this, message_t *message) if (message->get_exchange_type(message) == IKE_SA_INIT) { peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); - -#ifdef ME - /* if we are on a mediated connection we have already switched to - * port 4500 and the correct destination port is already configured, - * therefore we must not switch again */ - if (peer_cfg->get_mediated_by(peer_cfg)) - { - return SUCCESS; - } -#endif /* ME */ - if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY) || -#ifdef ME - /* if we are on a mediation connection we switch to port 4500 even - * if no NAT is detected. */ - peer_cfg->is_mediation(peer_cfg) || -#endif /* ME */ /* if peer supports NAT-T, we switch to port 4500 even - * if no NAT is detected. MOBIKE requires this. */ + * if no NAT is detected. can't be done later (when we would know + * whether the peer supports MOBIKE) because there would be no + * exchange to actually do the switch (other than a forced DPD). */ (peer_cfg->use_mobike(peer_cfg) && this->ike_sa->supports_extension(this->ike_sa, EXT_NATT))) { - host_t *me, *other; - - /* do not switch if we have a custom port from mobike/NAT */ - me = this->ike_sa->get_my_host(this->ike_sa); - if (me->get_port(me) == IKEV2_UDP_PORT) - { - me->set_port(me, IKEV2_NATT_PORT); - } - other = this->ike_sa->get_other_host(this->ike_sa); - if (other->get_port(other) == IKEV2_UDP_PORT) - { - other->set_port(other, IKEV2_NATT_PORT); - } + this->ike_sa->float_ports(this->ike_sa); } } @@ -342,7 +317,7 @@ static status_t build_i(private_ike_natd_t *this, message_t *message) } else { - host = charon->kernel_interface->get_source_addr(charon->kernel_interface, + host = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, this->ike_sa->get_other_host(this->ike_sa), NULL); if (host) { /* 2. */ @@ -353,8 +328,8 @@ static status_t build_i(private_ike_natd_t *this, message_t *message) } else { /* 3. */ - enumerator = charon->kernel_interface->create_address_enumerator( - charon->kernel_interface, FALSE, FALSE); + enumerator = hydra->kernel_interface->create_address_enumerator( + hydra->kernel_interface, FALSE, FALSE); while (enumerator->enumerate(enumerator, (void**)&host)) { /* apply port 500 to host, but work on a copy */ diff --git a/src/libcharon/sa/tasks/ike_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c index a2275e796..1a6c140c4 100644 --- a/src/libcharon/sa/tasks/ike_rekey.c +++ b/src/libcharon/sa/tasks/ike_rekey.c @@ -196,7 +196,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) DBG1(DBG_IKE, "peer seems to not support IKE rekeying, " "starting reauthentication"); this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - charon->processor->queue_job(charon->processor, + lib->processor->queue_job(lib->processor, (job_t*)rekey_ike_sa_job_create( this->ike_sa->get_id(this->ike_sa), TRUE)); return SUCCESS; @@ -217,7 +217,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) DBG1(DBG_IKE, "IKE_SA rekeying failed, " "trying again in %d seconds", retry); this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - charon->scheduler->schedule_job(charon->scheduler, job, retry); + lib->scheduler->schedule_job(lib->scheduler, job, retry); } return SUCCESS; case NEED_MORE: @@ -241,51 +241,56 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) if (this->collision && this->collision->get_type(this->collision) == IKE_REKEY) { - chunk_t this_nonce, other_nonce; - host_t *host; private_ike_rekey_t *other = (private_ike_rekey_t*)this->collision; - this_nonce = this->ike_init->get_lower_nonce(this->ike_init); - other_nonce = other->ike_init->get_lower_nonce(other->ike_init); - - /* if we have the lower nonce, delete rekeyed SA. If not, delete - * the redundant. */ - if (memcmp(this_nonce.ptr, other_nonce.ptr, - min(this_nonce.len, other_nonce.len)) < 0) - { - /* peer should delete this SA. Add a timeout just in case. */ - job_t *job = (job_t*)delete_ike_sa_job_create( - other->new_sa->get_id(other->new_sa), TRUE); - charon->scheduler->schedule_job(charon->scheduler, job, 10); - DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA"); - charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa); - other->new_sa = NULL; - } - else + /* ike_init can be NULL, if child_sa is half-open */ + if (other->ike_init) { - DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA"); - /* apply host for a proper delete */ - host = this->ike_sa->get_my_host(this->ike_sa); - this->new_sa->set_my_host(this->new_sa, host->clone(host)); - host = this->ike_sa->get_other_host(this->ike_sa); - this->new_sa->set_other_host(this->new_sa, host->clone(host)); - this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - if (this->new_sa->delete(this->new_sa) == DESTROY_ME) + host_t *host; + chunk_t this_nonce, other_nonce; + + this_nonce = this->ike_init->get_lower_nonce(this->ike_init); + other_nonce = other->ike_init->get_lower_nonce(other->ike_init); + + /* if we have the lower nonce, delete rekeyed SA. If not, delete + * the redundant. */ + if (memcmp(this_nonce.ptr, other_nonce.ptr, + min(this_nonce.len, other_nonce.len)) < 0) { - charon->ike_sa_manager->checkin_and_destroy( - charon->ike_sa_manager, this->new_sa); + /* peer should delete this SA. Add a timeout just in case. */ + job_t *job = (job_t*)delete_ike_sa_job_create( + other->new_sa->get_id(other->new_sa), TRUE); + lib->scheduler->schedule_job(lib->scheduler, job, 10); + DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA"); + charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa); + other->new_sa = NULL; } else { - charon->ike_sa_manager->checkin( - charon->ike_sa_manager, this->new_sa); + DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA"); + /* apply host for a proper delete */ + host = this->ike_sa->get_my_host(this->ike_sa); + this->new_sa->set_my_host(this->new_sa, host->clone(host)); + host = this->ike_sa->get_other_host(this->ike_sa); + this->new_sa->set_other_host(this->new_sa, host->clone(host)); + this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); + if (this->new_sa->delete(this->new_sa) == DESTROY_ME) + { + charon->ike_sa_manager->checkin_and_destroy( + charon->ike_sa_manager, this->new_sa); + } + else + { + charon->ike_sa_manager->checkin( + charon->ike_sa_manager, this->new_sa); + } + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); + /* inherit to other->new_sa in destroy() */ + this->new_sa = other->new_sa; + other->new_sa = NULL; + return SUCCESS; } - /* set threads active IKE_SA after checkin */ - charon->bus->set_sa(charon->bus, this->ike_sa); - /* inherit to other->new_sa in destroy() */ - this->new_sa = other->new_sa; - other->new_sa = NULL; - return SUCCESS; } /* set threads active IKE_SA after checkin */ charon->bus->set_sa(charon->bus, this->ike_sa); diff --git a/src/libcharon/sa/tasks/ike_vendor.c b/src/libcharon/sa/tasks/ike_vendor.c index 7c435b6d1..1c14ee06b 100644 --- a/src/libcharon/sa/tasks/ike_vendor.c +++ b/src/libcharon/sa/tasks/ike_vendor.c @@ -123,12 +123,14 @@ ike_vendor_t *ike_vendor_create(ike_sa_t *ike_sa, bool initiator) private_ike_vendor_t *this; INIT(this, - .public.task = { - .build = _build, - .process = _process, - .migrate = _migrate, - .get_type = _get_type, - .destroy = _destroy, + .public = { + .task = { + .build = _build, + .process = _process, + .migrate = _migrate, + .get_type = _get_type, + .destroy = _destroy, + }, }, .initiator = initiator, .ike_sa = ike_sa, diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 80bf647cd..f91eff077 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -15,6 +15,7 @@ #include "trap_manager.h" +#include <hydra.h> #include <daemon.h> #include <threading/rwlock.h> #include <utils/linked_list.h> @@ -138,8 +139,8 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer, if (!me || me->is_anyaddr(me)) { DESTROY_IF(me); - me = charon->kernel_interface->get_source_addr( - charon->kernel_interface, other, NULL); + me = hydra->kernel_interface->get_source_addr( + hydra->kernel_interface, other, NULL); if (!me) { DBG1(DBG_CFG, "installing trap failed, local address unknown"); diff --git a/src/libcharon/kernel/kernel_ipsec.c b/src/libcharon/tnccs/tnccs.c index 5b0335b16..2facf02c8 100644 --- a/src/libcharon/kernel/kernel_ipsec.c +++ b/src/libcharon/tnccs/tnccs.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2008 Tobias Brunner - * Hochschule fuer Technik Rapperswil + * 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 @@ -13,17 +13,10 @@ * for more details. */ -#include "kernel_ipsec.h" +#include "tnccs.h" -ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_BEET, - "TRANSPORT", - "TUNNEL", - "BEET", +ENUM(eap_type_names, TNCCS_1_1, TNCCS_2_0, + "TNCCS 1.1", + "TNCCS SOH", + "TNCCS 2.0", ); - -ENUM(policy_dir_names, POLICY_IN, POLICY_FWD, - "in", - "out", - "fwd" -); - diff --git a/src/libcharon/tnccs/tnccs.h b/src/libcharon/tnccs/tnccs.h new file mode 100644 index 000000000..583512e82 --- /dev/null +++ b/src/libcharon/tnccs/tnccs.h @@ -0,0 +1,52 @@ +/* + * 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 libcharon + */ + +#ifndef TNCCS_H_ +#define TNCCS_H_ + +typedef enum tnccs_type_t tnccs_type_t; + +#include <library.h> + +/** + * Type of TNC Client/Server protocol + */ +enum tnccs_type_t { + TNCCS_1_1, + TNCCS_SOH, + TNCCS_2_0 +}; + +/** + * 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); + +#endif /** TNC_H_ @}*/ diff --git a/src/libcharon/tnccs/tnccs_manager.c b/src/libcharon/tnccs/tnccs_manager.c new file mode 100644 index 000000000..0fd6737c0 --- /dev/null +++ b/src/libcharon/tnccs/tnccs_manager.c @@ -0,0 +1,148 @@ +/* + * 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 "tnccs_manager.h" + +#include <utils/linked_list.h> +#include <threading/rwlock.h> + +typedef struct private_tnccs_manager_t private_tnccs_manager_t; +typedef struct tnccs_entry_t tnccs_entry_t; + +/** + * TNCCS constructor entry + */ +struct tnccs_entry_t { + + /** + * TNCCS protocol type + */ + tnccs_type_t type; + + /** + * constructor function to create instance + */ + tnccs_constructor_t constructor; +}; + +/** + * private data of tnccs_manager + */ +struct private_tnccs_manager_t { + + /** + * public functions + */ + tnccs_manager_t public; + + /** + * list of tnccs_entry_t's + */ + linked_list_t *protocols; + + /** + * rwlock to lock methods + */ + rwlock_t *lock; +}; + +METHOD(tnccs_manager_t, add_method, void, + private_tnccs_manager_t *this, tnccs_type_t type, + tnccs_constructor_t constructor) +{ + tnccs_entry_t *entry = malloc_thing(tnccs_entry_t); + + entry->type = type; + entry->constructor = constructor; + + this->lock->write_lock(this->lock); + this->protocols->insert_last(this->protocols, entry); + this->lock->unlock(this->lock); +} + +METHOD(tnccs_manager_t, remove_method, void, + private_tnccs_manager_t *this, tnccs_constructor_t constructor) +{ + enumerator_t *enumerator; + tnccs_entry_t *entry; + + this->lock->write_lock(this->lock); + enumerator = this->protocols->create_enumerator(this->protocols); + while (enumerator->enumerate(enumerator, &entry)) + { + if (constructor == entry->constructor) + { + this->protocols->remove_at(this->protocols, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); +} + +METHOD(tnccs_manager_t, create_instance, tnccs_t*, + private_tnccs_manager_t *this, tnccs_type_t type, bool is_server) +{ + enumerator_t *enumerator; + tnccs_entry_t *entry; + tnccs_t *protocol = NULL; + + this->lock->read_lock(this->lock); + enumerator = this->protocols->create_enumerator(this->protocols); + while (enumerator->enumerate(enumerator, &entry)) + { + if (type == entry->type) + { + protocol = entry->constructor(is_server); + if (protocol) + { + break; + } + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + return protocol; +} + +METHOD(tnccs_manager_t, destroy, void, + private_tnccs_manager_t *this) +{ + this->protocols->destroy_function(this->protocols, free); + this->lock->destroy(this->lock); + free(this); +} + +/* + * See header + */ +tnccs_manager_t *tnccs_manager_create() +{ + private_tnccs_manager_t *this; + + INIT(this, + .public = { + .add_method = _add_method, + .remove_method = _remove_method, + .create_instance = _create_instance, + .destroy = _destroy, + }, + .protocols = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); + + return &this->public; +} + diff --git a/src/libcharon/tnccs/tnccs_manager.h b/src/libcharon/tnccs/tnccs_manager.h new file mode 100644 index 000000000..2f4a961a7 --- /dev/null +++ b/src/libcharon/tnccs/tnccs_manager.h @@ -0,0 +1,74 @@ +/* + * 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" + +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); + + /** + * 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_ @}*/ |