From 2b8de74ff4c334c25e89988c4a401b24b5bcf03d Mon Sep 17 00:00:00 2001 From: Romain Francoise Date: Tue, 21 Oct 2014 19:28:38 +0200 Subject: Import upstream release 5.2.1 --- src/libcharon/Android.mk | 3 +- src/libcharon/Makefile.am | 10 +- src/libcharon/Makefile.in | 296 +++--- src/libcharon/bus/bus.c | 37 +- src/libcharon/bus/bus.h | 23 +- src/libcharon/bus/listeners/listener.h | 18 +- src/libcharon/config/child_cfg.c | 11 + src/libcharon/config/proposal.c | 10 +- src/libcharon/daemon.c | 2 +- src/libcharon/encoding/message.c | 997 ++++++++++++++++--- src/libcharon/encoding/message.h | 72 +- src/libcharon/encoding/parser.c | 2 +- .../encoding/payloads/encrypted_fragment_payload.h | 85 ++ .../encoding/payloads/encrypted_payload.c | 1022 ++++++++++++++++++++ .../encoding/payloads/encrypted_payload.h | 132 +++ .../encoding/payloads/encryption_payload.c | 634 ------------ .../encoding/payloads/encryption_payload.h | 111 --- src/libcharon/encoding/payloads/ike_header.c | 16 +- src/libcharon/encoding/payloads/notify_payload.c | 18 +- src/libcharon/encoding/payloads/notify_payload.h | 4 + src/libcharon/encoding/payloads/payload.c | 41 +- src/libcharon/encoding/payloads/payload.h | 24 +- src/libcharon/encoding/payloads/sa_payload.c | 17 +- src/libcharon/network/receiver.c | 4 +- src/libcharon/plugins/addrblock/Makefile.in | 8 + src/libcharon/plugins/android_dns/Makefile.in | 8 + src/libcharon/plugins/android_log/Makefile.in | 8 + src/libcharon/plugins/certexpire/Makefile.in | 8 + src/libcharon/plugins/coupling/Makefile.in | 8 + src/libcharon/plugins/dhcp/Makefile.in | 8 + src/libcharon/plugins/dnscert/Makefile.in | 8 + src/libcharon/plugins/duplicheck/Makefile.in | 8 + src/libcharon/plugins/eap_aka/Makefile.in | 8 + src/libcharon/plugins/eap_aka_3gpp2/Makefile.in | 8 + src/libcharon/plugins/eap_dynamic/Makefile.in | 8 + src/libcharon/plugins/eap_gtc/Makefile.in | 8 + src/libcharon/plugins/eap_identity/Makefile.in | 8 + src/libcharon/plugins/eap_md5/Makefile.in | 8 + src/libcharon/plugins/eap_mschapv2/Makefile.in | 8 + src/libcharon/plugins/eap_peap/Makefile.in | 8 + src/libcharon/plugins/eap_radius/Makefile.in | 8 + src/libcharon/plugins/eap_radius/eap_radius.c | 50 + .../plugins/eap_radius/eap_radius_accounting.c | 10 + src/libcharon/plugins/eap_sim/Makefile.in | 8 + src/libcharon/plugins/eap_sim_file/Makefile.in | 8 + src/libcharon/plugins/eap_sim_pcsc/Makefile.in | 8 + .../plugins/eap_simaka_pseudonym/Makefile.in | 8 + .../plugins/eap_simaka_reauth/Makefile.in | 8 + src/libcharon/plugins/eap_simaka_sql/Makefile.in | 8 + src/libcharon/plugins/eap_tls/Makefile.in | 8 + src/libcharon/plugins/eap_tnc/Makefile.in | 8 + src/libcharon/plugins/eap_ttls/Makefile.in | 8 + src/libcharon/plugins/error_notify/Makefile.in | 8 + src/libcharon/plugins/ext_auth/Makefile.am | 18 + src/libcharon/plugins/ext_auth/Makefile.in | 774 +++++++++++++++ src/libcharon/plugins/ext_auth/ext_auth_listener.c | 203 ++++ src/libcharon/plugins/ext_auth/ext_auth_listener.h | 59 ++ src/libcharon/plugins/ext_auth/ext_auth_plugin.c | 156 +++ src/libcharon/plugins/ext_auth/ext_auth_plugin.h | 49 + src/libcharon/plugins/farp/Makefile.in | 8 + src/libcharon/plugins/ha/Makefile.in | 8 + src/libcharon/plugins/ha/ha_dispatcher.c | 2 + src/libcharon/plugins/ipseckey/Makefile.in | 8 + src/libcharon/plugins/kernel_iph/Makefile.in | 8 + src/libcharon/plugins/kernel_libipsec/Makefile.in | 8 + src/libcharon/plugins/kernel_wfp/Makefile.in | 8 + src/libcharon/plugins/led/Makefile.in | 8 + src/libcharon/plugins/load_tester/Makefile.in | 8 + src/libcharon/plugins/lookip/Makefile.in | 8 + src/libcharon/plugins/maemo/Makefile.in | 8 + src/libcharon/plugins/medcli/Makefile.in | 8 + src/libcharon/plugins/medsrv/Makefile.in | 8 + src/libcharon/plugins/osx_attr/Makefile.in | 8 + src/libcharon/plugins/radattr/Makefile.in | 8 + src/libcharon/plugins/smp/Makefile.in | 8 + src/libcharon/plugins/socket_default/Makefile.in | 8 + .../plugins/socket_default/socket_default_socket.c | 5 +- src/libcharon/plugins/socket_dynamic/Makefile.in | 8 + .../plugins/socket_dynamic/socket_dynamic_socket.c | 5 +- src/libcharon/plugins/socket_win/Makefile.in | 8 + .../plugins/socket_win/socket_win_socket.c | 5 +- src/libcharon/plugins/sql/Makefile.in | 8 + src/libcharon/plugins/stroke/Makefile.in | 8 + src/libcharon/plugins/stroke/stroke_cred.c | 12 +- src/libcharon/plugins/systime_fix/Makefile.in | 8 + src/libcharon/plugins/tnc_ifmap/Makefile.in | 8 + src/libcharon/plugins/tnc_pdp/Makefile.in | 8 + src/libcharon/plugins/uci/Makefile.in | 8 + src/libcharon/plugins/unit_tester/Makefile.in | 8 + src/libcharon/plugins/unity/Makefile.in | 8 + src/libcharon/plugins/unity/unity_narrow.c | 69 +- src/libcharon/plugins/updown/Makefile.in | 8 + src/libcharon/plugins/updown/updown_listener.c | 461 ++++----- src/libcharon/plugins/vici/Makefile.am | 7 + src/libcharon/plugins/vici/Makefile.in | 210 +++- src/libcharon/plugins/vici/README.md | 698 ++++++++++++- src/libcharon/plugins/vici/libvici.c | 5 +- src/libcharon/plugins/vici/libvici.h | 4 +- src/libcharon/plugins/vici/ruby/Makefile.am | 22 + src/libcharon/plugins/vici/ruby/Makefile.in | 556 +++++++++++ src/libcharon/plugins/vici/ruby/lib/vici.rb | 569 +++++++++++ src/libcharon/plugins/vici/ruby/vici.gemspec.in | 16 + src/libcharon/plugins/vici/suites/test_message.c | 2 +- src/libcharon/plugins/vici/vici_control.c | 12 + src/libcharon/plugins/vici/vici_cred.c | 5 +- src/libcharon/plugins/vici/vici_message.c | 4 + src/libcharon/plugins/whitelist/Makefile.in | 8 + src/libcharon/plugins/xauth_eap/Makefile.in | 8 + src/libcharon/plugins/xauth_generic/Makefile.in | 8 + src/libcharon/plugins/xauth_noauth/Makefile.in | 8 + src/libcharon/plugins/xauth_pam/Makefile.in | 8 + src/libcharon/processing/jobs/adopt_children_job.c | 40 + src/libcharon/processing/jobs/adopt_children_job.h | 8 + src/libcharon/processing/jobs/update_sa_job.c | 7 +- src/libcharon/sa/ike_sa.c | 138 ++- src/libcharon/sa/ike_sa.h | 34 +- src/libcharon/sa/ike_sa_manager.c | 48 +- src/libcharon/sa/ikev1/phase1.c | 12 + src/libcharon/sa/ikev1/task_manager_v1.c | 445 +++------ src/libcharon/sa/ikev1/tasks/aggressive_mode.c | 32 +- src/libcharon/sa/ikev1/tasks/informational.c | 6 +- src/libcharon/sa/ikev1/tasks/isakmp_vendor.c | 39 +- src/libcharon/sa/ikev1/tasks/main_mode.c | 31 +- src/libcharon/sa/ikev1/tasks/quick_mode.c | 26 +- src/libcharon/sa/ikev1/tasks/xauth.c | 23 +- src/libcharon/sa/ikev1/tasks/xauth.h | 5 + src/libcharon/sa/ikev2/task_manager_v2.c | 307 ++++-- src/libcharon/sa/ikev2/tasks/ike_init.c | 23 + src/libcharon/sa/ikev2/tasks/ike_mobike.c | 95 +- src/libcharon/sa/ikev2/tasks/ike_mobike.h | 8 +- 130 files changed, 7462 insertions(+), 1914 deletions(-) create mode 100644 src/libcharon/encoding/payloads/encrypted_fragment_payload.h create mode 100644 src/libcharon/encoding/payloads/encrypted_payload.c create mode 100644 src/libcharon/encoding/payloads/encrypted_payload.h delete mode 100644 src/libcharon/encoding/payloads/encryption_payload.c delete mode 100644 src/libcharon/encoding/payloads/encryption_payload.h create mode 100644 src/libcharon/plugins/ext_auth/Makefile.am create mode 100644 src/libcharon/plugins/ext_auth/Makefile.in create mode 100644 src/libcharon/plugins/ext_auth/ext_auth_listener.c create mode 100644 src/libcharon/plugins/ext_auth/ext_auth_listener.h create mode 100644 src/libcharon/plugins/ext_auth/ext_auth_plugin.c create mode 100644 src/libcharon/plugins/ext_auth/ext_auth_plugin.h create mode 100644 src/libcharon/plugins/vici/ruby/Makefile.am create mode 100644 src/libcharon/plugins/vici/ruby/Makefile.in create mode 100644 src/libcharon/plugins/vici/ruby/lib/vici.rb create mode 100644 src/libcharon/plugins/vici/ruby/vici.gemspec.in (limited to 'src/libcharon') diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk index a28b459de..4212ee87a 100644 --- a/src/libcharon/Android.mk +++ b/src/libcharon/Android.mk @@ -25,7 +25,8 @@ encoding/payloads/cp_payload.c encoding/payloads/cp_payload.h \ encoding/payloads/delete_payload.c encoding/payloads/delete_payload.h \ encoding/payloads/eap_payload.c encoding/payloads/eap_payload.h \ encoding/payloads/encodings.c encoding/payloads/encodings.h \ -encoding/payloads/encryption_payload.c encoding/payloads/encryption_payload.h \ +encoding/payloads/encrypted_payload.c encoding/payloads/encrypted_payload.h \ +encoding/payloads/encrypted_fragment_payload.h \ encoding/payloads/id_payload.c encoding/payloads/id_payload.h \ encoding/payloads/ike_header.c encoding/payloads/ike_header.h \ encoding/payloads/ke_payload.c encoding/payloads/ke_payload.h \ diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index e81c42405..e98f5e137 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -23,7 +23,8 @@ encoding/payloads/cp_payload.c encoding/payloads/cp_payload.h \ encoding/payloads/delete_payload.c encoding/payloads/delete_payload.h \ encoding/payloads/eap_payload.c encoding/payloads/eap_payload.h \ encoding/payloads/encodings.c encoding/payloads/encodings.h \ -encoding/payloads/encryption_payload.c encoding/payloads/encryption_payload.h \ +encoding/payloads/encrypted_payload.c encoding/payloads/encrypted_payload.h \ +encoding/payloads/encrypted_fragment_payload.h \ encoding/payloads/id_payload.c encoding/payloads/id_payload.h \ encoding/payloads/ike_header.c encoding/payloads/ike_header.h \ encoding/payloads/ke_payload.c encoding/payloads/ke_payload.h \ @@ -258,6 +259,13 @@ if MONOLITHIC endif endif +if USE_EXT_AUTH + SUBDIRS += plugins/ext_auth +if MONOLITHIC + libcharon_la_LIBADD += plugins/ext_auth/libstrongswan-ext-auth.la +endif +endif + if USE_EAP_IDENTITY SUBDIRS += plugins/eap_identity if MONOLITHIC diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in index 002da511d..4d89794b5 100644 --- a/src/libcharon/Makefile.in +++ b/src/libcharon/Makefile.in @@ -162,106 +162,108 @@ host_triplet = @host@ @MONOLITHIC_TRUE@@USE_IPSECKEY_TRUE@am__append_27 = plugins/ipseckey/libstrongswan-ipseckey.la @USE_UPDOWN_TRUE@am__append_28 = plugins/updown @MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_29 = plugins/updown/libstrongswan-updown.la -@USE_EAP_IDENTITY_TRUE@am__append_30 = plugins/eap_identity -@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_31 = plugins/eap_identity/libstrongswan-eap-identity.la -@USE_EAP_SIM_TRUE@am__append_32 = plugins/eap_sim -@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_33 = plugins/eap_sim/libstrongswan-eap-sim.la -@USE_EAP_SIM_FILE_TRUE@am__append_34 = plugins/eap_sim_file -@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_35 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la -@USE_EAP_SIM_PCSC_TRUE@am__append_36 = plugins/eap_sim_pcsc -@MONOLITHIC_TRUE@@USE_EAP_SIM_PCSC_TRUE@am__append_37 = plugins/eap_sim_pcsc/libstrongswan-eap-sim-pcsc.la -@USE_EAP_SIMAKA_SQL_TRUE@am__append_38 = plugins/eap_simaka_sql -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_39 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la -@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_40 = plugins/eap_simaka_pseudonym -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_41 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la -@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_42 = plugins/eap_simaka_reauth -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_43 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la -@USE_EAP_AKA_TRUE@am__append_44 = plugins/eap_aka -@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_45 = plugins/eap_aka/libstrongswan-eap-aka.la -@USE_EAP_AKA_3GPP2_TRUE@am__append_46 = plugins/eap_aka_3gpp2 -@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_47 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la -@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_48 = $(top_builddir)/src/libsimaka/libsimaka.la -@USE_EAP_MD5_TRUE@am__append_49 = plugins/eap_md5 -@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_50 = plugins/eap_md5/libstrongswan-eap-md5.la -@USE_EAP_GTC_TRUE@am__append_51 = plugins/eap_gtc -@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_52 = plugins/eap_gtc/libstrongswan-eap-gtc.la -@USE_EAP_MSCHAPV2_TRUE@am__append_53 = plugins/eap_mschapv2 -@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_54 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la -@USE_EAP_DYNAMIC_TRUE@am__append_55 = plugins/eap_dynamic -@MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE@am__append_56 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la -@USE_EAP_RADIUS_TRUE@am__append_57 = plugins/eap_radius -@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_58 = plugins/eap_radius/libstrongswan-eap-radius.la -@USE_EAP_TLS_TRUE@am__append_59 = plugins/eap_tls -@MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE@am__append_60 = plugins/eap_tls/libstrongswan-eap-tls.la -@USE_EAP_TTLS_TRUE@am__append_61 = plugins/eap_ttls -@MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE@am__append_62 = plugins/eap_ttls/libstrongswan-eap-ttls.la -@USE_EAP_PEAP_TRUE@am__append_63 = plugins/eap_peap -@MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE@am__append_64 = plugins/eap_peap/libstrongswan-eap-peap.la -@USE_EAP_TNC_TRUE@am__append_65 = plugins/eap_tnc -@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_66 = plugins/eap_tnc/libstrongswan-eap-tnc.la -@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_67 = $(top_builddir)/src/libtls/libtls.la -@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@am__append_68 = $(top_builddir)/src/libradius/libradius.la -@USE_TNC_IFMAP_TRUE@am__append_69 = plugins/tnc_ifmap -@MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE@am__append_70 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la -@USE_TNC_PDP_TRUE@am__append_71 = plugins/tnc_pdp -@MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE@am__append_72 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la -@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@am__append_73 = $(top_builddir)/src/libtnccs/libtnccs.la -@USE_MEDSRV_TRUE@am__append_74 = plugins/medsrv -@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_75 = plugins/medsrv/libstrongswan-medsrv.la -@USE_MEDCLI_TRUE@am__append_76 = plugins/medcli -@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_77 = plugins/medcli/libstrongswan-medcli.la -@USE_DHCP_TRUE@am__append_78 = plugins/dhcp -@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_79 = plugins/dhcp/libstrongswan-dhcp.la -@USE_OSX_ATTR_TRUE@am__append_80 = plugins/osx_attr -@MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE@am__append_81 = plugins/osx_attr/libstrongswan-osx-attr.la -@USE_ANDROID_DNS_TRUE@am__append_82 = plugins/android_dns -@MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE@am__append_83 = plugins/android_dns/libstrongswan-android-dns.la -@USE_ANDROID_LOG_TRUE@am__append_84 = plugins/android_log -@MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE@am__append_85 = plugins/android_log/libstrongswan-android-log.la -@USE_MAEMO_TRUE@am__append_86 = plugins/maemo -@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_87 = plugins/maemo/libstrongswan-maemo.la -@USE_HA_TRUE@am__append_88 = plugins/ha -@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_89 = plugins/ha/libstrongswan-ha.la -@USE_KERNEL_LIBIPSEC_TRUE@am__append_90 = plugins/kernel_libipsec -@MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE@am__append_91 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la -@USE_KERNEL_WFP_TRUE@am__append_92 = plugins/kernel_wfp -@MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE@am__append_93 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la -@USE_KERNEL_IPH_TRUE@am__append_94 = plugins/kernel_iph -@MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE@am__append_95 = plugins/kernel_iph/libstrongswan-kernel-iph.la -@USE_WHITELIST_TRUE@am__append_96 = plugins/whitelist -@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_97 = plugins/whitelist/libstrongswan-whitelist.la -@USE_LOOKIP_TRUE@am__append_98 = plugins/lookip -@MONOLITHIC_TRUE@@USE_LOOKIP_TRUE@am__append_99 = plugins/lookip/libstrongswan-lookip.la -@USE_ERROR_NOTIFY_TRUE@am__append_100 = plugins/error_notify -@MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE@am__append_101 = plugins/error_notify/libstrongswan-error-notify.la -@USE_CERTEXPIRE_TRUE@am__append_102 = plugins/certexpire -@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_103 = plugins/certexpire/libstrongswan-certexpire.la -@USE_SYSTIME_FIX_TRUE@am__append_104 = plugins/systime_fix -@MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE@am__append_105 = plugins/systime_fix/libstrongswan-systime-fix.la -@USE_LED_TRUE@am__append_106 = plugins/led -@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_107 = plugins/led/libstrongswan-led.la -@USE_DUPLICHECK_TRUE@am__append_108 = plugins/duplicheck -@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_109 = plugins/duplicheck/libstrongswan-duplicheck.la -@USE_COUPLING_TRUE@am__append_110 = plugins/coupling -@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_111 = plugins/coupling/libstrongswan-coupling.la -@USE_RADATTR_TRUE@am__append_112 = plugins/radattr -@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_113 = plugins/radattr/libstrongswan-radattr.la -@USE_UCI_TRUE@am__append_114 = plugins/uci -@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_115 = plugins/uci/libstrongswan-uci.la -@USE_ADDRBLOCK_TRUE@am__append_116 = plugins/addrblock -@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_117 = plugins/addrblock/libstrongswan-addrblock.la -@USE_UNITY_TRUE@am__append_118 = plugins/unity -@MONOLITHIC_TRUE@@USE_UNITY_TRUE@am__append_119 = plugins/unity/libstrongswan-unity.la -@USE_UNIT_TESTS_TRUE@am__append_120 = plugins/unit_tester -@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_121 = plugins/unit_tester/libstrongswan-unit-tester.la -@USE_XAUTH_GENERIC_TRUE@am__append_122 = plugins/xauth_generic -@MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE@am__append_123 = plugins/xauth_generic/libstrongswan-xauth-generic.la -@USE_XAUTH_EAP_TRUE@am__append_124 = plugins/xauth_eap -@MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE@am__append_125 = plugins/xauth_eap/libstrongswan-xauth-eap.la -@USE_XAUTH_PAM_TRUE@am__append_126 = plugins/xauth_pam -@MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE@am__append_127 = plugins/xauth_pam/libstrongswan-xauth-pam.la -@USE_XAUTH_NOAUTH_TRUE@am__append_128 = plugins/xauth_noauth -@MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE@am__append_129 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la +@USE_EXT_AUTH_TRUE@am__append_30 = plugins/ext_auth +@MONOLITHIC_TRUE@@USE_EXT_AUTH_TRUE@am__append_31 = plugins/ext_auth/libstrongswan-ext-auth.la +@USE_EAP_IDENTITY_TRUE@am__append_32 = plugins/eap_identity +@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_33 = plugins/eap_identity/libstrongswan-eap-identity.la +@USE_EAP_SIM_TRUE@am__append_34 = plugins/eap_sim +@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_35 = plugins/eap_sim/libstrongswan-eap-sim.la +@USE_EAP_SIM_FILE_TRUE@am__append_36 = plugins/eap_sim_file +@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_37 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la +@USE_EAP_SIM_PCSC_TRUE@am__append_38 = plugins/eap_sim_pcsc +@MONOLITHIC_TRUE@@USE_EAP_SIM_PCSC_TRUE@am__append_39 = plugins/eap_sim_pcsc/libstrongswan-eap-sim-pcsc.la +@USE_EAP_SIMAKA_SQL_TRUE@am__append_40 = plugins/eap_simaka_sql +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_41 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la +@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_42 = plugins/eap_simaka_pseudonym +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_43 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la +@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_44 = plugins/eap_simaka_reauth +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_45 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la +@USE_EAP_AKA_TRUE@am__append_46 = plugins/eap_aka +@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_47 = plugins/eap_aka/libstrongswan-eap-aka.la +@USE_EAP_AKA_3GPP2_TRUE@am__append_48 = plugins/eap_aka_3gpp2 +@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_49 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la +@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_50 = $(top_builddir)/src/libsimaka/libsimaka.la +@USE_EAP_MD5_TRUE@am__append_51 = plugins/eap_md5 +@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_52 = plugins/eap_md5/libstrongswan-eap-md5.la +@USE_EAP_GTC_TRUE@am__append_53 = plugins/eap_gtc +@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_54 = plugins/eap_gtc/libstrongswan-eap-gtc.la +@USE_EAP_MSCHAPV2_TRUE@am__append_55 = plugins/eap_mschapv2 +@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_56 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la +@USE_EAP_DYNAMIC_TRUE@am__append_57 = plugins/eap_dynamic +@MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE@am__append_58 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la +@USE_EAP_RADIUS_TRUE@am__append_59 = plugins/eap_radius +@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_60 = plugins/eap_radius/libstrongswan-eap-radius.la +@USE_EAP_TLS_TRUE@am__append_61 = plugins/eap_tls +@MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE@am__append_62 = plugins/eap_tls/libstrongswan-eap-tls.la +@USE_EAP_TTLS_TRUE@am__append_63 = plugins/eap_ttls +@MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE@am__append_64 = plugins/eap_ttls/libstrongswan-eap-ttls.la +@USE_EAP_PEAP_TRUE@am__append_65 = plugins/eap_peap +@MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE@am__append_66 = plugins/eap_peap/libstrongswan-eap-peap.la +@USE_EAP_TNC_TRUE@am__append_67 = plugins/eap_tnc +@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_68 = plugins/eap_tnc/libstrongswan-eap-tnc.la +@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_69 = $(top_builddir)/src/libtls/libtls.la +@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@am__append_70 = $(top_builddir)/src/libradius/libradius.la +@USE_TNC_IFMAP_TRUE@am__append_71 = plugins/tnc_ifmap +@MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE@am__append_72 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la +@USE_TNC_PDP_TRUE@am__append_73 = plugins/tnc_pdp +@MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE@am__append_74 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la +@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@am__append_75 = $(top_builddir)/src/libtnccs/libtnccs.la +@USE_MEDSRV_TRUE@am__append_76 = plugins/medsrv +@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_77 = plugins/medsrv/libstrongswan-medsrv.la +@USE_MEDCLI_TRUE@am__append_78 = plugins/medcli +@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_79 = plugins/medcli/libstrongswan-medcli.la +@USE_DHCP_TRUE@am__append_80 = plugins/dhcp +@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_81 = plugins/dhcp/libstrongswan-dhcp.la +@USE_OSX_ATTR_TRUE@am__append_82 = plugins/osx_attr +@MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE@am__append_83 = plugins/osx_attr/libstrongswan-osx-attr.la +@USE_ANDROID_DNS_TRUE@am__append_84 = plugins/android_dns +@MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE@am__append_85 = plugins/android_dns/libstrongswan-android-dns.la +@USE_ANDROID_LOG_TRUE@am__append_86 = plugins/android_log +@MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE@am__append_87 = plugins/android_log/libstrongswan-android-log.la +@USE_MAEMO_TRUE@am__append_88 = plugins/maemo +@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_89 = plugins/maemo/libstrongswan-maemo.la +@USE_HA_TRUE@am__append_90 = plugins/ha +@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_91 = plugins/ha/libstrongswan-ha.la +@USE_KERNEL_LIBIPSEC_TRUE@am__append_92 = plugins/kernel_libipsec +@MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE@am__append_93 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la +@USE_KERNEL_WFP_TRUE@am__append_94 = plugins/kernel_wfp +@MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE@am__append_95 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la +@USE_KERNEL_IPH_TRUE@am__append_96 = plugins/kernel_iph +@MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE@am__append_97 = plugins/kernel_iph/libstrongswan-kernel-iph.la +@USE_WHITELIST_TRUE@am__append_98 = plugins/whitelist +@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_99 = plugins/whitelist/libstrongswan-whitelist.la +@USE_LOOKIP_TRUE@am__append_100 = plugins/lookip +@MONOLITHIC_TRUE@@USE_LOOKIP_TRUE@am__append_101 = plugins/lookip/libstrongswan-lookip.la +@USE_ERROR_NOTIFY_TRUE@am__append_102 = plugins/error_notify +@MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE@am__append_103 = plugins/error_notify/libstrongswan-error-notify.la +@USE_CERTEXPIRE_TRUE@am__append_104 = plugins/certexpire +@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_105 = plugins/certexpire/libstrongswan-certexpire.la +@USE_SYSTIME_FIX_TRUE@am__append_106 = plugins/systime_fix +@MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE@am__append_107 = plugins/systime_fix/libstrongswan-systime-fix.la +@USE_LED_TRUE@am__append_108 = plugins/led +@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_109 = plugins/led/libstrongswan-led.la +@USE_DUPLICHECK_TRUE@am__append_110 = plugins/duplicheck +@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_111 = plugins/duplicheck/libstrongswan-duplicheck.la +@USE_COUPLING_TRUE@am__append_112 = plugins/coupling +@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_113 = plugins/coupling/libstrongswan-coupling.la +@USE_RADATTR_TRUE@am__append_114 = plugins/radattr +@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_115 = plugins/radattr/libstrongswan-radattr.la +@USE_UCI_TRUE@am__append_116 = plugins/uci +@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_117 = plugins/uci/libstrongswan-uci.la +@USE_ADDRBLOCK_TRUE@am__append_118 = plugins/addrblock +@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_119 = plugins/addrblock/libstrongswan-addrblock.la +@USE_UNITY_TRUE@am__append_120 = plugins/unity +@MONOLITHIC_TRUE@@USE_UNITY_TRUE@am__append_121 = plugins/unity/libstrongswan-unity.la +@USE_UNIT_TESTS_TRUE@am__append_122 = plugins/unit_tester +@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_123 = plugins/unit_tester/libstrongswan-unit-tester.la +@USE_XAUTH_GENERIC_TRUE@am__append_124 = plugins/xauth_generic +@MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE@am__append_125 = plugins/xauth_generic/libstrongswan-xauth-generic.la +@USE_XAUTH_EAP_TRUE@am__append_126 = plugins/xauth_eap +@MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE@am__append_127 = plugins/xauth_eap/libstrongswan-xauth-eap.la +@USE_XAUTH_PAM_TRUE@am__append_128 = plugins/xauth_pam +@MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE@am__append_129 = plugins/xauth_pam/libstrongswan-xauth-pam.la +@USE_XAUTH_NOAUTH_TRUE@am__append_130 = plugins/xauth_noauth +@MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE@am__append_131 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la subdir = src/libcharon DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -323,12 +325,12 @@ libcharon_la_DEPENDENCIES = \ $(am__append_29) $(am__append_31) $(am__append_33) \ $(am__append_35) $(am__append_37) $(am__append_39) \ $(am__append_41) $(am__append_43) $(am__append_45) \ - $(am__append_47) $(am__append_48) $(am__append_50) \ + $(am__append_47) $(am__append_49) $(am__append_50) \ $(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_67) \ - $(am__append_68) $(am__append_70) $(am__append_72) \ - $(am__append_73) $(am__append_75) $(am__append_77) \ + $(am__append_64) $(am__append_66) $(am__append_68) \ + $(am__append_69) $(am__append_70) $(am__append_72) \ + $(am__append_74) $(am__append_75) $(am__append_77) \ $(am__append_79) $(am__append_81) $(am__append_83) \ $(am__append_85) $(am__append_87) $(am__append_89) \ $(am__append_91) $(am__append_93) $(am__append_95) \ @@ -337,7 +339,7 @@ libcharon_la_DEPENDENCIES = \ $(am__append_109) $(am__append_111) $(am__append_113) \ $(am__append_115) $(am__append_117) $(am__append_119) \ $(am__append_121) $(am__append_123) $(am__append_125) \ - $(am__append_127) $(am__append_129) + $(am__append_127) $(am__append_129) $(am__append_131) am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ bus/listeners/listener.h bus/listeners/logger.h \ bus/listeners/file_logger.c bus/listeners/file_logger.h \ @@ -362,8 +364,9 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ encoding/payloads/eap_payload.c \ encoding/payloads/eap_payload.h encoding/payloads/encodings.c \ encoding/payloads/encodings.h \ - encoding/payloads/encryption_payload.c \ - encoding/payloads/encryption_payload.h \ + encoding/payloads/encrypted_payload.c \ + encoding/payloads/encrypted_payload.h \ + encoding/payloads/encrypted_fragment_payload.h \ encoding/payloads/id_payload.c encoding/payloads/id_payload.h \ encoding/payloads/ike_header.c encoding/payloads/ike_header.h \ encoding/payloads/ke_payload.c encoding/payloads/ke_payload.h \ @@ -553,7 +556,7 @@ am_libcharon_la_OBJECTS = bus/bus.lo bus/listeners/file_logger.lo \ encoding/payloads/delete_payload.lo \ encoding/payloads/eap_payload.lo \ encoding/payloads/encodings.lo \ - encoding/payloads/encryption_payload.lo \ + encoding/payloads/encrypted_payload.lo \ encoding/payloads/id_payload.lo \ encoding/payloads/ike_header.lo \ encoding/payloads/ke_payload.lo \ @@ -676,22 +679,23 @@ DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \ plugins/socket_dynamic plugins/socket_win plugins/farp \ plugins/stroke plugins/vici plugins/smp plugins/sql \ plugins/dnscert plugins/ipseckey plugins/updown \ - plugins/eap_identity plugins/eap_sim plugins/eap_sim_file \ - plugins/eap_sim_pcsc 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_dynamic \ - plugins/eap_radius plugins/eap_tls plugins/eap_ttls \ - plugins/eap_peap plugins/eap_tnc plugins/tnc_ifmap \ - plugins/tnc_pdp plugins/medsrv plugins/medcli plugins/dhcp \ - plugins/osx_attr plugins/android_dns plugins/android_log \ - plugins/maemo plugins/ha plugins/kernel_libipsec \ - plugins/kernel_wfp plugins/kernel_iph plugins/whitelist \ - plugins/lookip plugins/error_notify plugins/certexpire \ - plugins/systime_fix plugins/led plugins/duplicheck \ - plugins/coupling plugins/radattr plugins/uci plugins/addrblock \ - plugins/unity plugins/unit_tester plugins/xauth_generic \ - plugins/xauth_eap plugins/xauth_pam plugins/xauth_noauth + plugins/ext_auth plugins/eap_identity plugins/eap_sim \ + plugins/eap_sim_file plugins/eap_sim_pcsc \ + 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_dynamic plugins/eap_radius \ + plugins/eap_tls plugins/eap_ttls plugins/eap_peap \ + plugins/eap_tnc plugins/tnc_ifmap plugins/tnc_pdp \ + plugins/medsrv plugins/medcli plugins/dhcp plugins/osx_attr \ + plugins/android_dns plugins/android_log plugins/maemo \ + plugins/ha plugins/kernel_libipsec plugins/kernel_wfp \ + plugins/kernel_iph plugins/whitelist plugins/lookip \ + plugins/error_notify plugins/certexpire plugins/systime_fix \ + plugins/led plugins/duplicheck plugins/coupling \ + plugins/radattr plugins/uci plugins/addrblock plugins/unity \ + plugins/unit_tester plugins/xauth_generic plugins/xauth_eap \ + plugins/xauth_pam plugins/xauth_noauth DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -749,6 +753,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -809,6 +814,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -874,6 +880,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -921,6 +929,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ @@ -954,8 +966,9 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ encoding/payloads/eap_payload.c \ encoding/payloads/eap_payload.h encoding/payloads/encodings.c \ encoding/payloads/encodings.h \ - encoding/payloads/encryption_payload.c \ - encoding/payloads/encryption_payload.h \ + encoding/payloads/encrypted_payload.c \ + encoding/payloads/encrypted_payload.h \ + encoding/payloads/encrypted_fragment_payload.h \ encoding/payloads/id_payload.c encoding/payloads/id_payload.h \ encoding/payloads/ike_header.c encoding/payloads/ike_header.h \ encoding/payloads/ke_payload.c encoding/payloads/ke_payload.h \ @@ -1043,12 +1056,12 @@ libcharon_la_LIBADD = \ $(am__append_27) $(am__append_29) $(am__append_31) \ $(am__append_33) $(am__append_35) $(am__append_37) \ $(am__append_39) $(am__append_41) $(am__append_43) \ - $(am__append_45) $(am__append_47) $(am__append_48) \ + $(am__append_45) $(am__append_47) $(am__append_49) \ $(am__append_50) $(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_67) $(am__append_68) $(am__append_70) \ - $(am__append_72) $(am__append_73) $(am__append_75) \ + $(am__append_68) $(am__append_69) $(am__append_70) \ + $(am__append_72) $(am__append_74) $(am__append_75) \ $(am__append_77) $(am__append_79) $(am__append_81) \ $(am__append_83) $(am__append_85) $(am__append_87) \ $(am__append_89) $(am__append_91) $(am__append_93) \ @@ -1057,7 +1070,8 @@ libcharon_la_LIBADD = \ $(am__append_107) $(am__append_109) $(am__append_111) \ $(am__append_113) $(am__append_115) $(am__append_117) \ $(am__append_119) $(am__append_121) $(am__append_123) \ - $(am__append_125) $(am__append_127) $(am__append_129) + $(am__append_125) $(am__append_127) $(am__append_129) \ + $(am__append_131) EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@SUBDIRS = . $(am__append_6) $(am__append_8) \ @MONOLITHIC_FALSE@ $(am__append_10) $(am__append_12) \ @@ -1069,13 +1083,13 @@ EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@ $(am__append_34) $(am__append_36) \ @MONOLITHIC_FALSE@ $(am__append_38) $(am__append_40) \ @MONOLITHIC_FALSE@ $(am__append_42) $(am__append_44) \ -@MONOLITHIC_FALSE@ $(am__append_46) $(am__append_49) \ +@MONOLITHIC_FALSE@ $(am__append_46) $(am__append_48) \ @MONOLITHIC_FALSE@ $(am__append_51) $(am__append_53) \ @MONOLITHIC_FALSE@ $(am__append_55) $(am__append_57) \ @MONOLITHIC_FALSE@ $(am__append_59) $(am__append_61) \ @MONOLITHIC_FALSE@ $(am__append_63) $(am__append_65) \ -@MONOLITHIC_FALSE@ $(am__append_69) $(am__append_71) \ -@MONOLITHIC_FALSE@ $(am__append_74) $(am__append_76) \ +@MONOLITHIC_FALSE@ $(am__append_67) $(am__append_71) \ +@MONOLITHIC_FALSE@ $(am__append_73) $(am__append_76) \ @MONOLITHIC_FALSE@ $(am__append_78) $(am__append_80) \ @MONOLITHIC_FALSE@ $(am__append_82) $(am__append_84) \ @MONOLITHIC_FALSE@ $(am__append_86) $(am__append_88) \ @@ -1088,7 +1102,8 @@ EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@ $(am__append_114) $(am__append_116) \ @MONOLITHIC_FALSE@ $(am__append_118) $(am__append_120) \ @MONOLITHIC_FALSE@ $(am__append_122) $(am__append_124) \ -@MONOLITHIC_FALSE@ $(am__append_126) $(am__append_128) +@MONOLITHIC_FALSE@ $(am__append_126) $(am__append_128) \ +@MONOLITHIC_FALSE@ $(am__append_130) # build optional plugins ######################## @@ -1102,13 +1117,13 @@ EXTRA_DIST = Android.mk @MONOLITHIC_TRUE@ $(am__append_34) $(am__append_36) \ @MONOLITHIC_TRUE@ $(am__append_38) $(am__append_40) \ @MONOLITHIC_TRUE@ $(am__append_42) $(am__append_44) \ -@MONOLITHIC_TRUE@ $(am__append_46) $(am__append_49) \ +@MONOLITHIC_TRUE@ $(am__append_46) $(am__append_48) \ @MONOLITHIC_TRUE@ $(am__append_51) $(am__append_53) \ @MONOLITHIC_TRUE@ $(am__append_55) $(am__append_57) \ @MONOLITHIC_TRUE@ $(am__append_59) $(am__append_61) \ @MONOLITHIC_TRUE@ $(am__append_63) $(am__append_65) \ -@MONOLITHIC_TRUE@ $(am__append_69) $(am__append_71) \ -@MONOLITHIC_TRUE@ $(am__append_74) $(am__append_76) \ +@MONOLITHIC_TRUE@ $(am__append_67) $(am__append_71) \ +@MONOLITHIC_TRUE@ $(am__append_73) $(am__append_76) \ @MONOLITHIC_TRUE@ $(am__append_78) $(am__append_80) \ @MONOLITHIC_TRUE@ $(am__append_82) $(am__append_84) \ @MONOLITHIC_TRUE@ $(am__append_86) $(am__append_88) \ @@ -1121,7 +1136,8 @@ EXTRA_DIST = Android.mk @MONOLITHIC_TRUE@ $(am__append_114) $(am__append_116) \ @MONOLITHIC_TRUE@ $(am__append_118) $(am__append_120) \ @MONOLITHIC_TRUE@ $(am__append_122) $(am__append_124) \ -@MONOLITHIC_TRUE@ $(am__append_126) $(am__append_128) +@MONOLITHIC_TRUE@ $(am__append_126) $(am__append_128) \ +@MONOLITHIC_TRUE@ $(am__append_130) all: all-recursive .SUFFIXES: @@ -1267,7 +1283,7 @@ encoding/payloads/eap_payload.lo: encoding/payloads/$(am__dirstamp) \ encoding/payloads/$(DEPDIR)/$(am__dirstamp) encoding/payloads/encodings.lo: encoding/payloads/$(am__dirstamp) \ encoding/payloads/$(DEPDIR)/$(am__dirstamp) -encoding/payloads/encryption_payload.lo: \ +encoding/payloads/encrypted_payload.lo: \ encoding/payloads/$(am__dirstamp) \ encoding/payloads/$(DEPDIR)/$(am__dirstamp) encoding/payloads/id_payload.lo: encoding/payloads/$(am__dirstamp) \ @@ -1619,7 +1635,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/delete_payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/eap_payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/encodings.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/encryption_payload.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/encrypted_payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/endpoint_notify.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/fragment_payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/hash_payload.Plo@am__quote@ diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index d1c138cd1..cb59f976b 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -755,7 +755,7 @@ METHOD(bus_t, ike_rekey, void, this->mutex->unlock(this->mutex); } -METHOD(bus_t, ike_reestablish, void, +METHOD(bus_t, ike_reestablish_pre, void, private_bus_t *this, ike_sa_t *old, ike_sa_t *new) { enumerator_t *enumerator; @@ -766,12 +766,40 @@ METHOD(bus_t, ike_reestablish, void, enumerator = this->listeners->create_enumerator(this->listeners); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->calling || !entry->listener->ike_reestablish) + if (entry->calling || !entry->listener->ike_reestablish_pre) { continue; } entry->calling++; - keep = entry->listener->ike_reestablish(entry->listener, old, new); + keep = entry->listener->ike_reestablish_pre(entry->listener, old, new); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +METHOD(bus_t, ike_reestablish_post, void, + private_bus_t *this, ike_sa_t *old, ike_sa_t *new, bool initiated) +{ + enumerator_t *enumerator; + entry_t *entry; + bool keep; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->ike_reestablish_post) + { + continue; + } + entry->calling++; + keep = entry->listener->ike_reestablish_post(entry->listener, old, new, + initiated); entry->calling--; if (!keep) { @@ -978,7 +1006,8 @@ bus_t *bus_create() .child_keys = _child_keys, .ike_updown = _ike_updown, .ike_rekey = _ike_rekey, - .ike_reestablish = _ike_reestablish, + .ike_reestablish_pre = _ike_reestablish_pre, + .ike_reestablish_post = _ike_reestablish_post, .child_updown = _child_updown, .child_rekey = _child_rekey, .authorize = _authorize, diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h index 1d708c5a5..e1d221ca5 100644 --- a/src/libcharon/bus/bus.h +++ b/src/libcharon/bus/bus.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2006-2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -101,9 +101,11 @@ enum alert_t { /** received IKE message with invalid body, argument is message_t*, * followed by a status_t result returned by message_t.parse_body(). */ ALERT_PARSE_ERROR_BODY, - /** sending a retransmit for a message, argument is packet_t */ + /** sending a retransmit for a message, argument is packet_t, if the message + * got fragmented only the first fragment is passed */ ALERT_RETRANSMIT_SEND, - /** sending retransmits timed out, argument is packet_t, if available */ + /** sending retransmits timed out, argument is packet_t, if available and if + * the message got fragmented only the first fragment is passed */ ALERT_RETRANSMIT_SEND_TIMEOUT, /** received a retransmit for a message, argument is message_t */ ALERT_RETRANSMIT_RECEIVE, @@ -380,12 +382,23 @@ struct bus_t { void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new); /** - * IKE_SA reestablishing hook. + * IKE_SA reestablishing hook (before resolving hosts). * * @param old reestablished and obsolete IKE_SA * @param new new IKE_SA replacing old */ - void (*ike_reestablish)(bus_t *this, ike_sa_t *old, ike_sa_t *new); + void (*ike_reestablish_pre)(bus_t *this, ike_sa_t *old, ike_sa_t *new); + + /** + * IKE_SA reestablishing hook (after configuring and initiating the new + * IKE_SA). + * + * @param old reestablished and obsolete IKE_SA + * @param new new IKE_SA replacing old + * @param initiated TRUE if initiated successfully, FALSE otherwise + */ + void (*ike_reestablish_post)(bus_t *this, ike_sa_t *old, ike_sa_t *new, + bool initiated); /** * CHILD_SA up/down hook. diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h index abcc765e5..0910cb361 100644 --- a/src/libcharon/bus/listeners/listener.h +++ b/src/libcharon/bus/listeners/listener.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2011-2014 Tobias Brunner * Copyright (C) 2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -126,6 +127,19 @@ struct listener_t { */ bool (*ike_rekey)(listener_t *this, ike_sa_t *old, ike_sa_t *new); + /** + * Hook called when an initiator reestablishes an IKE_SA. + * + * This is invoked right after creating the new IKE_SA and setting the + * peer_cfg (and the old hosts), but before resolving the hosts anew. + * It is not invoked on the responder. + * + * @param old IKE_SA getting reestablished (is destroyed) + * @param new new IKE_SA replacing old (gets established) + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*ike_reestablish_pre)(listener_t *this, ike_sa_t *old, ike_sa_t *new); + /** * Hook called when an initiator reestablishes an IKE_SA. * @@ -134,9 +148,11 @@ struct listener_t { * * @param old IKE_SA getting reestablished (is destroyed) * @param new new IKE_SA replacing old (gets established) + * @param initiated TRUE if initiation was successful, FALSE otherwise * @return TRUE to stay registered, FALSE to unregister */ - bool (*ike_reestablish)(listener_t *this, ike_sa_t *old, ike_sa_t *new); + bool (*ike_reestablish_post)(listener_t *this, ike_sa_t *old, + ike_sa_t *new, bool initiated); /** * Hook called when a CHILD_SA gets up or down. diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c index 7e4a1433d..ed7c0d406 100644 --- a/src/libcharon/config/child_cfg.c +++ b/src/libcharon/config/child_cfg.c @@ -163,6 +163,11 @@ METHOD(child_cfg_t, add_proposal, void, } } +static bool match_proposal(proposal_t *item, proposal_t *proposal) +{ + return item->equals(item, proposal); +} + METHOD(child_cfg_t, get_proposals, linked_list_t*, private_child_cfg_t *this, bool strip_dh) { @@ -178,6 +183,12 @@ METHOD(child_cfg_t, get_proposals, linked_list_t*, { current->strip_dh(current, MODP_NONE); } + if (proposals->find_first(proposals, (linked_list_match_t)match_proposal, + NULL, current) == SUCCESS) + { + current->destroy(current); + continue; + } proposals->insert_last(proposals, current); } enumerator->destroy(enumerator); diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index 4d881cd2f..50d3c6f66 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -337,7 +337,7 @@ static bool algo_list_equals(private_proposal_t *this, proposal_t *other, break; } } - if (e2->enumerate(e2, &alg2, ks2)) + if (e2->enumerate(e2, &alg2, &ks2)) { /* other has more algs */ equals = FALSE; @@ -594,7 +594,7 @@ METHOD(proposal_t, destroy, void, } /* - * Describtion in header-file + * Described in header */ proposal_t *proposal_create(protocol_id_t protocol, u_int number) { @@ -787,7 +787,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) } /* - * Describtion in header-file + * Described in header */ proposal_t *proposal_create_default(protocol_id_t protocol) { @@ -826,7 +826,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol) } /* - * Describtion in header-file + * Described in header */ proposal_t *proposal_create_default_aead(protocol_id_t protocol) { @@ -853,7 +853,7 @@ proposal_t *proposal_create_default_aead(protocol_id_t protocol) } /* - * Describtion in header-file + * Described in header */ proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs) { diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index a89995a51..3ae7c4e6f 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -593,7 +593,7 @@ METHOD(daemon_t, initialize, bool, PLUGIN_DEPENDS(CUSTOM, "socket"), }; lib->plugins->add_static_features(lib->plugins, lib->ns, features, - countof(features), TRUE); + countof(features), TRUE, NULL, NULL); /* load plugins, further infrastructure may need it */ if (!lib->plugins->load(lib->plugins, plugins)) diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 0f5f40ada..cb6c97f25 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2013 Tobias Brunner + * Copyright (C) 2006-2014 Tobias Brunner * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2010 revosec AG * Copyright (C) 2006 Daniel Roethlisberger @@ -23,6 +23,8 @@ #include "message.h" #include +#include +#include #include #include #include @@ -30,9 +32,11 @@ #include #include #include -#include +#include +#include #include #include +#include /** * Max number of notify payloads per IKEv2 message @@ -802,6 +806,30 @@ static message_rule_t message_rules[] = { #endif /* USE_IKEV1 */ }; +/** + * Data for fragment reassembly. + */ +typedef struct { + + /** + * For IKEv1 the number of the last fragment (in case we receive them out + * of order), since the first one starts with 1 this defines the number of + * fragments we expect. + * For IKEv2 we store the total number of fragment we received last. + */ + u_int16_t last; + + /** + * Length of all currently received fragments. + */ + size_t len; + + /** + * Maximum length of a fragmented packet. + */ + size_t max_packet; + +} fragment_data_t; typedef struct private_message_t private_message_t; @@ -875,6 +903,12 @@ struct private_message_t { */ packet_t *packet; + /** + * Array of generated fragments (if any), as packet_t*. + * If defragmenting (i.e. frag != NULL) this contains fragment_t* + */ + array_t *fragments; + /** * Linked List where payload data are stored in. */ @@ -889,8 +923,45 @@ struct private_message_t { * The message rule for this message instance */ message_rule_t *rule; + + /** + * Data used to reassemble a fragmented message + */ + fragment_data_t *frag; }; +/** + * Maximum number of fragments we will handle + */ +#define MAX_FRAGMENTS 255 + +/** + * A single fragment within a fragmented message + */ +typedef struct { + + /** fragment number */ + u_int8_t num; + + /** fragment data */ + chunk_t data; + +} fragment_t; + +static void fragment_destroy(fragment_t *this) +{ + chunk_free(&this->data); + free(this); +} + +static void reset_defrag(private_message_t *this) +{ + array_destroy_function(this->fragments, (void*)fragment_destroy, NULL); + this->fragments = NULL; + this->frag->last = 0; + this->frag->len = 0; +} + /** * Get the message rule that applies to this message */ @@ -1049,6 +1120,12 @@ METHOD(message_t, is_encoded, bool, return this->packet->get_data(this->packet).ptr != NULL; } +METHOD(message_t, is_fragmented, bool, + private_message_t *this) +{ + return array_count(this->fragments) > 0; +} + METHOD(message_t, add_payload, void, private_message_t *this, payload_t *payload) { @@ -1330,6 +1407,12 @@ static char* get_string(private_message_t *this, char *buf, int len) return buf; } +METHOD(message_t, disable_sort, void, + private_message_t *this) +{ + this->sort_disabled = TRUE; +} + /** * reorder payloads depending on reordering rules */ @@ -1339,6 +1422,8 @@ static void order_payloads(private_message_t *this) payload_t *payload; int i; + DBG2(DBG_ENC, "order payloads in message"); + /* move to temp list */ list = linked_list_create(); while (this->payloads->remove_last(this->payloads, @@ -1392,29 +1477,42 @@ static void order_payloads(private_message_t *this) } /** - * Wrap payloads in an encryption payload + * Wrap payloads in an encrypted payload */ -static encryption_payload_t* wrap_payloads(private_message_t *this) +static encrypted_payload_t* wrap_payloads(private_message_t *this) { - encryption_payload_t *encryption; + encrypted_payload_t *encrypted = NULL; linked_list_t *payloads; payload_t *current; - /* copy all payloads in a temporary list */ + /* move all payloads to a temporary list */ payloads = linked_list_create(); while (this->payloads->remove_first(this->payloads, (void**)¤t) == SUCCESS) { - payloads->insert_last(payloads, current); + if (current->get_type(current) == PLV2_FRAGMENT) + { /* treat encrypted fragment payload as encrypted payload */ + encrypted = (encrypted_payload_t*)current; + } + else + { + payloads->insert_last(payloads, current); + } + } + if (encrypted) + { /* simply adopt all the unencrypted payloads */ + this->payloads->destroy(this->payloads); + this->payloads = payloads; + return encrypted; } if (this->is_encrypted) { - encryption = encryption_payload_create(PLV1_ENCRYPTED); + encrypted = encrypted_payload_create(PLV1_ENCRYPTED); } else { - encryption = encryption_payload_create(PLV2_ENCRYPTED); + encrypted = encrypted_payload_create(PLV2_ENCRYPTED); } while (payloads->remove_first(payloads, (void**)¤t) == SUCCESS) { @@ -1432,7 +1530,7 @@ static encryption_payload_t* wrap_payloads(private_message_t *this) { /* encryption is forced for IKEv1 */ DBG2(DBG_ENC, "insert payload %N into encrypted payload", payload_type_names, type); - encryption->add_payload(encryption, current); + encrypted->add_payload(encrypted, current); } else { @@ -1443,31 +1541,71 @@ static encryption_payload_t* wrap_payloads(private_message_t *this) } payloads->destroy(payloads); - return encryption; + return encrypted; } -METHOD(message_t, disable_sort, void, - private_message_t *this) +/** + * Creates the IKE header for this message + */ +static ike_header_t *create_header(private_message_t *this) { - this->sort_disabled = TRUE; + ike_header_t *ike_header; + bool *reserved; + int i; + + ike_header = ike_header_create_version(this->major_version, + this->minor_version); + ike_header->set_exchange_type(ike_header, this->exchange_type); + ike_header->set_message_id(ike_header, this->message_id); + if (this->major_version == IKEV2_MAJOR_VERSION) + { + ike_header->set_response_flag(ike_header, !this->is_request); + ike_header->set_version_flag(ike_header, this->version_flag); + ike_header->set_initiator_flag(ike_header, + this->ike_sa_id->is_initiator(this->ike_sa_id)); + } + else + { + ike_header->set_encryption_flag(ike_header, this->is_encrypted); + } + ike_header->set_initiator_spi(ike_header, + this->ike_sa_id->get_initiator_spi(this->ike_sa_id)); + ike_header->set_responder_spi(ike_header, + this->ike_sa_id->get_responder_spi(this->ike_sa_id)); + + for (i = 0; i < countof(this->reserved); i++) + { + reserved = payload_get_field(&ike_header->payload_interface, + RESERVED_BIT, i); + if (reserved) + { + *reserved = this->reserved[i]; + } + } + return ike_header; } -METHOD(message_t, generate, status_t, - private_message_t *this, keymat_t *keymat, packet_t **packet) +/** + * Generates the message, if needed, wraps the payloads in an encrypted payload. + * + * The generator and the possible enrypted payload are returned. The latter + * is not yet encrypted (but the transform is set). It is also not added to + * the payload list (so unless there are unencrypted payloads that list will + * be empty afterwards). + */ +static status_t generate_message(private_message_t *this, keymat_t *keymat, + generator_t **out_generator, encrypted_payload_t **encrypted) { keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat; generator_t *generator; - ike_header_t *ike_header; - payload_t *payload, *next; - encryption_payload_t *encryption = NULL; payload_type_t next_type; enumerator_t *enumerator; aead_t *aead = NULL; - chunk_t chunk, hash = chunk_empty; + chunk_t hash = chunk_empty; char str[BUF_LEN]; - u_int32_t *lenpos; - bool encrypted = FALSE, *reserved; - int i; + ike_header_t *ike_header; + payload_t *payload, *next; + bool encrypting = FALSE; if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED) { @@ -1493,6 +1631,7 @@ METHOD(message_t, generate, status_t, { order_payloads(this); } + if (keymat && keymat->get_version(keymat) == IKEV1) { /* get a hash for this message, if any is required */ @@ -1505,16 +1644,17 @@ METHOD(message_t, generate, status_t, this->payloads->insert_first(this->payloads, hash_payload); if (this->exchange_type == INFORMATIONAL_V1) { - this->is_encrypted = encrypted = TRUE; + this->is_encrypted = encrypting = TRUE; } chunk_free(&hash); } } + if (this->major_version == IKEV2_MAJOR_VERSION) { - encrypted = this->rule->encrypted; + encrypting = this->rule->encrypted; } - else if (!encrypted) + else if (!encrypting) { /* If at least one payload requires encryption, encrypt the message. * If no key material is available, the flag will be reset below. */ @@ -1526,7 +1666,7 @@ METHOD(message_t, generate, status_t, rule = get_payload_rule(this, payload->get_type(payload)); if (rule && rule->encrypted) { - this->is_encrypted = encrypted = TRUE; + this->is_encrypted = encrypting = TRUE; break; } } @@ -1539,9 +1679,10 @@ METHOD(message_t, generate, status_t, { aead = keymat->get_aead(keymat, FALSE); } - if (aead && encrypted) + if (aead && encrypting) { - encryption = wrap_payloads(this); + *encrypted = wrap_payloads(this); + (*encrypted)->set_transform(*encrypted, aead); } else { @@ -1549,39 +1690,9 @@ METHOD(message_t, generate, status_t, this->is_encrypted = FALSE; } - ike_header = ike_header_create_version(this->major_version, - this->minor_version); - ike_header->set_exchange_type(ike_header, this->exchange_type); - ike_header->set_message_id(ike_header, this->message_id); - if (this->major_version == IKEV2_MAJOR_VERSION) - { - ike_header->set_response_flag(ike_header, !this->is_request); - ike_header->set_version_flag(ike_header, this->version_flag); - ike_header->set_initiator_flag(ike_header, - this->ike_sa_id->is_initiator(this->ike_sa_id)); - } - else - { - ike_header->set_encryption_flag(ike_header, this->is_encrypted); - } - ike_header->set_initiator_spi(ike_header, - this->ike_sa_id->get_initiator_spi(this->ike_sa_id)); - ike_header->set_responder_spi(ike_header, - this->ike_sa_id->get_responder_spi(this->ike_sa_id)); - - for (i = 0; i < countof(this->reserved); i++) - { - reserved = payload_get_field(&ike_header->payload_interface, - RESERVED_BIT, i); - if (reserved) - { - *reserved = this->reserved[i]; - } - } - - generator = generator_create(); - /* generate all payloads with proper next type */ + *out_generator = generator = generator_create(); + ike_header = create_header(this); payload = (payload_t*)ike_header; enumerator = create_payload_enumerator(this); while (enumerator->enumerate(enumerator, &next)) @@ -1591,53 +1702,71 @@ METHOD(message_t, generate, status_t, payload = next; } enumerator->destroy(enumerator); + + next_type = PL_NONE; if (this->is_encrypted) { /* for encrypted IKEv1 messages */ - next_type = encryption->payload_interface.get_next_type( - (payload_t*)encryption); + next_type = (*encrypted)->payload_interface.get_next_type( + (payload_t*)*encrypted); } - else - { - next_type = encryption ? PLV2_ENCRYPTED : PL_NONE; + else if (*encrypted) + { /* use proper IKEv2 encrypted (fragment) payload type */ + next_type = (*encrypted)->payload_interface.get_type( + (payload_t*)*encrypted); } payload->set_next_type(payload, next_type); generator->generate_payload(generator, payload); ike_header->destroy(ike_header); + return SUCCESS; +} - if (encryption) - { /* set_transform() has to be called before get_length() */ - encryption->set_transform(encryption, aead); +/** + * Encrypts and adds the encrypted payload (if any) to the payload list and + * finalizes the message generation. Destroys the given generator. + */ +static status_t finalize_message(private_message_t *this, keymat_t *keymat, + generator_t *generator, encrypted_payload_t *encrypted) +{ + keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat; + chunk_t chunk; + u_int32_t *lenpos; + + if (encrypted) + { if (this->is_encrypted) { /* for IKEv1 instead of associated data we provide the IV */ if (!keymat_v1->get_iv(keymat_v1, this->message_id, &chunk)) { generator->destroy(generator); + encrypted->destroy(encrypted); return FAILED; } } else - { /* build associated data (without header of encryption payload) */ + { /* build associated data (without header of encrypted payload) */ chunk = generator->get_chunk(generator, &lenpos); - /* fill in length, including encryption payload */ - htoun32(lenpos, chunk.len + encryption->get_length(encryption)); + /* fill in length, including encrypted payload */ + htoun32(lenpos, chunk.len + encrypted->get_length(encrypted)); } - this->payloads->insert_last(this->payloads, encryption); - if (encryption->encrypt(encryption, this->message_id, chunk) != SUCCESS) + this->payloads->insert_last(this->payloads, encrypted); + if (encrypted->encrypt(encrypted, this->message_id, chunk) != SUCCESS) { generator->destroy(generator); return INVALID_STATE; } - generator->generate_payload(generator, &encryption->payload_interface); + generator->generate_payload(generator, &encrypted->payload_interface); } chunk = generator->get_chunk(generator, &lenpos); htoun32(lenpos, chunk.len); this->packet->set_data(this->packet, chunk_clone(chunk)); - if (this->is_encrypted) + if (this->is_encrypted && this->exchange_type != INFORMATIONAL_V1) { /* update the IV for the next IKEv1 message */ chunk_t last_block; + aead_t *aead; size_t bs; + aead = keymat->get_aead(keymat, FALSE); bs = aead->get_block_size(aead); last_block = chunk_create(chunk.ptr + chunk.len - bs, bs); if (!keymat_v1->update_iv(keymat_v1, this->message_id, last_block) || @@ -1648,30 +1777,301 @@ METHOD(message_t, generate, status_t, } } generator->destroy(generator); - *packet = this->packet->clone(this->packet); return SUCCESS; } -METHOD(message_t, get_packet, packet_t*, - private_message_t *this) +METHOD(message_t, generate, status_t, + private_message_t *this, keymat_t *keymat, packet_t **packet) { - if (this->packet == NULL) + generator_t *generator = NULL; + encrypted_payload_t *encrypted = NULL; + status_t status; + + status = generate_message(this, keymat, &generator, &encrypted); + if (status != SUCCESS) { - return NULL; + DESTROY_IF(generator); + return status; + } + status = finalize_message(this, keymat, generator, encrypted); + if (status != SUCCESS) + { + return status; + } + if (packet) + { + *packet = this->packet->clone(this->packet); + } + return SUCCESS; +} + +/** + * Creates a (basic) clone of the given message + */ +static message_t *clone_message(private_message_t *this) +{ + message_t *message; + host_t *src, *dst; + + src = this->packet->get_source(this->packet); + dst = this->packet->get_destination(this->packet); + + message = message_create(this->major_version, this->minor_version); + message->set_ike_sa_id(message, this->ike_sa_id); + message->set_message_id(message, this->message_id); + message->set_request(message, this->is_request); + message->set_source(message, src->clone(src)); + message->set_destination(message, dst->clone(dst)); + message->set_exchange_type(message, this->exchange_type); + memcpy(((private_message_t*)message)->reserved, this->reserved, + sizeof(this->reserved)); + return message; +} + +/** + * Create a single fragment with the given data + */ +static message_t *create_fragment(private_message_t *this, payload_type_t next, + u_int16_t num, u_int16_t count, chunk_t data) +{ + enumerator_t *enumerator; + payload_t *fragment, *payload; + message_t *message; + peer_cfg_t *peer_cfg; + ike_sa_t *ike_sa; + + message = clone_message(this); + if (this->major_version == IKEV1_MAJOR_VERSION) + { + /* other implementations seem to just use 0 as message ID, so here we go */ + message->set_message_id(message, 0); + /* always use the initial message type for fragments, even for quick mode + * or transaction messages. */ + ike_sa = charon->bus->get_sa(charon->bus); + if (ike_sa && (peer_cfg = ike_sa->get_peer_cfg(ike_sa)) && + peer_cfg->use_aggressive(peer_cfg)) + { + message->set_exchange_type(message, AGGRESSIVE); + } + else + { + message->set_exchange_type(message, ID_PROT); + } + fragment = (payload_t*)fragment_payload_create_from_data( + num, num == count, data); + } + else + { + fragment = (payload_t*)encrypted_fragment_payload_create_from_data( + num, count, data); + if (num == 1) + { + /* only in the first fragment is this set to the type of the first + * payload in the encrypted payload */ + fragment->set_next_type(fragment, next); + /* move unencrypted payloads to the first fragment */ + enumerator = this->payloads->create_enumerator(this->payloads); + while (enumerator->enumerate(enumerator, &payload)) + { + if (payload->get_type(payload) != PLV2_ENCRYPTED) + { + this->payloads->remove_at(this->payloads, enumerator); + message->add_payload(message, payload); + } + } + enumerator->destroy(enumerator); + } + } + message->add_payload(message, (payload_t*)fragment); + return message; +} + +/** + * Destroy all fragments + */ +static void clear_fragments(private_message_t *this) +{ + array_destroy_offset(this->fragments, offsetof(packet_t, destroy)); + this->fragments = NULL; +} + +/** + * Reduce the fragment length but ensure it stays > 0 + */ +#define REDUCE_FRAG_LEN(fl, amount) ({ \ + fl = max(1, (ssize_t)fl - (amount)); \ +}) + +METHOD(message_t, fragment, status_t, + private_message_t *this, keymat_t *keymat, size_t frag_len, + enumerator_t **fragments) +{ + encrypted_payload_t *encrypted = NULL; + generator_t *generator = NULL; + message_t *fragment; + packet_t *packet; + payload_type_t next = PL_NONE; + u_int16_t num, count; + host_t *src, *dst; + chunk_t data; + status_t status; + u_int32_t *lenpos; + size_t len; + + src = this->packet->get_source(this->packet); + dst = this->packet->get_destination(this->packet); + if (!frag_len) + { + frag_len = (src->get_family(src) == AF_INET) ? 576 : 1280; + } + /* frag_len is the complete IP datagram length, account for overhead (we + * assume no IP options/extension headers are used) */ + REDUCE_FRAG_LEN(frag_len, (src->get_family(src) == AF_INET) ? 20 : 40); + /* 8 (UDP header) */ + REDUCE_FRAG_LEN(frag_len, 8); + if (dst->get_port(dst) != IKEV2_UDP_PORT && + src->get_port(src) != IKEV2_UDP_PORT) + { /* reduce length due to non-ESP marker */ + REDUCE_FRAG_LEN(frag_len, 4); + } + + if (is_encoded(this)) + { + if (this->major_version == IKEV2_MAJOR_VERSION) + { + encrypted = (encrypted_payload_t*)get_payload(this, PLV2_ENCRYPTED); + } + data = this->packet->get_data(this->packet); + len = data.len; + } + else + { + status = generate_message(this, keymat, &generator, &encrypted); + if (status != SUCCESS) + { + DESTROY_IF(generator); + return status; + } + data = generator->get_chunk(generator, &lenpos); + len = data.len + (encrypted ? encrypted->get_length(encrypted) : 0); + } + + /* check if we actually need to fragment the message and if we have an + * encrypted payload for IKEv2 */ + if (len <= frag_len || + (this->major_version == IKEV2_MAJOR_VERSION && !encrypted)) + { + if (generator) + { + status = finalize_message(this, keymat, generator, encrypted); + if (status != SUCCESS) + { + return status; + } + } + *fragments = enumerator_create_single(this->packet, NULL); + return SUCCESS; + } + + /* frag_len denoted the maximum IKE message size so far, later on it will + * denote the maximum content size of a fragment payload, therefore, + * account for IKE header */ + REDUCE_FRAG_LEN(frag_len, 28); + + if (this->major_version == IKEV1_MAJOR_VERSION) + { + if (generator) + { + status = finalize_message(this, keymat, generator, encrypted); + if (status != SUCCESS) + { + return status; + } + data = this->packet->get_data(this->packet); + generator = NULL; + } + /* overhead for the fragmentation payload header */ + REDUCE_FRAG_LEN(frag_len, 8); } + else + { + aead_t *aead; + + if (generator) + { + generator->destroy(generator); + generator = generator_create(); + } + else + { /* do not log again if it was generated previously */ + generator = generator_create_no_dbg(); + } + next = encrypted->payload_interface.get_next_type((payload_t*)encrypted); + encrypted->generate_payloads(encrypted, generator); + data = generator->get_chunk(generator, &lenpos); + if (!is_encoded(this)) + { + encrypted->destroy(encrypted); + } + aead = keymat->get_aead(keymat, FALSE); + /* overhead for the encrypted fragment payload */ + REDUCE_FRAG_LEN(frag_len, aead->get_iv_size(aead)); + REDUCE_FRAG_LEN(frag_len, aead->get_icv_size(aead)); + /* header */ + REDUCE_FRAG_LEN(frag_len, 8); + /* padding and padding length */ + frag_len = round_down(frag_len, aead->get_block_size(aead)); + REDUCE_FRAG_LEN(frag_len, 1); + /* TODO-FRAG: if there are unencrypted payloads, should we account for + * their length in the first fragment? we still would have to add + * an encrypted fragment payload (albeit empty), even so we couldn't + * prevent IP fragmentation in every case */ + } + + count = data.len / frag_len + (data.len % frag_len ? 1 : 0); + this->fragments = array_create(0, count); + DBG1(DBG_ENC, "splitting IKE message with length of %zu bytes into " + "%hu fragments", len, count); + for (num = 1; num <= count; num++) + { + len = min(data.len, frag_len); + fragment = create_fragment(this, next, num, count, + chunk_create(data.ptr, len)); + status = fragment->generate(fragment, keymat, &packet); + fragment->destroy(fragment); + if (status != SUCCESS) + { + DBG1(DBG_ENC, "failed to generate IKE fragment"); + clear_fragments(this); + DESTROY_IF(generator); + return FAILED; + } + array_insert(this->fragments, ARRAY_TAIL, packet); + data = chunk_skip(data, len); + } + *fragments = array_create_enumerator(this->fragments); + DESTROY_IF(generator); + return SUCCESS; +} + +METHOD(message_t, get_packet, packet_t*, + private_message_t *this) +{ return this->packet->clone(this->packet); } METHOD(message_t, get_packet_data, chunk_t, private_message_t *this) { - if (this->packet == NULL) - { - return chunk_empty; - } return this->packet->get_data(this->packet); } +METHOD(message_t, get_fragments, enumerator_t*, + private_message_t *this) +{ + return array_create_enumerator(this->fragments); +} + METHOD(message_t, parse_header, status_t, private_message_t *this) { @@ -1682,6 +2082,10 @@ METHOD(message_t, parse_header, status_t, DBG2(DBG_ENC, "parsing header of message"); + if (!this->parser) + { /* reassembled IKEv2 message, header is inherited from fragments */ + return SUCCESS; + } this->parser->reset_context(this->parser); status = this->parser->parse_payload(this->parser, PL_HEADER, (payload_t**)&ike_header); @@ -1723,7 +2127,7 @@ METHOD(message_t, parse_header, status_t, this->first_payload = ike_header->payload_interface.get_next_type( &ike_header->payload_interface); if (this->first_payload == PLV1_FRAGMENT && this->is_encrypted) - { /* racoon sets the encryted bit when sending a fragment, but these + { /* racoon sets the encrypted bit when sending a fragment, but these * messages are really not encrypted */ this->is_encrypted = FALSE; } @@ -1780,9 +2184,9 @@ static status_t parse_payloads(private_message_t *this) status_t status; if (this->is_encrypted) - { /* wrap the whole encrypted IKEv1 message in a special encryption + { /* wrap the whole encrypted IKEv1 message in a special encrypted * payload which is then handled just like a regular payload */ - encryption_payload_t *encryption; + encrypted_payload_t *encryption; status = this->parser->parse_payload(this->parser, PLV1_ENCRYPTED, (payload_t**)&encryption); @@ -1824,9 +2228,9 @@ static status_t parse_payloads(private_message_t *this) payload_type_names, type); this->payloads->insert_last(this->payloads, payload); - /* an encrypted payload is the last one, so STOP here. decryption is - * done later */ - if (type == PLV2_ENCRYPTED) + /* an encrypted (fragment) payload MUST be the last one, so STOP here. + * decryption is done later */ + if (type == PLV2_ENCRYPTED || type == PLV2_FRAGMENT) { DBG2(DBG_ENC, "%N payload found, stop parsing", payload_type_names, type); @@ -1841,7 +2245,7 @@ static status_t parse_payloads(private_message_t *this) * Decrypt an encrypted payload and extract all contained payloads. */ static status_t decrypt_and_extract(private_message_t *this, keymat_t *keymat, - payload_t *previous, encryption_payload_t *encryption) + payload_t *previous, encrypted_payload_t *encryption) { payload_t *encrypted; payload_type_t type; @@ -1861,43 +2265,52 @@ static status_t decrypt_and_extract(private_message_t *this, keymat_t *keymat, DBG1(DBG_ENC, "found encrypted payload, but no transform set"); return INVALID_ARG; } - bs = aead->get_block_size(aead); - encryption->set_transform(encryption, aead); - chunk = this->packet->get_data(this->packet); - if (chunk.len < encryption->get_length(encryption) || - chunk.len < bs) + if (!this->parser) { - DBG1(DBG_ENC, "invalid payload length"); - return VERIFY_ERROR; + /* reassembled IKEv2 messages are already decrypted, we still call + * decrypt() to parse the contained payloads */ + status = encryption->decrypt(encryption, chunk_empty); } - if (keymat->get_version(keymat) == IKEV1) - { /* instead of associated data we provide the IV, we also update - * the IV with the last encrypted block */ - keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat; - chunk_t iv; - - if (keymat_v1->get_iv(keymat_v1, this->message_id, &iv)) + else + { + bs = aead->get_block_size(aead); + encryption->set_transform(encryption, aead); + chunk = this->packet->get_data(this->packet); + if (chunk.len < encryption->get_length(encryption) || + chunk.len < bs) { - status = encryption->decrypt(encryption, iv); - if (status == SUCCESS) + DBG1(DBG_ENC, "invalid payload length"); + return VERIFY_ERROR; + } + if (keymat->get_version(keymat) == IKEV1) + { /* instead of associated data we provide the IV, we also update + * the IV with the last encrypted block */ + keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat; + chunk_t iv; + + if (keymat_v1->get_iv(keymat_v1, this->message_id, &iv)) { - if (!keymat_v1->update_iv(keymat_v1, this->message_id, - chunk_create(chunk.ptr + chunk.len - bs, bs))) + status = encryption->decrypt(encryption, iv); + if (status == SUCCESS) { - status = FAILED; + if (!keymat_v1->update_iv(keymat_v1, this->message_id, + chunk_create(chunk.ptr + chunk.len - bs, bs))) + { + status = FAILED; + } } } + else + { + status = FAILED; + } } else { - status = FAILED; + chunk.len -= encryption->get_length(encryption); + status = encryption->decrypt(encryption, chunk); } } - else - { - chunk.len -= encryption->get_length(encryption); - status = encryption->decrypt(encryption, chunk); - } if (status != SUCCESS) { return status; @@ -1922,6 +2335,41 @@ static status_t decrypt_and_extract(private_message_t *this, keymat_t *keymat, return SUCCESS; } +/** + * Decrypt an encrypted fragment payload. + */ +static status_t decrypt_fragment(private_message_t *this, keymat_t *keymat, + encrypted_fragment_payload_t *fragment) +{ + encrypted_payload_t *encrypted = (encrypted_payload_t*)fragment; + chunk_t chunk; + aead_t *aead; + size_t bs; + + if (!keymat) + { + DBG1(DBG_ENC, "found encrypted fragment payload, but no keymat"); + return INVALID_ARG; + } + aead = keymat->get_aead(keymat, TRUE); + if (!aead) + { + DBG1(DBG_ENC, "found encrypted fragment payload, but no transform set"); + return INVALID_ARG; + } + bs = aead->get_block_size(aead); + encrypted->set_transform(encrypted, aead); + chunk = this->packet->get_data(this->packet); + if (chunk.len < encrypted->get_length(encrypted) || + chunk.len < bs) + { + DBG1(DBG_ENC, "invalid payload length"); + return VERIFY_ERROR; + } + chunk.len -= encrypted->get_length(encrypted); + return encrypted->decrypt(encrypted, chunk); +} + /** * Do we accept unencrypted ID/HASH payloads in Main Mode, as seen from * some SonicWall boxes? @@ -1941,7 +2389,7 @@ static bool accept_unencrypted_mm(private_message_t *this, payload_type_t type) } /** - * Decrypt payload from the encryption payload + * Decrypt payload from the encrypted payload */ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat) { @@ -1950,7 +2398,7 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat) payload_rule_t *rule; payload_type_t type; status_t status = SUCCESS; - bool was_encrypted = FALSE; + char *was_encrypted = NULL; enumerator = this->payloads->create_enumerator(this->payloads); while (enumerator->enumerate(enumerator, &payload)) @@ -1959,20 +2407,24 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat) DBG2(DBG_ENC, "process payload of type %N", payload_type_names, type); - if (type == PLV2_ENCRYPTED || type == PLV1_ENCRYPTED) + if (type == PLV2_ENCRYPTED || type == PLV1_ENCRYPTED || + type == PLV2_FRAGMENT) { - encryption_payload_t *encryption; - if (was_encrypted) { - DBG1(DBG_ENC, "encrypted payload can't contain other payloads " - "of type %N", payload_type_names, type); + DBG1(DBG_ENC, "%s can't contain other payloads of type %N", + was_encrypted, payload_type_names, type); status = VERIFY_ERROR; break; } + } + + if (type == PLV2_ENCRYPTED || type == PLV1_ENCRYPTED) + { + encrypted_payload_t *encryption; DBG2(DBG_ENC, "found an encrypted payload"); - encryption = (encryption_payload_t*)payload; + encryption = (encrypted_payload_t*)payload; this->payloads->remove_at(this->payloads, enumerator); if (enumerator->enumerate(enumerator, NULL)) @@ -1988,7 +2440,27 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat) { break; } - was_encrypted = TRUE; + was_encrypted = "encrypted payload"; + } + else if (type == PLV2_FRAGMENT) + { + encrypted_fragment_payload_t *fragment; + + DBG2(DBG_ENC, "found an encrypted fragment payload"); + fragment = (encrypted_fragment_payload_t*)payload; + + if (enumerator->enumerate(enumerator, NULL)) + { + DBG1(DBG_ENC, "encrypted fragment payload is not last payload"); + status = VERIFY_ERROR; + break; + } + status = decrypt_fragment(this, keymat, fragment); + if (status != SUCCESS) + { + break; + } + was_encrypted = "encrypted fragment payload"; } if (payload_is_known(type) && !was_encrypted && @@ -2085,10 +2557,15 @@ METHOD(message_t, parse_body, status_t, return NOT_SUPPORTED; } - status = parse_payloads(this); - if (status != SUCCESS) - { /* error is already logged */ - return status; + /* reassembled IKEv2 messages are already parsed (except for the payloads + * contained in the encrypted payload, which are handled below) */ + if (this->parser) + { + status = parse_payloads(this); + if (status != SUCCESS) + { /* error is already logged */ + return status; + } } status = decrypt_payloads(this, keymat); @@ -2142,7 +2619,7 @@ METHOD(message_t, parse_body, status_t, } chunk_free(&hash); } - if (this->is_encrypted) + if (this->is_encrypted && this->exchange_type != INFORMATIONAL_V1) { /* message verified, confirm IV */ if (!keymat_v1->confirm_iv(keymat_v1, this->message_id)) { @@ -2153,13 +2630,234 @@ METHOD(message_t, parse_body, status_t, return SUCCESS; } +/** + * Store the fragment data for the fragment with the given fragment number. + */ +static status_t add_fragment(private_message_t *this, u_int16_t num, + chunk_t data) +{ + fragment_t *fragment; + int i, insert_at = -1; + + for (i = 0; i < array_count(this->fragments); i++) + { + array_get(this->fragments, i, &fragment); + if (fragment->num == num) + { + /* ignore a duplicate fragment */ + DBG1(DBG_ENC, "received duplicate fragment #%hu", num); + return NEED_MORE; + } + if (fragment->num > num) + { + insert_at = i; + break; + } + } + this->frag->len += data.len; + if (this->frag->len > this->frag->max_packet) + { + DBG1(DBG_ENC, "fragmented IKE message is too large"); + reset_defrag(this); + return FAILED; + } + INIT(fragment, + .num = num, + .data = chunk_clone(data), + ); + array_insert(this->fragments, insert_at, fragment); + return SUCCESS; +} + +/** + * Merge the cached fragment data and resets the defragmentation state. + * Also updates the IP addresses to those of the last received fragment. + */ +static chunk_t merge_fragments(private_message_t *this, message_t *last) +{ + fragment_t *fragment; + bio_writer_t *writer; + host_t *src, *dst; + chunk_t data; + int i; + + writer = bio_writer_create(this->frag->len); + for (i = 0; i < array_count(this->fragments); i++) + { + array_get(this->fragments, i, &fragment); + writer->write_data(writer, fragment->data); + } + data = writer->extract_buf(writer); + writer->destroy(writer); + + /* set addresses to those of the last fragment we received */ + src = last->get_source(last); + dst = last->get_destination(last); + this->packet->set_source(this->packet, src->clone(src)); + this->packet->set_destination(this->packet, dst->clone(dst)); + + reset_defrag(this); + free(this->frag); + this->frag = NULL; + return data; +} + +METHOD(message_t, add_fragment_v1, status_t, + private_message_t *this, message_t *message) +{ + fragment_payload_t *payload; + chunk_t data; + u_int8_t num; + status_t status; + + if (!this->frag) + { + return INVALID_STATE; + } + payload = (fragment_payload_t*)message->get_payload(message, PLV1_FRAGMENT); + if (!payload) + { + return INVALID_ARG; + } + if (!this->fragments || this->message_id != payload->get_id(payload)) + { + reset_defrag(this); + this->message_id = payload->get_id(payload); + /* we don't know the total number of fragments, assume something */ + this->fragments = array_create(0, 4); + } + + num = payload->get_number(payload); + data = payload->get_data(payload); + if (!this->frag->last && payload->is_last(payload)) + { + this->frag->last = num; + } + status = add_fragment(this, num, data); + if (status != SUCCESS) + { + return status; + } + + if (array_count(this->fragments) != this->frag->last) + { + /* there are some fragments missing */ + DBG1(DBG_ENC, "received fragment #%hhu, waiting for complete IKE " + "message", num); + return NEED_MORE; + } + + DBG1(DBG_ENC, "received fragment #%hhu, reassembling fragmented IKE " + "message", num); + + data = merge_fragments(this, message); + this->packet->set_data(this->packet, data); + this->parser = parser_create(data); + + if (parse_header(this) != SUCCESS) + { + DBG1(DBG_IKE, "failed to parse header of reassembled IKE message"); + return FAILED; + } + return SUCCESS; +} + +METHOD(message_t, add_fragment_v2, status_t, + private_message_t *this, message_t *message) +{ + encrypted_fragment_payload_t *encrypted_fragment; + encrypted_payload_t *encrypted; + payload_t *payload; + enumerator_t *enumerator; + chunk_t data; + u_int16_t total, num; + status_t status; + + if (!this->frag) + { + return INVALID_STATE; + } + payload = message->get_payload(message, PLV2_FRAGMENT); + if (!payload || this->message_id != message->get_message_id(message)) + { + return INVALID_ARG; + } + encrypted_fragment = (encrypted_fragment_payload_t*)payload; + total = encrypted_fragment->get_total_fragments(encrypted_fragment); + if (total > MAX_FRAGMENTS) + { + DBG1(DBG_IKE, "maximum fragment count exceeded"); + reset_defrag(this); + return FAILED; + } + if (!this->fragments || total > this->frag->last) + { + reset_defrag(this); + this->frag->last = total; + this->fragments = array_create(0, total); + } + num = encrypted_fragment->get_fragment_number(encrypted_fragment); + data = encrypted_fragment->get_content(encrypted_fragment); + status = add_fragment(this, num, data); + if (status != SUCCESS) + { + return status; + } + + if (num == 1) + { + /* the first fragment denotes the payload type of the first payload in + * the original encrypted payload, cache that */ + this->first_payload = payload->get_next_type(payload); + /* move all unencrypted payloads contained in the first fragment */ + enumerator = message->create_payload_enumerator(message); + while (enumerator->enumerate(enumerator, &payload)) + { + if (payload->get_type(payload) != PLV2_FRAGMENT) + { + message->remove_payload_at(message, enumerator); + this->payloads->insert_last(this->payloads, payload); + } + } + enumerator->destroy(enumerator); + } + + if (array_count(this->fragments) != total) + { + /* there are some fragments missing */ + DBG1(DBG_ENC, "received fragment #%hu of %hu, waiting for complete IKE " + "message", num, total); + return NEED_MORE; + } + + DBG1(DBG_ENC, "received fragment #%hu of %hu, reassembling fragmented IKE " + "message", num, total); + + data = merge_fragments(this, message); + encrypted = encrypted_payload_create_from_plain(this->first_payload, data); + this->payloads->insert_last(this->payloads, encrypted); + /* update next payload type (could be an unencrypted payload) */ + this->payloads->get_first(this->payloads, (void**)&payload); + this->first_payload = payload->get_type(payload); + return SUCCESS; +} + METHOD(message_t, destroy, void, private_message_t *this) { DESTROY_IF(this->ike_sa_id); + DESTROY_IF(this->parser); this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy)); this->packet->destroy(this->packet); - this->parser->destroy(this->parser); + if (this->frag) + { + reset_defrag(this); + free(this->frag); + } + else + { + array_destroy_offset(this->fragments, offsetof(packet_t, destroy)); + } free(this); } @@ -2195,6 +2893,9 @@ message_t *message_create_from_packet(packet_t *packet) .disable_sort = _disable_sort, .generate = _generate, .is_encoded = _is_encoded, + .is_fragmented = _is_fragmented, + .fragment = _fragment, + .add_fragment = _add_fragment_v2, .set_source = _set_source, .get_source = _get_source, .set_destination = _set_destination, @@ -2207,6 +2908,7 @@ message_t *message_create_from_packet(packet_t *packet) .parse_body = _parse_body, .get_packet = _get_packet, .get_packet_data = _get_packet_data, + .get_fragments = _get_fragments, .destroy = _destroy, }, .exchange_type = EXCHANGE_TYPE_UNDEFINED, @@ -2232,3 +2934,34 @@ message_t *message_create(int major, int minor) return this; } + +/* + * Described in header. + */ +message_t *message_create_defrag(message_t *fragment) +{ + private_message_t *this; + + if (!fragment->get_payload(fragment, PLV1_FRAGMENT) && + !fragment->get_payload(fragment, PLV2_FRAGMENT)) + { + return NULL; + } + this = (private_message_t*)clone_message((private_message_t*)fragment); + /* we don't need a parser for IKEv2, the one for IKEv1 is created after + * reassembling the original message */ + this->parser->destroy(this->parser); + this->parser = NULL; + if (fragment->get_major_version(fragment) == IKEV1_MAJOR_VERSION) + { + /* we store the fragment ID in the message ID field, which should be + * zero for fragments, but make sure */ + this->message_id = 0; + this->public.add_fragment = _add_fragment_v1; + } + INIT(this->frag, + .max_packet = lib->settings->get_int(lib->settings, + "%s.max_packet", PACKET_MAX_DEFAULT, lib->ns), + ); + return &this->public; +} diff --git a/src/libcharon/encoding/message.h b/src/libcharon/encoding/message.h index 7631a7c3a..a03aa8e96 100644 --- a/src/libcharon/encoding/message.h +++ b/src/libcharon/encoding/message.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2011 Tobias Brunner + * Copyright (C) 2006-2014 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005 Jan Hutter @@ -39,7 +39,7 @@ typedef struct message_t message_t; * * The message handles parsing and generation of payloads * via parser_t/generator_t. Encryption is done transparently - * via the encryption_payload_t. A set of rules for messages + * via the encrypted_payload_t. A set of rules for messages * and payloads does check parsed messages. */ struct message_t { @@ -264,6 +264,53 @@ struct message_t { */ bool (*is_encoded)(message_t *this); + /** + * Generates the message split into fragments of the given size (total IP + * datagram length). + * + * @param keymat keymat to encrypt/sign message(s) + * @param frag_len fragment length (maximum total IP datagram length), 0 + * for default value depending on address family + * @param fragments receives an enumerator with generated packet_t*, + * which are owned by the enumerator + * @return + * - SUCCESS if message could be fragmented + * - FAILED if fragmentation failed + * - and the possible return values of generate() + */ + status_t (*fragment)(message_t *this, keymat_t *keymat, size_t frag_len, + enumerator_t **fragments); + + /** + * Check if the message has been encoded and fragmented using fragment(), + * and whether there actually resulted fragments (if not is_encoded() will + * be TRUE). + * + * The packets of individual fragments can be retrieved with + * get_fragments(). + * + * @return TRUE if message has been encoded and fragmented + */ + bool (*is_fragmented)(message_t *this); + + /** + * Add a fragment to the message if it was created with + * message_create_defrag(). + * + * Once the message is completed it should be processed like any other + * inbound message. + * + * @param fragment fragment to add + * @return + * - SUCCESS if message was reassembled + * - NEED_MORE if not all fragments have yet been received + * - FAILED if reassembling failed + * - INVALID_ARG if fragment is invalid for some reason + * - INVALID_STATE if message was not created using + * message_create_defrag() + */ + status_t (*add_fragment)(message_t *this, message_t *fragment); + /** * Gets the source host informations. * @@ -337,11 +384,11 @@ struct message_t { notify_payload_t* (*get_notify)(message_t *this, notify_type_t type); /** - * Returns a clone of the internal stored packet_t object. + * Returns a clone of the internally stored packet_t object. * * @return packet_t object as clone of internal one */ - packet_t * (*get_packet) (message_t *this); + packet_t *(*get_packet) (message_t *this); /** * Returns a chunk pointing to internal packet_t data. @@ -350,6 +397,13 @@ struct message_t { */ chunk_t (*get_packet_data) (message_t *this); + /** + * Returns internally stored packet_t* objects for each fragment. + * + * @return enumerator internal packet_t* objects + */ + enumerator_t *(*get_fragments)(message_t *this); + /** * Destroys a message and all including objects. */ @@ -380,4 +434,14 @@ message_t *message_create_from_packet(packet_t *packet); */ message_t *message_create(int major, int minor); +/** + * Creates a message_t object that is used to reassemble fragmented messages. + * + * Use add_fragment() to add fragments. + * + * @param fragment initial fragment (is not added) + * @return message_t object, NULL if fragment is not actually one + */ +message_t *message_create_defrag(message_t *fragment); + #endif /** MESSAGE_H_ @}*/ diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c index c33e30dd3..d6240fde2 100644 --- a/src/libcharon/encoding/parser.c +++ b/src/libcharon/encoding/parser.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/libcharon/encoding/payloads/encrypted_fragment_payload.h b/src/libcharon/encoding/payloads/encrypted_fragment_payload.h new file mode 100644 index 000000000..1c2cc379f --- /dev/null +++ b/src/libcharon/encoding/payloads/encrypted_fragment_payload.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 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 . + * + * 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 encrypted_fragment_payload encrypted_fragment_payload + * @{ @ingroup payloads + */ + +#ifndef ENCRYPTED_FRAGMENT_PAYLOAD_H_ +#define ENCRYPTED_FRAGMENT_PAYLOAD_H_ + +typedef struct encrypted_fragment_payload_t encrypted_fragment_payload_t; + +#include + +/** + * The Encrypted Fragment Payload as described in RFC 7383 + * + * The implementation is located in encrypted_payload.c as it is very similar. + */ +struct encrypted_fragment_payload_t { + + /** + * Implements payload_t interface. + */ + encrypted_payload_t encrypted; + + /** + * Get the fragment number. + * + * @return fragment number + */ + u_int16_t (*get_fragment_number)(encrypted_fragment_payload_t *this); + + /** + * Get the total number of fragments. + * + * @return total number of fragments + */ + u_int16_t (*get_total_fragments)(encrypted_fragment_payload_t *this); + + /** + * Get the (decrypted) content of this payload. + * + * @return internal payload data + */ + chunk_t (*get_content)(encrypted_fragment_payload_t *this); + + /** + * Destroys an encrypted_fragment_payload_t object. + */ + void (*destroy)(encrypted_fragment_payload_t *this); +}; + +/** + * Creates an empty encrypted_fragment_payload_t object. + * + * @return encrypted_fragment_payload_t object + */ +encrypted_fragment_payload_t *encrypted_fragment_payload_create(); + +/** + * Creates an encrypted fragment payload from the given data. + * + * @param num fragment number (first one should be 1) + * @param total total number of fragments + * @param data fragment data (gets cloned) + * @return encrypted_fragment_payload_t object + */ +encrypted_fragment_payload_t *encrypted_fragment_payload_create_from_data( + u_int16_t num, u_int16_t total, chunk_t data); + +#endif /** ENCRYPTED_FRAGMENT_PAYLOAD_H_ @}*/ diff --git a/src/libcharon/encoding/payloads/encrypted_payload.c b/src/libcharon/encoding/payloads/encrypted_payload.c new file mode 100644 index 000000000..5c574c34d --- /dev/null +++ b/src/libcharon/encoding/payloads/encrypted_payload.c @@ -0,0 +1,1022 @@ +/* + * Copyright (C) 2011-2014 Tobias Brunner + * Copyright (C) 2005-2010 Martin Willi + * Copyright (C) 2010 revosec AG + * 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 . + * + * 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 +#include + +#include "encrypted_payload.h" +#include "encrypted_fragment_payload.h" + +#include +#include +#include +#include + +typedef struct private_encrypted_payload_t private_encrypted_payload_t; +typedef struct private_encrypted_fragment_payload_t private_encrypted_fragment_payload_t; + +struct private_encrypted_payload_t { + + /** + * Public encrypted_payload_t interface. + */ + encrypted_payload_t public; + + /** + * There is no next payload for an encrypted payload, + * since encrypted payload MUST be the last one. + * next_payload means here the first payload of the + * contained, encrypted payload. + */ + u_int8_t next_payload; + + /** + * Flags, including reserved bits + */ + u_int8_t flags; + + /** + * Length of this payload + */ + u_int16_t payload_length; + + /** + * Chunk containing the IV, plain, padding and ICV. + */ + chunk_t encrypted; + + /** + * AEAD transform to use + */ + aead_t *aead; + + /** + * Contained payloads + */ + linked_list_t *payloads; + + /** + * Type of payload, PLV2_ENCRYPTED or PLV1_ENCRYPTED + */ + payload_type_t type; +}; + +struct private_encrypted_fragment_payload_t { + + /** + * Public interface. + */ + encrypted_fragment_payload_t public; + + /** + * The first fragment contains the type of the first payload contained in + * the original encrypted payload, for all other fragments it MUST be set + * to zero. + */ + u_int8_t next_payload; + + /** + * Flags, including reserved bits + */ + u_int8_t flags; + + /** + * Length of this payload + */ + u_int16_t payload_length; + + /** + * Chunk containing the IV, plain, padding and ICV. + */ + chunk_t encrypted; + + /** + * Fragment number + */ + u_int16_t fragment_number; + + /** + * Total fragments + */ + u_int16_t total_fragments; + + /** + * AEAD transform to use + */ + aead_t *aead; + + /** + * Chunk containing the plain packet data. + */ + chunk_t plain; +}; + +/** + * Encoding rules to parse or generate a IKEv2-Encrypted Payload. + * + * The defined offsets are the positions in a object of type + * private_encrypted_payload_t. + */ +static encoding_rule_t encodings_v2[] = { + /* 1 Byte next payload type, stored in the field next_payload */ + { U_INT_8, offsetof(private_encrypted_payload_t, next_payload) }, + /* Critical and 7 reserved bits, all stored for reconstruction */ + { U_INT_8, offsetof(private_encrypted_payload_t, flags) }, + /* Length of the whole encrypted payload*/ + { PAYLOAD_LENGTH, offsetof(private_encrypted_payload_t, payload_length) }, + /* encrypted data, stored in a chunk. contains iv, data, padding */ + { CHUNK_DATA, offsetof(private_encrypted_payload_t, encrypted) }, +}; + +/* + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload !C! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Initialization Vector ! + ! (length is block size for encryption algorithm) ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Encrypted IKE Payloads ! + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! Padding (0-255 octets) ! + +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + ! ! Pad Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ~ Integrity Checksum Data ~ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/** + * Encoding rules to parse or generate a complete encrypted IKEv1 message. + * + * The defined offsets are the positions in a object of type + * private_encrypted_payload_t. + */ +static encoding_rule_t encodings_v1[] = { + /* encrypted data, stored in a chunk */ + { ENCRYPTED_DATA, offsetof(private_encrypted_payload_t, encrypted) }, +}; + +/* + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Encrypted IKE Payloads ! + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! Padding (0-255 octets) ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/** + * Encoding rules to parse or generate an IKEv2-Encrypted Fragment Payload. + * + * The defined offsets are the positions in a object of type + * private_encrypted_payload_t. + */ +static encoding_rule_t encodings_fragment[] = { + /* 1 Byte next payload type, stored in the field next_payload */ + { U_INT_8, offsetof(private_encrypted_fragment_payload_t, next_payload) }, + /* Critical and 7 reserved bits, all stored for reconstruction */ + { U_INT_8, offsetof(private_encrypted_fragment_payload_t, flags) }, + /* Length of the whole encryption payload*/ + { PAYLOAD_LENGTH, offsetof(private_encrypted_fragment_payload_t, payload_length) }, + /* Fragment number */ + { U_INT_16, offsetof(private_encrypted_fragment_payload_t, fragment_number) }, + /* Total number of fragments */ + { U_INT_16, offsetof(private_encrypted_fragment_payload_t, total_fragments) }, + /* encrypted data, stored in a chunk. contains iv, data, padding */ + { CHUNK_DATA, offsetof(private_encrypted_fragment_payload_t, encrypted) }, +}; + +/* + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload !C! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Fragment Number | Total Fragments ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Initialization Vector ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Encrypted IKE Payloads ! + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! Padding (0-255 octets) ! + +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + ! ! Pad Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ~ Integrity Checksum Data ~ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +METHOD(payload_t, verify, status_t, + private_encrypted_payload_t *this) +{ + return SUCCESS; +} + +METHOD(payload_t, get_encoding_rules, int, + private_encrypted_payload_t *this, encoding_rule_t **rules) +{ + if (this->type == PLV2_ENCRYPTED) + { + *rules = encodings_v2; + return countof(encodings_v2); + } + *rules = encodings_v1; + return countof(encodings_v1); +} + +METHOD(payload_t, get_header_length, int, + private_encrypted_payload_t *this) +{ + if (this->type == PLV2_ENCRYPTED) + { + return 4; + } + return 0; +} + +METHOD(payload_t, get_type, payload_type_t, + private_encrypted_payload_t *this) +{ + return this->type; +} + +METHOD(payload_t, get_next_type, payload_type_t, + private_encrypted_payload_t *this) +{ + return this->next_payload; +} + +METHOD(payload_t, set_next_type, void, + private_encrypted_payload_t *this, payload_type_t type) +{ + /* the next payload is set during add, still allow this for IKEv1 */ + this->next_payload = type; +} + +/** + * Get length of encryption/integrity overhead for the given plaintext length + */ +static size_t compute_overhead(aead_t *aead, size_t len) +{ + size_t bs, overhead; + + /* padding */ + bs = aead->get_block_size(aead); + overhead = bs - (len % bs); + /* add iv */ + overhead += aead->get_iv_size(aead); + /* add icv */ + overhead += aead->get_icv_size(aead); + return overhead; +} + +/** + * Compute the length of the whole payload + */ +static void compute_length(private_encrypted_payload_t *this) +{ + enumerator_t *enumerator; + payload_t *payload; + size_t length = 0; + + if (this->encrypted.len) + { + length = this->encrypted.len; + } + else + { + enumerator = this->payloads->create_enumerator(this->payloads); + while (enumerator->enumerate(enumerator, &payload)) + { + length += payload->get_length(payload); + } + enumerator->destroy(enumerator); + + if (this->aead) + { + length += compute_overhead(this->aead, length); + } + } + length += get_header_length(this); + this->payload_length = length; +} + +METHOD2(payload_t, encrypted_payload_t, get_length, size_t, + private_encrypted_payload_t *this) +{ + compute_length(this); + return this->payload_length; +} + +METHOD(encrypted_payload_t, add_payload, void, + private_encrypted_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); + last_payload->set_next_type(last_payload, payload->get_type(payload)); + } + else + { + this->next_payload = payload->get_type(payload); + } + payload->set_next_type(payload, PL_NONE); + this->payloads->insert_last(this->payloads, payload); + compute_length(this); +} + +METHOD(encrypted_payload_t, remove_payload, payload_t *, + private_encrypted_payload_t *this) +{ + payload_t *payload; + + if (this->payloads->remove_first(this->payloads, + (void**)&payload) == SUCCESS) + { + return payload; + } + return NULL; +} + +/** + * Generate payload before encryption + */ +static chunk_t generate(private_encrypted_payload_t *this, + generator_t *generator) +{ + payload_t *current, *next; + enumerator_t *enumerator; + u_int32_t *lenpos; + chunk_t chunk = chunk_empty; + + enumerator = this->payloads->create_enumerator(this->payloads); + if (enumerator->enumerate(enumerator, ¤t)) + { + this->next_payload = current->get_type(current); + + 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, PL_NONE); + generator->generate_payload(generator, current); + + chunk = generator->get_chunk(generator, &lenpos); + DBG2(DBG_ENC, "generated content in encrypted payload"); + } + enumerator->destroy(enumerator); + return chunk; +} + +METHOD(encrypted_payload_t, generate_payloads, void, + private_encrypted_payload_t *this, generator_t *generator) +{ + generate(this, generator); +} + +/** + * Append the encrypted payload header to the associated data + */ +static chunk_t append_header(private_encrypted_payload_t *this, chunk_t assoc) +{ + 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)); +} + +/** + * Encrypts the data in plain and returns it in an allocated chunk. + */ +static status_t encrypt_content(char *label, aead_t *aead, u_int64_t mid, + chunk_t plain, chunk_t assoc, chunk_t *encrypted) +{ + chunk_t iv, padding, icv, crypt; + iv_gen_t *iv_gen; + rng_t *rng; + size_t bs; + + rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); + if (!rng) + { + DBG1(DBG_ENC, "encrypting %s failed, no RNG found", label); + return NOT_SUPPORTED; + } + + iv_gen = aead->get_iv_gen(aead); + if (!iv_gen) + { + DBG1(DBG_ENC, "encrypting %s failed, no IV generator", label); + return NOT_SUPPORTED; + } + + bs = aead->get_block_size(aead); + /* we need at least one byte padding to store the padding length */ + padding.len = bs - (plain.len % bs); + iv.len = aead->get_iv_size(aead); + icv.len = aead->get_icv_size(aead); + + /* prepare data to authenticate-encrypt: + * | IV | plain | padding | ICV | + * \____crypt______/ ^ + * | / + * v / + * assoc -> + ------->/ + */ + *encrypted = chunk_alloc(iv.len + plain.len + padding.len + icv.len); + iv.ptr = 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); + + if (!iv_gen->get_iv(iv_gen, mid, iv.len, iv.ptr) || + !rng->get_bytes(rng, padding.len - 1, padding.ptr)) + { + DBG1(DBG_ENC, "encrypting %s failed, no IV or padding", label); + rng->destroy(rng); + + return FAILED; + } + padding.ptr[padding.len - 1] = padding.len - 1; + rng->destroy(rng); + + DBG3(DBG_ENC, "%s encryption:", label); + DBG3(DBG_ENC, "IV %B", &iv); + DBG3(DBG_ENC, "plain %B", &plain); + DBG3(DBG_ENC, "padding %B", &padding); + DBG3(DBG_ENC, "assoc %B", &assoc); + + if (!aead->encrypt(aead, crypt, assoc, iv, NULL)) + { + return FAILED; + } + DBG3(DBG_ENC, "encrypted %B", &crypt); + DBG3(DBG_ENC, "ICV %B", &icv); + return SUCCESS; +} + +METHOD(encrypted_payload_t, encrypt, status_t, + private_encrypted_payload_t *this, u_int64_t mid, chunk_t assoc) +{ + generator_t *generator; + chunk_t plain; + status_t status; + + if (this->aead == NULL) + { + DBG1(DBG_ENC, "encrypting encrypted payload failed, transform missing"); + return INVALID_STATE; + } + + free(this->encrypted.ptr); + generator = generator_create(); + plain = generate(this, generator); + assoc = append_header(this, assoc); + status = encrypt_content("encrypted payload", this->aead, mid, plain, assoc, + &this->encrypted); + generator->destroy(generator); + free(assoc.ptr); + return status; +} + +METHOD(encrypted_payload_t, encrypt_v1, status_t, + private_encrypted_payload_t *this, u_int64_t mid, chunk_t iv) +{ + generator_t *generator; + chunk_t plain, padding; + size_t bs; + + if (this->aead == NULL) + { + DBG1(DBG_ENC, "encryption failed, transform missing"); + return INVALID_STATE; + } + + generator = generator_create(); + plain = generate(this, generator); + bs = this->aead->get_block_size(this->aead); + padding.len = bs - (plain.len % bs); + + /* prepare data to encrypt: + * | plain | padding | */ + free(this->encrypted.ptr); + this->encrypted = chunk_alloc(plain.len + padding.len); + memcpy(this->encrypted.ptr, plain.ptr, plain.len); + plain.ptr = this->encrypted.ptr; + padding.ptr = plain.ptr + plain.len; + memset(padding.ptr, 0, padding.len); + generator->destroy(generator); + + DBG3(DBG_ENC, "encrypting payloads:"); + DBG3(DBG_ENC, "IV %B", &iv); + DBG3(DBG_ENC, "plain %B", &plain); + DBG3(DBG_ENC, "padding %B", &padding); + + if (!this->aead->encrypt(this->aead, this->encrypted, chunk_empty, iv, NULL)) + { + return FAILED; + } + + DBG3(DBG_ENC, "encrypted %B", &this->encrypted); + + return SUCCESS; +} + +/** + * Parse the payloads after decryption. + */ +static status_t parse(private_encrypted_payload_t *this, chunk_t plain) +{ + parser_t *parser; + payload_type_t type; + + parser = parser_create(plain); + type = this->next_payload; + while (type != PL_NONE) + { + payload_t *payload; + + if (plain.len < 4 || untoh16(plain.ptr + 2) > plain.len) + { + DBG1(DBG_ENC, "invalid %N payload length, decryption failed?", + payload_type_names, type); + parser->destroy(parser); + return PARSE_ERROR; + } + if (parser->parse_payload(parser, type, &payload) != SUCCESS) + { + parser->destroy(parser); + return PARSE_ERROR; + } + if (payload->verify(payload) != SUCCESS) + { + DBG1(DBG_ENC, "%N verification failed", + payload_type_names, payload->get_type(payload)); + payload->destroy(payload); + parser->destroy(parser); + return VERIFY_ERROR; + } + type = payload->get_next_type(payload); + this->payloads->insert_last(this->payloads, payload); + } + parser->destroy(parser); + DBG2(DBG_ENC, "parsed content of encrypted payload"); + return SUCCESS; +} + +/** + * Decrypts the given data in-place and returns a chunk pointing to the + * resulting plaintext. + */ +static status_t decrypt_content(char *label, aead_t *aead, chunk_t encrypted, + chunk_t assoc, chunk_t *plain) +{ + chunk_t iv, padding, icv, crypt; + size_t bs; + + /* prepare data to authenticate-decrypt: + * | IV | plain | padding | ICV | + * \____crypt______/ ^ + * | / + * v / + * assoc -> + ------->/ + */ + bs = aead->get_block_size(aead); + iv.len = aead->get_iv_size(aead); + iv.ptr = encrypted.ptr; + icv.len = aead->get_icv_size(aead); + icv.ptr = encrypted.ptr + encrypted.len - icv.len; + crypt.ptr = iv.ptr + iv.len; + crypt.len = encrypted.len - iv.len; + + if (iv.len + icv.len > encrypted.len || + (crypt.len - icv.len) % bs) + { + DBG1(DBG_ENC, "decrypting %s payload failed, invalid length", label); + return FAILED; + } + + DBG3(DBG_ENC, "%s decryption:", label); + DBG3(DBG_ENC, "IV %B", &iv); + DBG3(DBG_ENC, "encrypted %B", &crypt); + DBG3(DBG_ENC, "ICV %B", &icv); + DBG3(DBG_ENC, "assoc %B", &assoc); + + if (!aead->decrypt(aead, crypt, assoc, iv, NULL)) + { + DBG1(DBG_ENC, "verifying %s integrity failed", label); + return FAILED; + } + + *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, "decrypting %s failed, padding invalid %B", label, + &crypt); + return PARSE_ERROR; + } + plain->len -= padding.len; + padding.ptr = plain->ptr + plain->len; + + DBG3(DBG_ENC, "plain %B", plain); + DBG3(DBG_ENC, "padding %B", &padding); + return SUCCESS; +} + +METHOD(encrypted_payload_t, decrypt, status_t, + private_encrypted_payload_t *this, chunk_t assoc) +{ + chunk_t plain; + status_t status; + + if (this->aead == NULL) + { + DBG1(DBG_ENC, "decrypting encrypted payload failed, transform missing"); + return INVALID_STATE; + } + + assoc = append_header(this, assoc); + status = decrypt_content("encrypted payload", this->aead, this->encrypted, + assoc, &plain); + free(assoc.ptr); + + if (status != SUCCESS) + { + return status; + } + return parse(this, plain); +} + +METHOD(encrypted_payload_t, decrypt_plain, status_t, + private_encrypted_payload_t *this, chunk_t assoc) +{ + if (!this->encrypted.ptr) + { + return FAILED; + } + return parse(this, this->encrypted); +} + +METHOD(encrypted_payload_t, decrypt_v1, status_t, + private_encrypted_payload_t *this, chunk_t iv) +{ + if (this->aead == NULL) + { + DBG1(DBG_ENC, "decryption failed, transform missing"); + return INVALID_STATE; + } + + /* data must be a multiple of block size */ + if (iv.len != this->aead->get_block_size(this->aead) || + this->encrypted.len < iv.len || this->encrypted.len % iv.len) + { + DBG1(DBG_ENC, "decryption failed, invalid length"); + return FAILED; + } + + DBG3(DBG_ENC, "decrypting payloads:"); + DBG3(DBG_ENC, "encrypted %B", &this->encrypted); + + if (!this->aead->decrypt(this->aead, this->encrypted, chunk_empty, iv, NULL)) + { + return FAILED; + } + + DBG3(DBG_ENC, "plain %B", &this->encrypted); + + return parse(this, this->encrypted); +} + +METHOD(encrypted_payload_t, set_transform, void, + private_encrypted_payload_t *this, aead_t* aead) +{ + this->aead = aead; +} + +METHOD2(payload_t, encrypted_payload_t, destroy, void, + private_encrypted_payload_t *this) +{ + this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy)); + free(this->encrypted.ptr); + free(this); +} + +/* + * Described in header + */ +encrypted_payload_t *encrypted_payload_create(payload_type_t type) +{ + private_encrypted_payload_t *this; + + INIT(this, + .public = { + .payload_interface = { + .verify = _verify, + .get_encoding_rules = _get_encoding_rules, + .get_header_length = _get_header_length, + .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, + .generate_payloads = _generate_payloads, + .set_transform = _set_transform, + .encrypt = _encrypt, + .decrypt = _decrypt, + .destroy = _destroy, + }, + .next_payload = PL_NONE, + .payloads = linked_list_create(), + .type = type, + ); + this->payload_length = get_header_length(this); + + if (type == PLV1_ENCRYPTED) + { + this->public.encrypt = _encrypt_v1; + this->public.decrypt = _decrypt_v1; + } + + return &this->public; +} + +/* + * Described in header + */ +encrypted_payload_t *encrypted_payload_create_from_plain(payload_type_t next, + chunk_t plain) +{ + private_encrypted_payload_t *this; + + this = (private_encrypted_payload_t*)encrypted_payload_create(PLV2_ENCRYPTED); + this->public.decrypt = _decrypt_plain; + this->next_payload = next; + this->encrypted = plain; + compute_length(this); + + return &this->public; +} + +METHOD(payload_t, frag_verify, status_t, + private_encrypted_fragment_payload_t *this) +{ + if (!this->fragment_number || !this->total_fragments || + this->fragment_number > this->total_fragments) + { + DBG1(DBG_ENC, "invalid fragment number (%u) or total fragments (%u)", + this->fragment_number, this->total_fragments); + return FAILED; + } + if (this->fragment_number > 1 && this->next_payload != 0) + { + DBG1(DBG_ENC, "invalid next payload (%u) for fragment %u, ignored", + this->next_payload, this->fragment_number); + this->next_payload = 0; + } + return SUCCESS; +} + +METHOD(payload_t, frag_get_encoding_rules, int, + private_encrypted_fragment_payload_t *this, encoding_rule_t **rules) +{ + *rules = encodings_fragment; + return countof(encodings_fragment); +} + +METHOD(payload_t, frag_get_header_length, int, + private_encrypted_fragment_payload_t *this) +{ + return 8; +} + +METHOD(payload_t, frag_get_type, payload_type_t, + private_encrypted_fragment_payload_t *this) +{ + return PLV2_FRAGMENT; +} + +METHOD(payload_t, frag_get_next_type, payload_type_t, + private_encrypted_fragment_payload_t *this) +{ + return this->next_payload; +} + +METHOD(payload_t, frag_set_next_type, void, + private_encrypted_fragment_payload_t *this, payload_type_t type) +{ + if (this->fragment_number == 1 && this->next_payload == PL_NONE) + { + this->next_payload = type; + } +} + +METHOD2(payload_t, encrypted_payload_t, frag_get_length, size_t, + private_encrypted_fragment_payload_t *this) +{ + if (this->encrypted.len) + { + this->payload_length = this->encrypted.len; + } + else + { + this->payload_length = this->plain.len; + + if (this->aead) + { + this->payload_length += compute_overhead(this->aead, + this->payload_length); + } + } + this->payload_length += frag_get_header_length(this); + return this->payload_length; +} + +METHOD(encrypted_fragment_payload_t, get_fragment_number, u_int16_t, + private_encrypted_fragment_payload_t *this) +{ + return this->fragment_number; +} + +METHOD(encrypted_fragment_payload_t, get_total_fragments, u_int16_t, + private_encrypted_fragment_payload_t *this) +{ + return this->total_fragments; +} + +METHOD(encrypted_fragment_payload_t, frag_get_content, chunk_t, + private_encrypted_fragment_payload_t *this) +{ + return this->plain; +} + +METHOD(encrypted_payload_t, frag_add_payload, void, + private_encrypted_fragment_payload_t *this, payload_t* payload) +{ + payload->destroy(payload); +} + +METHOD(encrypted_payload_t, frag_set_transform, void, + private_encrypted_fragment_payload_t *this, aead_t* aead) +{ + this->aead = aead; +} + +/** + * Append the encrypted fragment payload header to the associated data + */ +static chunk_t append_header_frag(private_encrypted_fragment_payload_t *this, + chunk_t assoc) +{ + struct { + u_int8_t next_payload; + u_int8_t flags; + u_int16_t length; + u_int16_t fragment_number; + u_int16_t total_fragments; + } __attribute__((packed)) header = { + .next_payload = this->next_payload, + .flags = this->flags, + .length = htons(frag_get_length(this)), + .fragment_number = htons(this->fragment_number), + .total_fragments = htons(this->total_fragments), + }; + return chunk_cat("cc", assoc, chunk_from_thing(header)); +} + +METHOD(encrypted_payload_t, frag_encrypt, status_t, + private_encrypted_fragment_payload_t *this, u_int64_t mid, chunk_t assoc) +{ + status_t status; + + if (!this->aead) + { + DBG1(DBG_ENC, "encrypting encrypted fragment payload failed, " + "transform missing"); + return INVALID_STATE; + } + free(this->encrypted.ptr); + assoc = append_header_frag(this, assoc); + status = encrypt_content("encrypted fragment payload", this->aead, mid, + this->plain, assoc, &this->encrypted); + free(assoc.ptr); + return status; +} + +METHOD(encrypted_payload_t, frag_decrypt, status_t, + private_encrypted_fragment_payload_t *this, chunk_t assoc) +{ + status_t status; + + if (!this->aead) + { + DBG1(DBG_ENC, "decrypting encrypted fragment payload failed, " + "transform missing"); + return INVALID_STATE; + } + free(this->plain.ptr); + assoc = append_header_frag(this, assoc); + status = decrypt_content("encrypted fragment payload", this->aead, + this->encrypted, assoc, &this->plain); + this->plain = chunk_clone(this->plain); + free(assoc.ptr); + return status; +} + +METHOD2(payload_t, encrypted_payload_t, frag_destroy, void, + private_encrypted_fragment_payload_t *this) +{ + free(this->encrypted.ptr); + free(this->plain.ptr); + free(this); +} + +/* + * Described in header + */ +encrypted_fragment_payload_t *encrypted_fragment_payload_create() +{ + private_encrypted_fragment_payload_t *this; + + INIT(this, + .public = { + .encrypted = { + .payload_interface = { + .verify = _frag_verify, + .get_encoding_rules = _frag_get_encoding_rules, + .get_header_length = _frag_get_header_length, + .get_length = _frag_get_length, + .get_next_type = _frag_get_next_type, + .set_next_type = _frag_set_next_type, + .get_type = _frag_get_type, + .destroy = _frag_destroy, + }, + .get_length = _frag_get_length, + .add_payload = _frag_add_payload, + .remove_payload = (void*)return_null, + .generate_payloads = nop, + .set_transform = _frag_set_transform, + .encrypt = _frag_encrypt, + .decrypt = _frag_decrypt, + .destroy = _frag_destroy, + }, + .get_fragment_number = _get_fragment_number, + .get_total_fragments = _get_total_fragments, + .get_content = _frag_get_content, + }, + .next_payload = PL_NONE, + ); + this->payload_length = frag_get_header_length(this); + + return &this->public; +} + +/* + * Described in header + */ +encrypted_fragment_payload_t *encrypted_fragment_payload_create_from_data( + u_int16_t num, u_int16_t total, chunk_t plain) +{ + private_encrypted_fragment_payload_t *this; + + this = (private_encrypted_fragment_payload_t*)encrypted_fragment_payload_create(); + this->fragment_number = num; + this->total_fragments = total; + this->plain = chunk_clone(plain); + + return &this->public; +} diff --git a/src/libcharon/encoding/payloads/encrypted_payload.h b/src/libcharon/encoding/payloads/encrypted_payload.h new file mode 100644 index 000000000..be59e3c2d --- /dev/null +++ b/src/libcharon/encoding/payloads/encrypted_payload.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2014 Tobias Brunner + * Copyright (C) 2005-2010 Martin Willi + * Copyright (C) 2010 revosec AG + * 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 . + * + * 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 encrypted_payload encrypted_payload + * @{ @ingroup payloads + */ + +#ifndef ENCRYPTED_PAYLOAD_H_ +#define ENCRYPTED_PAYLOAD_H_ + +typedef struct encrypted_payload_t encrypted_payload_t; + +#include +#include +#include +#include + +/** + * The encrypted payload as described in RFC section 3.14. + */ +struct encrypted_payload_t { + + /** + * Implements payload_t interface. + */ + payload_t payload_interface; + + /** + * Get the payload length. + * + * @return (expected) payload length + */ + size_t (*get_length)(encrypted_payload_t *this); + + /** + * Adds a payload to this encryption payload. + * + * @param payload payload_t object to add + */ + void (*add_payload) (encrypted_payload_t *this, payload_t *payload); + + /** + * Remove the first payload in the list + * + * @param payload removed payload + * @return payload, NULL if none left + */ + payload_t* (*remove_payload)(encrypted_payload_t *this); + + /** + * Uses the given generator to generate the contained payloads. + * + * @param generator generator used to generate the contained payloads + */ + void (*generate_payloads)(encrypted_payload_t *this, + generator_t *generator); + + /** + * Set the AEAD transform to use. + * + * @param aead aead transform to use + */ + void (*set_transform) (encrypted_payload_t *this, aead_t *aead); + + /** + * Generate, encrypt and sign contained payloads. + * + * @param mid message ID + * @param assoc associated data + * @return + * - SUCCESS if encryption successful + * - FAILED if encryption failed + * - INVALID_STATE if aead not supplied, but needed + */ + status_t (*encrypt) (encrypted_payload_t *this, u_int64_t mid, + chunk_t assoc); + + /** + * Decrypt, verify and parse contained payloads. + * + * @param assoc associated data + * @return + * - 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 (*decrypt) (encrypted_payload_t *this, chunk_t assoc); + + /** + * Destroys an encrypted_payload_t object. + */ + void (*destroy) (encrypted_payload_t *this); +}; + +/** + * Creates an empty encrypted_payload_t object. + * + * @param type PLV2_ENCRYPTED or PLV1_ENCRYPTED + * @return encrypted_payload_t object + */ +encrypted_payload_t *encrypted_payload_create(payload_type_t type); + +/** + * Creates an encrypted payload with the given plain text data and next payload + * type. + * + * @param next next payload type + * @param plain plaintext data (gets adopted) + * @return encrypted_payload_t object + */ +encrypted_payload_t *encrypted_payload_create_from_plain(payload_type_t next, + chunk_t plain); + +#endif /** ENCRYPTED_PAYLOAD_H_ @}*/ diff --git a/src/libcharon/encoding/payloads/encryption_payload.c b/src/libcharon/encoding/payloads/encryption_payload.c deleted file mode 100644 index 5784562f8..000000000 --- a/src/libcharon/encoding/payloads/encryption_payload.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (C) 2005-2010 Martin Willi - * Copyright (C) 2010 revosec AG - * Copyright (C) 2011 Tobias Brunner - * 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 . - * - * 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 -#include - -#include "encryption_payload.h" - -#include -#include -#include -#include -#include - -typedef struct private_encryption_payload_t private_encryption_payload_t; - -/** - * Private data of an encryption_payload_t' Object. - * - */ -struct private_encryption_payload_t { - - /** - * Public encryption_payload_t interface. - */ - encryption_payload_t public; - - /** - * There is no next payload for an encryption payload, - * since encryption payload MUST be the last one. - * next_payload means here the first payload of the - * contained, encrypted payload. - */ - u_int8_t next_payload; - - /** - * Flags, including reserved bits - */ - u_int8_t flags; - - /** - * Length of this payload - */ - u_int16_t payload_length; - - /** - * Chunk containing the IV, plain, padding and ICV. - */ - chunk_t encrypted; - - /** - * AEAD transform to use - */ - aead_t *aead; - - /** - * Contained payloads - */ - linked_list_t *payloads; - - /** - * Type of payload, PLV2_ENCRYPTED or PLV1_ENCRYPTED - */ - payload_type_t type; -}; - -/** - * Encoding rules to parse or generate a IKEv2-Encryption Payload. - * - * The defined offsets are the positions in a object of type - * private_encryption_payload_t. - */ -static encoding_rule_t encodings_v2[] = { - /* 1 Byte next payload type, stored in the field next_payload */ - { U_INT_8, offsetof(private_encryption_payload_t, next_payload) }, - /* 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 */ - { CHUNK_DATA, offsetof(private_encryption_payload_t, encrypted) }, -}; - -/* - 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! Next Payload !C! RESERVED ! Payload Length ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! Initialization Vector ! - ! (length is block size for encryption algorithm) ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! Encrypted IKE Payloads ! - + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! ! Padding (0-255 octets) ! - +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ - ! ! Pad Length ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ~ Integrity Checksum Data ~ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -*/ - -/** - * Encoding rules to parse or generate a complete encrypted IKEv1 message. - * - * The defined offsets are the positions in a object of type - * private_encryption_payload_t. - */ -static encoding_rule_t encodings_v1[] = { - /* encrypted data, stored in a chunk */ - { ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) }, -}; - -/* - 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! Encrypted IKE Payloads ! - + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! ! Padding (0-255 octets) ! - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -*/ - -METHOD(payload_t, verify, status_t, - private_encryption_payload_t *this) -{ - return SUCCESS; -} - -METHOD(payload_t, get_encoding_rules, int, - private_encryption_payload_t *this, encoding_rule_t **rules) -{ - if (this->type == PLV2_ENCRYPTED) - { - *rules = encodings_v2; - return countof(encodings_v2); - } - *rules = encodings_v1; - return countof(encodings_v1); -} - -METHOD(payload_t, get_header_length, int, - private_encryption_payload_t *this) -{ - if (this->type == PLV2_ENCRYPTED) - { - return 4; - } - return 0; -} - -METHOD(payload_t, get_type, payload_type_t, - private_encryption_payload_t *this) -{ - return this->type; -} - -METHOD(payload_t, get_next_type, payload_type_t, - private_encryption_payload_t *this) -{ - return this->next_payload; -} - -METHOD(payload_t, set_next_type, void, - private_encryption_payload_t *this, payload_type_t type) -{ - /* the next payload is set during add, still allow this for IKEv1 */ - this->next_payload = type; -} - -/** - * Compute the length of the whole payload - */ -static void compute_length(private_encryption_payload_t *this) -{ - enumerator_t *enumerator; - payload_t *payload; - size_t bs, length = 0; - - if (this->encrypted.len) - { - length = this->encrypted.len; - } - else - { - 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 += get_header_length(this); - this->payload_length = length; -} - -METHOD2(payload_t, encryption_payload_t, get_length, size_t, - private_encryption_payload_t *this) -{ - compute_length(this); - return this->payload_length; -} - -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); - last_payload->set_next_type(last_payload, payload->get_type(payload)); - } - else - { - this->next_payload = payload->get_type(payload); - } - payload->set_next_type(payload, PL_NONE); - this->payloads->insert_last(this->payloads, payload); - compute_length(this); -} - -METHOD(encryption_payload_t, remove_payload, payload_t *, - private_encryption_payload_t *this) -{ - payload_t *payload; - - if (this->payloads->remove_first(this->payloads, - (void**)&payload) == SUCCESS) - { - return payload; - } - return NULL; -} - -/** - * Generate payload before encryption - */ -static chunk_t generate(private_encryption_payload_t *this, - generator_t *generator) -{ - payload_t *current, *next; - enumerator_t *enumerator; - u_int32_t *lenpos; - chunk_t chunk = chunk_empty; - - enumerator = this->payloads->create_enumerator(this->payloads); - if (enumerator->enumerate(enumerator, ¤t)) - { - this->next_payload = current->get_type(current); - - 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, PL_NONE); - generator->generate_payload(generator, current); - - chunk = generator->get_chunk(generator, &lenpos); - DBG2(DBG_ENC, "generated content in encryption payload"); - } - enumerator->destroy(enumerator); - return chunk; -} - -/** - * Append the encryption payload header to the associated data - */ -static chunk_t append_header(private_encryption_payload_t *this, chunk_t assoc) -{ - 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, status_t, - private_encryption_payload_t *this, u_int64_t mid, chunk_t assoc) -{ - chunk_t iv, plain, padding, icv, crypt; - generator_t *generator; - iv_gen_t *iv_gen; - rng_t *rng; - size_t bs; - - if (this->aead == NULL) - { - DBG1(DBG_ENC, "encrypting encryption payload failed, transform missing"); - return INVALID_STATE; - } - - rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); - if (!rng) - { - DBG1(DBG_ENC, "encrypting encryption payload failed, no RNG found"); - return NOT_SUPPORTED; - } - - iv_gen = this->aead->get_iv_gen(this->aead); - if (!iv_gen) - { - DBG1(DBG_ENC, "encrypting encryption payload failed, no IV generator"); - return NOT_SUPPORTED; - } - - assoc = append_header(this, assoc); - - 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); - - if (!iv_gen->get_iv(iv_gen, mid, iv.len, iv.ptr) || - !rng->get_bytes(rng, padding.len - 1, padding.ptr)) - { - DBG1(DBG_ENC, "encrypting encryption payload failed, no IV or padding"); - rng->destroy(rng); - free(assoc.ptr); - return FAILED; - } - padding.ptr[padding.len - 1] = padding.len - 1; - rng->destroy(rng); - - 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); - - if (!this->aead->encrypt(this->aead, crypt, assoc, iv, NULL)) - { - free(assoc.ptr); - return FAILED; - } - - DBG3(DBG_ENC, "encrypted %B", &crypt); - DBG3(DBG_ENC, "ICV %B", &icv); - - free(assoc.ptr); - - return SUCCESS; -} - -METHOD(encryption_payload_t, encrypt_v1, status_t, - private_encryption_payload_t *this, u_int64_t mid, chunk_t iv) -{ - generator_t *generator; - chunk_t plain, padding; - size_t bs; - - if (this->aead == NULL) - { - DBG1(DBG_ENC, "encryption failed, transform missing"); - return INVALID_STATE; - } - - generator = generator_create(); - plain = generate(this, generator); - bs = this->aead->get_block_size(this->aead); - padding.len = bs - (plain.len % bs); - - /* prepare data to encrypt: - * | plain | padding | */ - free(this->encrypted.ptr); - this->encrypted = chunk_alloc(plain.len + padding.len); - memcpy(this->encrypted.ptr, plain.ptr, plain.len); - plain.ptr = this->encrypted.ptr; - padding.ptr = plain.ptr + plain.len; - memset(padding.ptr, 0, padding.len); - generator->destroy(generator); - - DBG3(DBG_ENC, "encrypting payloads:"); - DBG3(DBG_ENC, "plain %B", &plain); - DBG3(DBG_ENC, "padding %B", &padding); - - if (!this->aead->encrypt(this->aead, this->encrypted, chunk_empty, iv, NULL)) - { - return FAILED; - } - - DBG3(DBG_ENC, "encrypted %B", &this->encrypted); - - return SUCCESS; -} - -/** - * Parse the payloads after decryption. - */ -static status_t parse(private_encryption_payload_t *this, chunk_t plain) -{ - parser_t *parser; - payload_type_t type; - - parser = parser_create(plain); - type = this->next_payload; - while (type != PL_NONE) - { - payload_t *payload; - - if (plain.len < 4 || untoh16(plain.ptr + 2) > plain.len) - { - DBG1(DBG_ENC, "invalid %N payload length, decryption failed?", - payload_type_names, type); - parser->destroy(parser); - return PARSE_ERROR; - } - if (parser->parse_payload(parser, type, &payload) != SUCCESS) - { - parser->destroy(parser); - return PARSE_ERROR; - } - if (payload->verify(payload) != SUCCESS) - { - DBG1(DBG_ENC, "%N verification failed", - payload_type_names, payload->get_type(payload)); - payload->destroy(payload); - parser->destroy(parser); - return VERIFY_ERROR; - } - type = payload->get_next_type(payload); - this->payloads->insert_last(this->payloads, payload); - } - parser->destroy(parser); - DBG2(DBG_ENC, "parsed content of encryption payload"); - return SUCCESS; -} - -METHOD(encryption_payload_t, decrypt, status_t, - private_encryption_payload_t *this, chunk_t assoc) -{ - chunk_t iv, plain, padding, icv, crypt; - size_t bs; - - if (this->aead == NULL) - { - DBG1(DBG_ENC, "decrypting encryption payload failed, transform missing"); - return INVALID_STATE; - } - - /* 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; - - if (iv.len + icv.len > this->encrypted.len || - (crypt.len - icv.len) % bs) - { - DBG1(DBG_ENC, "decrypting encryption payload failed, invalid length"); - return FAILED; - } - - assoc = append_header(this, assoc); - - 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); - - if (!this->aead->decrypt(this->aead, crypt, assoc, iv, NULL)) - { - DBG1(DBG_ENC, "verifying encryption payload integrity failed"); - free(assoc.ptr); - return FAILED; - } - free(assoc.ptr); - - 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, "decrypting encryption payload failed, " - "padding invalid %B", &crypt); - return PARSE_ERROR; - } - plain.len -= padding.len; - padding.ptr = plain.ptr + plain.len; - - DBG3(DBG_ENC, "plain %B", &plain); - DBG3(DBG_ENC, "padding %B", &padding); - - return parse(this, plain); -} - -METHOD(encryption_payload_t, decrypt_v1, status_t, - private_encryption_payload_t *this, chunk_t iv) -{ - if (this->aead == NULL) - { - DBG1(DBG_ENC, "decryption failed, transform missing"); - return INVALID_STATE; - } - - /* data must be a multiple of block size */ - if (iv.len != this->aead->get_block_size(this->aead) || - this->encrypted.len < iv.len || this->encrypted.len % iv.len) - { - DBG1(DBG_ENC, "decryption failed, invalid length"); - return FAILED; - } - - DBG3(DBG_ENC, "decrypting payloads:"); - DBG3(DBG_ENC, "encrypted %B", &this->encrypted); - - if (!this->aead->decrypt(this->aead, this->encrypted, chunk_empty, iv, NULL)) - { - return FAILED; - } - - DBG3(DBG_ENC, "plain %B", &this->encrypted); - - return parse(this, this->encrypted); -} - -METHOD(encryption_payload_t, set_transform, void, - private_encryption_payload_t *this, aead_t* aead) -{ - this->aead = aead; -} - -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); -} - -/* - * Described in header - */ -encryption_payload_t *encryption_payload_create(payload_type_t type) -{ - private_encryption_payload_t *this; - - INIT(this, - .public = { - .payload_interface = { - .verify = _verify, - .get_encoding_rules = _get_encoding_rules, - .get_header_length = _get_header_length, - .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 = PL_NONE, - .payloads = linked_list_create(), - .type = type, - ); - this->payload_length = get_header_length(this); - - if (type == PLV1_ENCRYPTED) - { - this->public.encrypt = _encrypt_v1; - this->public.decrypt = _decrypt_v1; - } - - return &this->public; -} diff --git a/src/libcharon/encoding/payloads/encryption_payload.h b/src/libcharon/encoding/payloads/encryption_payload.h deleted file mode 100644 index ee44c2de1..000000000 --- a/src/libcharon/encoding/payloads/encryption_payload.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2005-2010 Martin Willi - * Copyright (C) 2010 revosec AG - * 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 . - * - * 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 encryption_payload encryption_payload - * @{ @ingroup payloads - */ - -#ifndef ENCRYPTION_PAYLOAD_H_ -#define ENCRYPTION_PAYLOAD_H_ - -typedef struct encryption_payload_t encryption_payload_t; - -#include -#include -#include - -/** - * The encryption payload as described in RFC section 3.14. - */ -struct encryption_payload_t { - - /** - * Implements payload_t interface. - */ - payload_t payload_interface; - - /** - * Get the payload length. - * - * @return (expected) payload length - */ - size_t (*get_length)(encryption_payload_t *this); - - /** - * Adds a payload to this encryption payload. - * - * @param payload payload_t object to add - */ - void (*add_payload) (encryption_payload_t *this, payload_t *payload); - - /** - * Remove the first payload in the list - * - * @param payload removed payload - * @return payload, NULL if none left - */ - payload_t* (*remove_payload)(encryption_payload_t *this); - - /** - * Set the AEAD transform to use. - * - * @param aead aead transform to use - */ - void (*set_transform) (encryption_payload_t *this, aead_t *aead); - - /** - * Generate, encrypt and sign contained payloads. - * - * @param mid message ID - * @param assoc associated data - * @return - * - SUCCESS if encryption successful - * - FAILED if encryption failed - * - INVALID_STATE if aead not supplied, but needed - */ - status_t (*encrypt) (encryption_payload_t *this, u_int64_t mid, - chunk_t assoc); - - /** - * Decrypt, verify and parse contained payloads. - * - * @param assoc associated data - * @return - * - 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 (*decrypt) (encryption_payload_t *this, chunk_t assoc); - - /** - * Destroys an encryption_payload_t object. - */ - void (*destroy) (encryption_payload_t *this); -}; - -/** - * Creates an empty encryption_payload_t object. - * - * @param type PLV2_ENCRYPTED or PLV1_ENCRYPTED - * @return encryption_payload_t object - */ -encryption_payload_t *encryption_payload_create(payload_type_t type); - -#endif /** ENCRYPTION_PAYLOAD_H_ @}*/ diff --git a/src/libcharon/encoding/payloads/ike_header.c b/src/libcharon/encoding/payloads/ike_header.c index 7015667ee..c96738a34 100644 --- a/src/libcharon/encoding/payloads/ike_header.c +++ b/src/libcharon/encoding/payloads/ike_header.c @@ -210,8 +210,9 @@ METHOD(payload_t, verify, status_t, case TRANSACTION: case QUICK_MODE: case NEW_GROUP_MODE: - if (this->maj_version != IKEV1_MAJOR_VERSION) + if (this->maj_version == IKEV2_MAJOR_VERSION) { + /* IKEv1 exchange type in IKEv2? */ return FAILED; } break; @@ -223,14 +224,20 @@ METHOD(payload_t, verify, status_t, #ifdef ME case ME_CONNECT: #endif /* ME */ - if (this->maj_version != IKEV2_MAJOR_VERSION) + if (this->maj_version == IKEV1_MAJOR_VERSION) { + /* IKEv2 exchange type in IKEv1? */ return FAILED; } break; default: - /* unsupported exchange type */ - return FAILED; + if (this->maj_version == IKEV1_MAJOR_VERSION || + this->maj_version == IKEV2_MAJOR_VERSION) + { + /* unsupported exchange type for known version */ + return FAILED; + } + break; } if (this->initiator_spi == 0) { @@ -501,4 +508,3 @@ ike_header_t *ike_header_create_version(int major, int minor) } return this; } - diff --git a/src/libcharon/encoding/payloads/notify_payload.c b/src/libcharon/encoding/payloads/notify_payload.c index dd92e429a..94723ddd7 100644 --- a/src/libcharon/encoding/payloads/notify_payload.c +++ b/src/libcharon/encoding/payloads/notify_payload.c @@ -65,7 +65,7 @@ ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_ "ME_CONNECT_FAILED"); ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED, "MS_NOTIFY_STATUS"); -ENUM_NEXT(notify_type_names, INITIAL_CONTACT, IFOM_CAPABILITY, MS_NOTIFY_STATUS, +ENUM_NEXT(notify_type_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY_STATUS, "INITIAL_CONTACT", "SET_WINDOW_SIZE", "ADDITIONAL_TS_POSSIBLE", @@ -110,8 +110,10 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, IFOM_CAPABILITY, MS_NOTIFY_STATUS, "PSK_PERSIST", "PSK_CONFIRM", "ERX_SUPPORTED", - "IFOM_CAPABILITY"); -ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, IFOM_CAPABILITY, + "IFOM_CAPABILITY", + "SENDER_REQUEST_ID", + "FRAGMENTATION_SUPPORTED"); +ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, FRAGMENTATION_SUPPORTED, "INITIAL_CONTACT"); ENUM_NEXT(notify_type_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1, "DPD_R_U_THERE", @@ -128,7 +130,7 @@ ENUM_NEXT(notify_type_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE, "ME_CONNECTKEY", "ME_CONNECTAUTH", "ME_RESPONSE", - "RADIUS_ATTRIBUTE",); + "RADIUS_ATTRIBUTE"); ENUM_END(notify_type_names, RADIUS_ATTRIBUTE); @@ -172,7 +174,7 @@ ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_S "ME_CONN_FAIL"); ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED, "MS_STATUS"); -ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, IFOM_CAPABILITY, MS_NOTIFY_STATUS, +ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY_STATUS, "INIT_CONTACT", "SET_WINSIZE", "ADD_TS_POSS", @@ -217,8 +219,10 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, IFOM_CAPABILITY, MS_NOTIFY_S "PSK_PST", "PSK_CFM", "ERX_SUP", - "IFOM_CAP"); -ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, IFOM_CAPABILITY, + "IFOM_CAP", + "SENDER_REQ_ID", + "FRAG_SUP"); +ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, FRAGMENTATION_SUPPORTED, "INITIAL_CONTACT"); ENUM_NEXT(notify_type_short_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1, "DPD", diff --git a/src/libcharon/encoding/payloads/notify_payload.h b/src/libcharon/encoding/payloads/notify_payload.h index 3c56f0673..25521c2bb 100644 --- a/src/libcharon/encoding/payloads/notify_payload.h +++ b/src/libcharon/encoding/payloads/notify_payload.h @@ -147,6 +147,10 @@ enum notify_type_t { ERX_SUPPORTED = 16427, /* IFOM capability, 3GPP TS 24.303, annex B.2 */ IFOM_CAPABILITY = 16428, + /* SENDER_REQUEST_ID (draft-yeung-g-ikev2) */ + SENDER_REQUEST_ID = 16429, + /* IKEv2 fragmentation supported, RFC 7383 */ + FRAGMENTATION_SUPPORTED = 16430, /* IKEv1 initial contact */ INITIAL_CONTACT_IKEV1 = 24578, /* IKEv1 DPD */ diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c index fd616620d..600b6dd68 100644 --- a/src/libcharon/encoding/payloads/payload.c +++ b/src/libcharon/encoding/payloads/payload.c @@ -28,7 +28,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -59,7 +60,7 @@ ENUM_NEXT(payload_type_names, PLV1_SECURITY_ASSOCIATION, PLV1_CONFIGURATION, PL_ ENUM_NEXT(payload_type_names, PLV1_NAT_D, PLV1_NAT_OA, PLV1_CONFIGURATION, "NAT_D_V1", "NAT_OA_V1"); -ENUM_NEXT(payload_type_names, PLV2_SECURITY_ASSOCIATION, PLV2_GSPM, PLV1_NAT_OA, +ENUM_NEXT(payload_type_names, PLV2_SECURITY_ASSOCIATION, PLV2_FRAGMENT, PLV1_NAT_OA, "SECURITY_ASSOCIATION", "KEY_EXCHANGE", "ID_INITIATOR", @@ -76,16 +77,20 @@ ENUM_NEXT(payload_type_names, PLV2_SECURITY_ASSOCIATION, PLV2_GSPM, PLV1_NAT_OA, "ENCRYPTED", "CONFIGURATION", "EAP", - "GSPM"); + "GSPM", + "GROUP_ID", + "GROUP_SECURITY_ASSOCIATION", + "KEY_DOWNLOAD", + "ENCRYPTED_FRAGMENT"); #ifdef ME -ENUM_NEXT(payload_type_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_GSPM, +ENUM_NEXT(payload_type_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_FRAGMENT, "ID_PEER"); ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ID_PEER, "NAT_D_DRAFT_V1", "NAT_OA_DRAFT_V1", "FRAGMENT"); #else -ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_GSPM, +ENUM_NEXT(payload_type_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_FRAGMENT, "NAT_D_DRAFT_V1", "NAT_OA_DRAFT_V1", "FRAGMENT"); @@ -125,7 +130,7 @@ ENUM_NEXT(payload_type_short_names, PLV1_SECURITY_ASSOCIATION, PLV1_CONFIGURATIO ENUM_NEXT(payload_type_short_names, PLV1_NAT_D, PLV1_NAT_OA, PLV1_CONFIGURATION, "NAT-D", "NAT-OA"); -ENUM_NEXT(payload_type_short_names, PLV2_SECURITY_ASSOCIATION, PLV2_GSPM, PLV1_NAT_OA, +ENUM_NEXT(payload_type_short_names, PLV2_SECURITY_ASSOCIATION, PLV2_FRAGMENT, PLV1_NAT_OA, "SA", "KE", "IDi", @@ -142,16 +147,20 @@ ENUM_NEXT(payload_type_short_names, PLV2_SECURITY_ASSOCIATION, PLV2_GSPM, PLV1_N "E", "CP", "EAP", - "GSPM"); + "GSPM", + "IDg", + "GSA", + "KD", + "EF"); #ifdef ME -ENUM_NEXT(payload_type_short_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_GSPM, +ENUM_NEXT(payload_type_short_names, PLV2_ID_PEER, PLV2_ID_PEER, PLV2_FRAGMENT, "IDp"); ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_ID_PEER, "NAT-D", "NAT-OA", "FRAG"); #else -ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_GSPM, +ENUM_NEXT(payload_type_short_names, PLV1_NAT_D_DRAFT_00_03, PLV1_FRAGMENT, PLV2_FRAGMENT, "NAT-D", "NAT-OA", "FRAG"); @@ -244,9 +253,11 @@ payload_t *payload_create(payload_type_t type) return (payload_t*)eap_payload_create(); case PLV2_ENCRYPTED: case PLV1_ENCRYPTED: - return (payload_t*)encryption_payload_create(type); + return (payload_t*)encrypted_payload_create(type); case PLV1_FRAGMENT: return (payload_t*)fragment_payload_create(); + case PLV2_FRAGMENT: + return (payload_t*)encrypted_fragment_payload_create(); default: return (payload_t*)unknown_payload_create(type); } @@ -261,15 +272,19 @@ bool payload_is_known(payload_type_t type) { return TRUE; } - if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP) + if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION) { return TRUE; } - if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION) + if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA) { return TRUE; } - if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA) + if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP) + { + return TRUE; + } + if (type == PLV2_FRAGMENT) { return TRUE; } diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h index d9dd619f7..036cd422d 100644 --- a/src/libcharon/encoding/payloads/payload.h +++ b/src/libcharon/encoding/payloads/payload.h @@ -193,7 +193,7 @@ enum payload_type_t { PLV2_TS_RESPONDER = 45, /** - * Encryption payload, contains other payloads (E). + * Encrypted payload, contains other payloads (E). */ PLV2_ENCRYPTED = 46, @@ -212,6 +212,26 @@ enum payload_type_t { */ PLV2_GSPM = 49, + /** + * Group Identification (draft-yeung-g-ikev2) + */ + PLV2_IDG = 50, + + /** + * Group Security Association (draft-yeung-g-ikev2) + */ + PLV2_GSA = 51, + + /** + * Key Download (draft-yeung-g-ikev2) + */ + PLV2_KD = 52, + + /** + * Encrypted fragment payload (SKF), RFC 7383 + */ + PLV2_FRAGMENT = 53, + #ifdef ME /** * Identification payload for peers has a value from @@ -231,7 +251,7 @@ enum payload_type_t { PLV1_NAT_OA_DRAFT_00_03 = 131, /** - * IKE fragment (proprietary IKEv1 extension) + * IKEv1 fragment (proprietary IKEv1 extension) */ PLV1_FRAGMENT = 132, diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c index 8e3a01285..407038a2d 100644 --- a/src/libcharon/encoding/payloads/sa_payload.c +++ b/src/libcharon/encoding/payloads/sa_payload.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -296,7 +296,7 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*, linked_list_t *substructs, *list; if (this->type == PLV1_SECURITY_ASSOCIATION) - { /* IKEv1 proposals start with 0 */ + { /* IKEv1 proposals may start with 0 or 1 (or any other number really) */ struct_number = ignore_struct_number = -1; } @@ -309,17 +309,22 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*, enumerator = this->proposals->create_enumerator(this->proposals); while (enumerator->enumerate(enumerator, &substruct)) { + int current_number = substruct->get_proposal_number(substruct); + /* check if a proposal has a single protocol */ - if (substruct->get_proposal_number(substruct) == struct_number) + if (current_number == struct_number) { if (ignore_struct_number < struct_number) - { /* remove an already added, if first of series */ + { /* remove an already added substruct, if first of series */ substructs->remove_last(substructs, (void**)&substruct); ignore_struct_number = struct_number; } continue; } - struct_number++; + /* for IKEv1 the numbers don't have to be consecutive, for IKEv2 they do + * but since we don't really care for the actual number we accept them + * anyway. we already verified that they increase monotonically. */ + struct_number = current_number; substructs->insert_last(substructs, substruct); } enumerator->destroy(enumerator); @@ -364,7 +369,7 @@ METHOD(sa_payload_t, get_ipcomp_proposals, linked_list_t*, } if (proposal_number != current_proposal) { /* start of a new proposal */ - if (espah && ipcomp) + if (espah && ipcomp && ipcomp->get_cpi(ipcomp, NULL)) { /* previous proposal is valid */ break; } diff --git a/src/libcharon/network/receiver.c b/src/libcharon/network/receiver.c index a2a3b1f89..5ce9471bd 100644 --- a/src/libcharon/network/receiver.c +++ b/src/libcharon/network/receiver.c @@ -524,8 +524,7 @@ static job_requeue_t receive_packets(private_receiver_t *this) #ifdef USE_IKEV2 send_notify(message, IKEV2_MAJOR_VERSION, INFORMATIONAL, INVALID_MAJOR_VERSION, chunk_empty); -#endif /* USE_IKEV2 */ -#ifdef USE_IKEV1 +#elif defined(USE_IKEV1) send_notify(message, IKEV1_MAJOR_VERSION, INFORMATIONAL_V1, INVALID_MAJOR_VERSION, chunk_empty); #endif /* USE_IKEV1 */ @@ -684,4 +683,3 @@ receiver_t *receiver_create() return &this->public; } - diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in index 0655959ca..c3b014c3c 100644 --- a/src/libcharon/plugins/addrblock/Makefile.in +++ b/src/libcharon/plugins/addrblock/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/android_dns/Makefile.in b/src/libcharon/plugins/android_dns/Makefile.in index 287c94acc..50594a452 100644 --- a/src/libcharon/plugins/android_dns/Makefile.in +++ b/src/libcharon/plugins/android_dns/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/android_log/Makefile.in b/src/libcharon/plugins/android_log/Makefile.in index 9fd515073..700a4219c 100644 --- a/src/libcharon/plugins/android_log/Makefile.in +++ b/src/libcharon/plugins/android_log/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in index edda93e77..08101d51d 100644 --- a/src/libcharon/plugins/certexpire/Makefile.in +++ b/src/libcharon/plugins/certexpire/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in index 5670f4323..679d2dae6 100644 --- a/src/libcharon/plugins/coupling/Makefile.in +++ b/src/libcharon/plugins/coupling/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in index da364b06e..768c2b32b 100644 --- a/src/libcharon/plugins/dhcp/Makefile.in +++ b/src/libcharon/plugins/dhcp/Makefile.in @@ -233,6 +233,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -293,6 +294,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -358,6 +360,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -405,6 +409,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/dnscert/Makefile.in b/src/libcharon/plugins/dnscert/Makefile.in index d408cd24e..3484e08a3 100644 --- a/src/libcharon/plugins/dnscert/Makefile.in +++ b/src/libcharon/plugins/dnscert/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in index 97432f1b1..381d7a119 100644 --- a/src/libcharon/plugins/duplicheck/Makefile.in +++ b/src/libcharon/plugins/duplicheck/Makefile.in @@ -242,6 +242,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -302,6 +303,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -367,6 +369,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -414,6 +418,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in index 5b20fe5a6..3b0f8763c 100644 --- a/src/libcharon/plugins/eap_aka/Makefile.in +++ b/src/libcharon/plugins/eap_aka/Makefile.in @@ -236,6 +236,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -296,6 +297,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -361,6 +363,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -408,6 +412,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in index d0ee19899..839a379ea 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in +++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in @@ -237,6 +237,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -297,6 +298,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -362,6 +364,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -409,6 +413,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_dynamic/Makefile.in b/src/libcharon/plugins/eap_dynamic/Makefile.in index 78b66ac96..fdbad6234 100644 --- a/src/libcharon/plugins/eap_dynamic/Makefile.in +++ b/src/libcharon/plugins/eap_dynamic/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in index 7f18792c4..9675104da 100644 --- a/src/libcharon/plugins/eap_gtc/Makefile.in +++ b/src/libcharon/plugins/eap_gtc/Makefile.in @@ -234,6 +234,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -294,6 +295,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -359,6 +361,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -406,6 +410,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in index 5275a348c..0610b5859 100644 --- a/src/libcharon/plugins/eap_identity/Makefile.in +++ b/src/libcharon/plugins/eap_identity/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in index 5dd623d6e..38c9d0b7c 100644 --- a/src/libcharon/plugins/eap_md5/Makefile.in +++ b/src/libcharon/plugins/eap_md5/Makefile.in @@ -234,6 +234,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -294,6 +295,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -359,6 +361,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -406,6 +410,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in index c0e42198c..f5dfd6814 100644 --- a/src/libcharon/plugins/eap_mschapv2/Makefile.in +++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in index 615a916c1..5ccd58158 100644 --- a/src/libcharon/plugins/eap_peap/Makefile.in +++ b/src/libcharon/plugins/eap_peap/Makefile.in @@ -236,6 +236,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -296,6 +297,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -361,6 +363,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -408,6 +412,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in index cd4355dfa..04cc422f5 100644 --- a/src/libcharon/plugins/eap_radius/Makefile.in +++ b/src/libcharon/plugins/eap_radius/Makefile.in @@ -237,6 +237,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -297,6 +298,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -362,6 +364,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -409,6 +413,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c index 6719497d3..60d12dc1d 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius.c +++ b/src/libcharon/plugins/eap_radius/eap_radius.c @@ -413,6 +413,30 @@ static void add_unity_attribute(eap_radius_provider_t *provider, u_int32_t id, } } +/** + * Add a DNS/NBNS configuration attribute + */ +static void add_nameserver_attribute(eap_radius_provider_t *provider, + u_int32_t id, int type, chunk_t data) +{ + /* these are from different vendors, but there is currently no conflict */ + switch (type) + { + case 5: /* CVPN3000-Primary-DNS */ + case 6: /* CVPN3000-Secondary-DNS */ + case 28: /* MS-Primary-DNS-Server */ + case 29: /* MS-Secondary-DNS-Server */ + provider->add_attribute(provider, id, INTERNAL_IP4_DNS, data); + break; + case 7: /* CVPN3000-Primary-WINS */ + case 8: /* CVPN3000-Secondary-WINS */ + case 30: /* MS-Primary-NBNS-Server */ + case 31: /* MS-Secondary-NBNS-Server */ + provider->add_attribute(provider, id, INTERNAL_IP4_NBNS, data); + break; + } +} + /** * Add a UNITY_LOCAL_LAN or UNITY_SPLIT_INCLUDE attribute */ @@ -515,6 +539,16 @@ static void process_cfg_attributes(radius_message_t *msg) { switch (type) { + case 5: /* CVPN3000-Primary-DNS */ + case 6: /* CVPN3000-Secondary-DNS */ + case 7: /* CVPN3000-Primary-WINS */ + case 8: /* CVPN3000-Secondary-WINS */ + if (data.len == 4) + { + add_nameserver_attribute(provider, + ike_sa->get_unique_id(ike_sa), type, data); + } + break; case 15: /* CVPN3000-IPSec-Banner1 */ case 28: /* CVPN3000-IPSec-Default-Domain */ case 29: /* CVPN3000-IPSec-Split-DNS-Names */ @@ -546,6 +580,22 @@ static void process_cfg_attributes(radius_message_t *msg) break; } } + if (vendor == PEN_MICROSOFT) + { + switch (type) + { + case 28: /* MS-Primary-DNS-Server */ + case 29: /* MS-Secondary-DNS-Server */ + case 30: /* MS-Primary-NBNS-Server */ + case 31: /* MS-Secondary-NBNS-Server */ + if (data.len == 4) + { + add_nameserver_attribute(provider, + ike_sa->get_unique_id(ike_sa), type, data); + } + break; + } + } } enumerator->destroy(enumerator); diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c index 0020c5d57..31c96d229 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c @@ -488,6 +488,16 @@ static void send_start(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa) message->add(message, RAT_ACCT_SESSION_ID, chunk_create(entry->sid, strlen(entry->sid))); + if (!entry->interim.interval) + { + entry->interim.interval = lib->settings->get_time(lib->settings, + "%s.plugins.eap-radius.accounting_interval", 0, lib->ns); + if (entry->interim.interval) + { + DBG1(DBG_CFG, "scheduling RADIUS Interim-Updates every %us", + entry->interim.interval); + } + } schedule_interim(this, entry); this->mutex->unlock(this->mutex); diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in index 494efd99a..6a00ea74d 100644 --- a/src/libcharon/plugins/eap_sim/Makefile.in +++ b/src/libcharon/plugins/eap_sim/Makefile.in @@ -236,6 +236,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -296,6 +297,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -361,6 +363,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -408,6 +412,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in index 82e7561f8..7a08f4e0e 100644 --- a/src/libcharon/plugins/eap_sim_file/Makefile.in +++ b/src/libcharon/plugins/eap_sim_file/Makefile.in @@ -237,6 +237,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -297,6 +298,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -362,6 +364,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -409,6 +413,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in index 9a7a1909e..a1ec7adc1 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in +++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in @@ -238,6 +238,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -298,6 +299,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -363,6 +365,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -410,6 +414,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in index 886b0c575..bf99ab095 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in @@ -238,6 +238,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -298,6 +299,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -363,6 +365,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -410,6 +414,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in index 57c64246b..ce4602365 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in @@ -237,6 +237,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -297,6 +298,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -362,6 +364,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -409,6 +413,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in index eb4d3fa95..0c0b7fd52 100644 --- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in @@ -236,6 +236,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -296,6 +297,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -361,6 +363,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -408,6 +412,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in index c63d56b53..25696f524 100644 --- a/src/libcharon/plugins/eap_tls/Makefile.in +++ b/src/libcharon/plugins/eap_tls/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in index 97552dfd0..2d5d65875 100644 --- a/src/libcharon/plugins/eap_tnc/Makefile.in +++ b/src/libcharon/plugins/eap_tnc/Makefile.in @@ -236,6 +236,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -296,6 +297,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -361,6 +363,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -408,6 +412,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in index 70cc18405..38c7632ac 100644 --- a/src/libcharon/plugins/eap_ttls/Makefile.in +++ b/src/libcharon/plugins/eap_ttls/Makefile.in @@ -237,6 +237,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -297,6 +298,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -362,6 +364,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -409,6 +413,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/error_notify/Makefile.in b/src/libcharon/plugins/error_notify/Makefile.in index 0782dde53..d9fa454ca 100644 --- a/src/libcharon/plugins/error_notify/Makefile.in +++ b/src/libcharon/plugins/error_notify/Makefile.in @@ -243,6 +243,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -303,6 +304,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -368,6 +370,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -415,6 +419,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/ext_auth/Makefile.am b/src/libcharon/plugins/ext_auth/Makefile.am new file mode 100644 index 000000000..d51ea8881 --- /dev/null +++ b/src/libcharon/plugins/ext_auth/Makefile.am @@ -0,0 +1,18 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-ext-auth.la +else +plugin_LTLIBRARIES = libstrongswan-ext-auth.la +endif + +libstrongswan_ext_auth_la_SOURCES = ext_auth_plugin.h ext_auth_plugin.c \ + ext_auth_listener.h ext_auth_listener.c + +libstrongswan_ext_auth_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/ext_auth/Makefile.in b/src/libcharon/plugins/ext_auth/Makefile.in new file mode 100644 index 000000000..a1b47dd33 --- /dev/null +++ b/src/libcharon/plugins/ext_auth/Makefile.in @@ -0,0 +1,774 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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/ext_auth +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +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/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +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__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +libstrongswan_ext_auth_la_LIBADD = +am_libstrongswan_ext_auth_la_OBJECTS = ext_auth_plugin.lo \ + ext_auth_listener.lo +libstrongswan_ext_auth_la_OBJECTS = \ + $(am_libstrongswan_ext_auth_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libstrongswan_ext_auth_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_ext_auth_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_ext_auth_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_ext_auth_la_rpath = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +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) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libstrongswan_ext_auth_la_SOURCES) +DIST_SOURCES = $(libstrongswan_ext_auth_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEM = @GEM@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +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@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB = @OPENSSL_LIB@ +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@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +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_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +aikgen_plugins = @aikgen_plugins@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +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@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +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@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +swanctldir = @swanctldir@ +sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +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@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-ext-auth.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-ext-auth.la +libstrongswan_ext_auth_la_SOURCES = ext_auth_plugin.h ext_auth_plugin.c \ + ext_auth_listener.h ext_auth_listener.c + +libstrongswan_ext_auth_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/ext_auth/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/ext_auth/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)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + @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 " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ + 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)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libstrongswan-ext-auth.la: $(libstrongswan_ext_auth_la_OBJECTS) $(libstrongswan_ext_auth_la_DEPENDENCIES) $(EXTRA_libstrongswan_ext_auth_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_ext_auth_la_LINK) $(am_libstrongswan_ext_auth_la_rpath) $(libstrongswan_ext_auth_la_OBJECTS) $(libstrongswan_ext_auth_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext_auth_listener.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext_auth_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + 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-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +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 TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + cscopelist-am ctags ctags-am 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 tags-am 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/ext_auth/ext_auth_listener.c b/src/libcharon/plugins/ext_auth/ext_auth_listener.c new file mode 100644 index 000000000..06cec20d7 --- /dev/null +++ b/src/libcharon/plugins/ext_auth/ext_auth_listener.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2014 Vyronas Tsingaras (vtsingaras@it.auth.gr) + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * 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. + */ + +/* for vasprintf() */ +#define _GNU_SOURCE +#include "ext_auth_listener.h" + +#include +#include + +#include +#include + +typedef struct private_ext_auth_listener_t private_ext_auth_listener_t; + +/** + * Private data of an ext_auth_listener_t object. + */ +struct private_ext_auth_listener_t { + + /** + * Public ext_auth_listener_listener_t interface. + */ + ext_auth_listener_t public; + + /** + * Path to authorization program + */ + char *script; +}; + +/** + * Allocate and push a format string to the environment + */ +static bool push_env(char *envp[], u_int count, char *fmt, ...) +{ + int i = 0; + char *str; + va_list args; + + while (envp[i]) + { + if (++i + 1 >= count) + { + return FALSE; + } + } + va_start(args, fmt); + if (vasprintf(&str, fmt, args) >= 0) + { + envp[i] = str; + } + va_end(args); + return envp[i] != NULL; +} + +/** + * Free all allocated environment strings + */ +static void free_env(char *envp[]) +{ + int i; + + for (i = 0; envp[i]; i++) + { + free(envp[i]); + } +} + +METHOD(listener_t, authorize, bool, + private_ext_auth_listener_t *this, ike_sa_t *ike_sa, + bool final, bool *success) +{ + if (final) + { + FILE *shell; + process_t *process; + char *envp[32] = {}; + int out, retval; + + *success = FALSE; + + push_env(envp, countof(envp), "IKE_UNIQUE_ID=%u", + ike_sa->get_unique_id(ike_sa)); + push_env(envp, countof(envp), "IKE_NAME=%s", + ike_sa->get_name(ike_sa)); + + push_env(envp, countof(envp), "IKE_LOCAL_HOST=%H", + ike_sa->get_my_host(ike_sa)); + push_env(envp, countof(envp), "IKE_REMOTE_HOST=%H", + ike_sa->get_other_host(ike_sa)); + + push_env(envp, countof(envp), "IKE_LOCAL_ID=%Y", + ike_sa->get_my_id(ike_sa)); + push_env(envp, countof(envp), "IKE_REMOTE_ID=%Y", + ike_sa->get_other_id(ike_sa)); + + if (ike_sa->has_condition(ike_sa, COND_EAP_AUTHENTICATED) || + ike_sa->has_condition(ike_sa, COND_XAUTH_AUTHENTICATED)) + { + push_env(envp, countof(envp), "IKE_REMOTE_EAP_ID=%Y", + ike_sa->get_other_eap_id(ike_sa)); + } + + process = process_start_shell(envp, NULL, &out, NULL, + "2>&1 %s", this->script); + if (process) + { + shell = fdopen(out, "r"); + if (shell) + { + while (TRUE) + { + char resp[128], *e; + + if (fgets(resp, sizeof(resp), shell) == NULL) + { + if (ferror(shell)) + { + DBG1(DBG_CFG, "error reading from ext-auth script"); + } + break; + } + else + { + e = resp + strlen(resp); + if (e > resp && e[-1] == '\n') + { + e[-1] = '\0'; + } + DBG1(DBG_CHD, "ext-auth: %s", resp); + } + } + fclose(shell); + } + else + { + close(out); + } + if (process->wait(process, &retval)) + { + if (retval == EXIT_SUCCESS) + { + *success = TRUE; + } + else + { + DBG1(DBG_CFG, "rejecting IKE_SA for ext-auth result: %d", + retval); + } + } + } + free_env(envp); + } + return TRUE; +} + +METHOD(ext_auth_listener_t, destroy, void, + private_ext_auth_listener_t *this) +{ + free(this); +} + +/** + * See header + */ +ext_auth_listener_t *ext_auth_listener_create(char *script) +{ + private_ext_auth_listener_t *this; + + INIT(this, + .public = { + .listener = { + .authorize = _authorize, + }, + .destroy = _destroy, + }, + .script = script, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/ext_auth/ext_auth_listener.h b/src/libcharon/plugins/ext_auth/ext_auth_listener.h new file mode 100644 index 000000000..3fec83066 --- /dev/null +++ b/src/libcharon/plugins/ext_auth/ext_auth_listener.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014 Vyronas Tsingaras (vtsingaras@it.auth.gr) + * + * 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. + */ + +/** + * @defgroup ext_auth_listener ext_auth_listener + * @{ @ingroup ext_auth + */ + +#ifndef EXT_AUTH_LISTENER_H_ +#define EXT_AUTH_LISTENER_H_ + +#include + +typedef struct ext_auth_listener_t ext_auth_listener_t; + +/** + * Listener using an external script to authorize connection + */ +struct ext_auth_listener_t { + + /** + * Implements listener_t interface. + */ + listener_t listener; + + /** + * Destroy the listener. + */ + void (*destroy)(ext_auth_listener_t *this); +}; + +/** + * Create ext_auth_listener instance. + * + * @param script path to authorization script + * @return listener instance + */ +ext_auth_listener_t *ext_auth_listener_create(char *script); + +#endif /** ext_auth_LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/ext_auth/ext_auth_plugin.c b/src/libcharon/plugins/ext_auth/ext_auth_plugin.c new file mode 100644 index 000000000..b3698c767 --- /dev/null +++ b/src/libcharon/plugins/ext_auth/ext_auth_plugin.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2014 Vyronas Tsingaras (vtsingaras@it.auth.gr) + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * 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 "ext_auth_plugin.h" +#include "ext_auth_listener.h" + +#include + +typedef struct private_ext_auth_plugin_t private_ext_auth_plugin_t; + +/** + * private data of ext_auth plugin + */ +struct private_ext_auth_plugin_t { + + /** + * implements plugin interface + */ + ext_auth_plugin_t public; + + /** + * Listener verifying peers during authorization + */ + ext_auth_listener_t *listener; +}; + +METHOD(plugin_t, get_name, char*, + private_ext_auth_plugin_t *this) +{ + return "ext-auth"; +} + +/** + * Create a listener instance, NULL on error + */ +static ext_auth_listener_t* create_listener() +{ + char *script; + + script = lib->settings->get_str(lib->settings, + "%s.plugins.ext-auth.script", NULL, lib->ns); + if (!script) + { + DBG1(DBG_CFG, "no script for ext-auth script defined, disabled"); + return NULL; + } + DBG1(DBG_CFG, "using ext-auth script '%s'", script); + return ext_auth_listener_create(script); +} + +/** + * Register listener + */ +static bool plugin_cb(private_ext_auth_plugin_t *this, + plugin_feature_t *feature, bool reg, void *cb_data) +{ + if (reg) + { + this->listener = create_listener(); + if (!this->listener) + { + return FALSE; + } + charon->bus->add_listener(charon->bus, &this->listener->listener); + } + else + { + if (this->listener) + { + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); + } + } + return TRUE; +} + +METHOD(plugin_t, get_features, int, + private_ext_auth_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL), + PLUGIN_PROVIDE(CUSTOM, "ext_auth"), + }; + *features = f; + return countof(f); +} + + +METHOD(plugin_t, reload, bool, + private_ext_auth_plugin_t *this) +{ + ext_auth_listener_t *listener; + + /* reload new listener overlapped */ + listener = create_listener(); + if (listener) + { + charon->bus->add_listener(charon->bus, &listener->listener); + } + if (this->listener) + { + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->listener->destroy(this->listener); + } + this->listener = listener; + + return TRUE; +} + +METHOD(plugin_t, destroy, void, + private_ext_auth_plugin_t *this) +{ + free(this); +} + +/** + * Plugin constructor + */ +plugin_t *ext_auth_plugin_create() +{ + private_ext_auth_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .reload = _reload, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/ext_auth/ext_auth_plugin.h b/src/libcharon/plugins/ext_auth/ext_auth_plugin.h new file mode 100644 index 000000000..1288e240c --- /dev/null +++ b/src/libcharon/plugins/ext_auth/ext_auth_plugin.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 Vyronas Tsingaras (vtsingaras@it.auth.gr) + * + * 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. + */ + +/** + * @defgroup ext_auth ext_auth + * @ingroup cplugins + * + * @defgroup ext_auth_plugin ext_auth_plugin + * @{ @ingroup ext_auth + */ + +#ifndef EXT_AUTH_PLUGIN_H_ +#define EXT_AUTH_PLUGIN_H_ + +#include + +typedef struct ext_auth_plugin_t ext_auth_plugin_t; + +/** + * Plugin using an external script to authorize connections. + */ +struct ext_auth_plugin_t { + + /** + * Implements plugin interface. + */ + plugin_t plugin; +}; + +#endif /** EXT_AUTH_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in index 75ff158a8..2bfd38ba1 100644 --- a/src/libcharon/plugins/farp/Makefile.in +++ b/src/libcharon/plugins/farp/Makefile.in @@ -233,6 +233,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -293,6 +294,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -358,6 +360,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -405,6 +409,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in index cec73620a..aa5bdb747 100644 --- a/src/libcharon/plugins/ha/Makefile.in +++ b/src/libcharon/plugins/ha/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c index 6ff24c334..e20e872c1 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -437,11 +437,13 @@ static void process_ike_update(private_ha_dispatcher_t *this, pools->destroy(pools); } } +#ifdef USE_IKEV1 if (ike_sa->get_version(ike_sa) == IKEV1) { lib->processor->queue_job(lib->processor, (job_t*) adopt_children_job_create(ike_sa->get_id(ike_sa))); } +#endif /* USE_IKEV1 */ this->cache->cache(this->cache, ike_sa, message); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); } diff --git a/src/libcharon/plugins/ipseckey/Makefile.in b/src/libcharon/plugins/ipseckey/Makefile.in index da2e8d7fb..bd3fd63aa 100644 --- a/src/libcharon/plugins/ipseckey/Makefile.in +++ b/src/libcharon/plugins/ipseckey/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/kernel_iph/Makefile.in b/src/libcharon/plugins/kernel_iph/Makefile.in index 460c7b730..7e1f79bd8 100644 --- a/src/libcharon/plugins/kernel_iph/Makefile.in +++ b/src/libcharon/plugins/kernel_iph/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.in b/src/libcharon/plugins/kernel_libipsec/Makefile.in index a4e5ba931..c961c0bd8 100644 --- a/src/libcharon/plugins/kernel_libipsec/Makefile.in +++ b/src/libcharon/plugins/kernel_libipsec/Makefile.in @@ -237,6 +237,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -297,6 +298,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -362,6 +364,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -409,6 +413,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/kernel_wfp/Makefile.in b/src/libcharon/plugins/kernel_wfp/Makefile.in index ff987f8d4..1c92e30fc 100644 --- a/src/libcharon/plugins/kernel_wfp/Makefile.in +++ b/src/libcharon/plugins/kernel_wfp/Makefile.in @@ -243,6 +243,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -303,6 +304,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -368,6 +370,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -415,6 +419,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in index 78ec6660e..db4552dde 100644 --- a/src/libcharon/plugins/led/Makefile.in +++ b/src/libcharon/plugins/led/Makefile.in @@ -232,6 +232,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -292,6 +293,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -357,6 +359,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -404,6 +408,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in index df75c0f4b..418dccba5 100644 --- a/src/libcharon/plugins/load_tester/Makefile.in +++ b/src/libcharon/plugins/load_tester/Makefile.in @@ -245,6 +245,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -305,6 +306,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -370,6 +372,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -417,6 +421,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/lookip/Makefile.in b/src/libcharon/plugins/lookip/Makefile.in index deb517ed8..f0f2c75f4 100644 --- a/src/libcharon/plugins/lookip/Makefile.in +++ b/src/libcharon/plugins/lookip/Makefile.in @@ -241,6 +241,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -301,6 +302,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -366,6 +368,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -413,6 +417,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in index aa3ade079..3a866e968 100644 --- a/src/libcharon/plugins/maemo/Makefile.in +++ b/src/libcharon/plugins/maemo/Makefile.in @@ -237,6 +237,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -297,6 +298,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -362,6 +364,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -409,6 +413,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in index 919b936c0..e0f70ce44 100644 --- a/src/libcharon/plugins/medcli/Makefile.in +++ b/src/libcharon/plugins/medcli/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in index ce81fb1a8..adb61e817 100644 --- a/src/libcharon/plugins/medsrv/Makefile.in +++ b/src/libcharon/plugins/medsrv/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/osx_attr/Makefile.in b/src/libcharon/plugins/osx_attr/Makefile.in index 870b42790..a0c21c442 100644 --- a/src/libcharon/plugins/osx_attr/Makefile.in +++ b/src/libcharon/plugins/osx_attr/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in index 35ebf9975..14abba99a 100644 --- a/src/libcharon/plugins/radattr/Makefile.in +++ b/src/libcharon/plugins/radattr/Makefile.in @@ -236,6 +236,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -296,6 +297,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -361,6 +363,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -408,6 +412,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in index 35e7f2a87..7c5b030f4 100644 --- a/src/libcharon/plugins/smp/Makefile.in +++ b/src/libcharon/plugins/smp/Makefile.in @@ -233,6 +233,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -293,6 +294,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -358,6 +360,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -405,6 +409,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in index bee1259e6..548524a38 100644 --- a/src/libcharon/plugins/socket_default/Makefile.in +++ b/src/libcharon/plugins/socket_default/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c index 081d3efc7..9cc39955b 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -45,9 +45,6 @@ #include #include -/* Maximum size of a packet */ -#define MAX_PACKET 10000 - /* these are not defined on some platforms */ #ifndef SOL_IP #define SOL_IP IPPROTO_IP @@ -739,7 +736,7 @@ socket_default_socket_t *socket_default_socket_create() .natt = lib->settings->get_int(lib->settings, "%s.port_nat_t", CHARON_NATT_PORT, lib->ns), .max_packet = lib->settings->get_int(lib->settings, - "%s.max_packet", MAX_PACKET, lib->ns), + "%s.max_packet", PACKET_MAX_DEFAULT, lib->ns), .set_source = lib->settings->get_bool(lib->settings, "%s.plugins.socket-default.set_source", TRUE, lib->ns), diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in index 073806d64..892549c6c 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.in +++ b/src/libcharon/plugins/socket_dynamic/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c index 3161a709f..b82a69e1b 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c @@ -42,9 +42,6 @@ #include #include -/* Maximum size of a packet */ -#define MAX_PACKET 10000 - /* these are not defined on some platforms */ #ifndef SOL_IP #define SOL_IP IPPROTO_IP @@ -668,7 +665,7 @@ socket_dynamic_socket_t *socket_dynamic_socket_create() }, .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), .max_packet = lib->settings->get_int(lib->settings, - "%s.max_packet", MAX_PACKET, lib->ns), + "%s.max_packet", PACKET_MAX_DEFAULT, lib->ns), ); if (pipe(this->notify) != 0) diff --git a/src/libcharon/plugins/socket_win/Makefile.in b/src/libcharon/plugins/socket_win/Makefile.in index ff38e8158..88b2ac3f0 100644 --- a/src/libcharon/plugins/socket_win/Makefile.in +++ b/src/libcharon/plugins/socket_win/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/socket_win/socket_win_socket.c b/src/libcharon/plugins/socket_win/socket_win_socket.c index 5ebe04aac..fbfbedae1 100644 --- a/src/libcharon/plugins/socket_win/socket_win_socket.c +++ b/src/libcharon/plugins/socket_win/socket_win_socket.c @@ -25,9 +25,6 @@ #include -/* Maximum size of a packet */ -#define MAX_PACKET 10000 - /* number of sockets in use */ #define SOCKET_COUNT 2 @@ -458,7 +455,7 @@ socket_win_socket_t *socket_win_socket_create() "%s.port_nat_t", CHARON_NATT_PORT, lib->ns), }, .max_packet = lib->settings->get_int(lib->settings, - "%s.max_packet", MAX_PACKET, lib->ns), + "%s.max_packet", PACKET_MAX_DEFAULT, lib->ns), ); for (i = 0; i < SOCKET_COUNT; i++) diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in index 208b900e1..3c132457b 100644 --- a/src/libcharon/plugins/sql/Makefile.in +++ b/src/libcharon/plugins/sql/Makefile.in @@ -233,6 +233,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -293,6 +294,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -358,6 +360,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -405,6 +409,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in index 59a59834a..d4680186a 100644 --- a/src/libcharon/plugins/stroke/Makefile.in +++ b/src/libcharon/plugins/stroke/Makefile.in @@ -237,6 +237,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -297,6 +298,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -362,6 +364,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -409,6 +413,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c index f908219ed..83431d17c 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.c +++ b/src/libcharon/plugins/stroke/stroke_cred.c @@ -64,6 +64,11 @@ struct private_stroke_cred_t { */ stroke_cred_t public; + /** + * secrets file with credential information + */ + char *secrets_file; + /** * credentials */ @@ -1297,7 +1302,7 @@ METHOD(stroke_cred_t, reread, void, if (msg->reread.flags & REREAD_SECRETS) { DBG1(DBG_CFG, "rereading secrets"); - load_secrets(this, NULL, SECRETS_FILE, 0, prompt); + load_secrets(this, NULL, this->secrets_file, 0, prompt); } if (msg->reread.flags & REREAD_CACERTS) { @@ -1370,6 +1375,9 @@ stroke_cred_t *stroke_cred_create() .cachecrl = _cachecrl, .destroy = _destroy, }, + .secrets_file = lib->settings->get_str(lib->settings, + "%s.plugins.stroke.secrets_file", SECRETS_FILE, + lib->ns), .creds = mem_cred_create(), ); @@ -1380,7 +1388,7 @@ stroke_cred_t *stroke_cred_create() FALSE, lib->ns); load_certs(this); - load_secrets(this, NULL, SECRETS_FILE, 0, NULL); + load_secrets(this, NULL, this->secrets_file, 0, NULL); return &this->public; } diff --git a/src/libcharon/plugins/systime_fix/Makefile.in b/src/libcharon/plugins/systime_fix/Makefile.in index 769ad52bc..0e477f9f3 100644 --- a/src/libcharon/plugins/systime_fix/Makefile.in +++ b/src/libcharon/plugins/systime_fix/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in index 51d46a673..3f2952c4b 100644 --- a/src/libcharon/plugins/tnc_ifmap/Makefile.in +++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in @@ -238,6 +238,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -298,6 +299,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -363,6 +365,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -410,6 +414,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in index 531c00c0c..97c479632 100644 --- a/src/libcharon/plugins/tnc_pdp/Makefile.in +++ b/src/libcharon/plugins/tnc_pdp/Makefile.in @@ -239,6 +239,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -299,6 +300,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -364,6 +366,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -411,6 +415,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in index 948db7e3c..5e16c3c35 100644 --- a/src/libcharon/plugins/uci/Makefile.in +++ b/src/libcharon/plugins/uci/Makefile.in @@ -233,6 +233,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -293,6 +294,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -358,6 +360,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -405,6 +409,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/unit_tester/Makefile.in index 6e4dbff2b..1aca319c7 100644 --- a/src/libcharon/plugins/unit_tester/Makefile.in +++ b/src/libcharon/plugins/unit_tester/Makefile.in @@ -238,6 +238,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -298,6 +299,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -363,6 +365,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -410,6 +414,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/unity/Makefile.in b/src/libcharon/plugins/unity/Makefile.in index 4d411f68e..1e04ebced 100644 --- a/src/libcharon/plugins/unity/Makefile.in +++ b/src/libcharon/plugins/unity/Makefile.in @@ -234,6 +234,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -294,6 +295,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -359,6 +361,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -406,6 +410,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/unity/unity_narrow.c b/src/libcharon/plugins/unity/unity_narrow.c index 9f72a80da..52a2c7f24 100644 --- a/src/libcharon/plugins/unity/unity_narrow.c +++ b/src/libcharon/plugins/unity/unity_narrow.c @@ -139,6 +139,23 @@ static void narrow_responder_post(child_cfg_t *child_cfg, linked_list_t *local) configured->destroy(configured); } +/** + * Check if any Split-Include attributes are active on this IKE_SA + */ +static bool has_split_includes(private_unity_narrow_t *this, ike_sa_t *ike_sa) +{ + enumerator_t *enumerator; + traffic_selector_t *ts; + bool has; + + enumerator = this->handler->create_include_enumerator(this->handler, + ike_sa->get_unique_id(ike_sa)); + has = enumerator->enumerate(enumerator, &ts); + enumerator->destroy(enumerator); + + return has; +} + METHOD(listener_t, narrow, bool, private_unity_narrow_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, narrow_hook_t type, linked_list_t *local, linked_list_t *remote) @@ -146,23 +163,43 @@ METHOD(listener_t, narrow, bool, if (ike_sa->get_version(ike_sa) == IKEV1 && ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY)) { - switch (type) + /* depending on who initiates a rekeying the hooks will not match the + * roles in the IKE_SA */ + if (ike_sa->has_condition(ike_sa, COND_ORIGINAL_INITIATOR)) { - case NARROW_INITIATOR_PRE_AUTH: - narrow_pre(remote, "other"); - break; - case NARROW_INITIATOR_POST_AUTH: - narrow_initiator(this, ike_sa, - child_sa->get_config(child_sa), remote); - break; - case NARROW_RESPONDER: - narrow_pre(local, "us"); - break; - case NARROW_RESPONDER_POST: - narrow_responder_post(child_sa->get_config(child_sa), local); - break; - default: - break; + switch (type) + { + case NARROW_INITIATOR_PRE_AUTH: + case NARROW_RESPONDER: + if (has_split_includes(this, ike_sa)) + { + narrow_pre(remote, "other"); + } + break; + case NARROW_INITIATOR_POST_AUTH: + case NARROW_RESPONDER_POST: + narrow_initiator(this, ike_sa, + child_sa->get_config(child_sa), remote); + break; + default: + break; + } + } + else + { + switch (type) + { + case NARROW_INITIATOR_PRE_AUTH: + case NARROW_RESPONDER: + narrow_pre(local, "us"); + break; + case NARROW_INITIATOR_POST_AUTH: + case NARROW_RESPONDER_POST: + narrow_responder_post(child_sa->get_config(child_sa), local); + break; + default: + break; + } } } return TRUE; diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in index b377110ec..834d373f3 100644 --- a/src/libcharon/plugins/updown/Makefile.in +++ b/src/libcharon/plugins/updown/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c index 200f298a1..1d15cc55e 100644 --- a/src/libcharon/plugins/updown/updown_listener.c +++ b/src/libcharon/plugins/updown/updown_listener.c @@ -16,9 +16,11 @@ #define _GNU_SOURCE #include +#include #include "updown_listener.h" +#include #include #include #include @@ -97,53 +99,84 @@ static char* uncache_iface(private_updown_listener_t *this, u_int32_t reqid) } /** - * Create variables for handled DNS attributes + * Allocate and push a format string to the environment */ -static char *make_dns_vars(private_updown_listener_t *this, ike_sa_t *ike_sa) +static bool push_env(char *envp[], u_int count, char *fmt, ...) { - enumerator_t *enumerator; - host_t *host; - int v4 = 0, v6 = 0; - char total[512] = "", current[64]; + int i = 0; + char *str; + va_list args; - if (!this->handler) + while (envp[i]) { - return strdup(""); + if (++i + 1 >= count) + { + return FALSE; + } } + va_start(args, fmt); + if (vasprintf(&str, fmt, args) >= 0) + { + envp[i] = str; + } + va_end(args); + return envp[i] != NULL; +} - enumerator = this->handler->create_dns_enumerator(this->handler, - ike_sa->get_unique_id(ike_sa)); - while (enumerator->enumerate(enumerator, &host)) +/** + * Free all allocated environment strings + */ +static void free_env(char *envp[]) +{ + int i; + + for (i = 0; envp[i]; i++) { - switch (host->get_family(host)) + free(envp[i]); + } +} + +/** + * Push variables for handled DNS attributes + */ +static void push_dns_env(private_updown_listener_t *this, ike_sa_t *ike_sa, + char *envp[], u_int count) +{ + enumerator_t *enumerator; + host_t *host; + int v4 = 0, v6 = 0; + + if (this->handler) + { + enumerator = this->handler->create_dns_enumerator(this->handler, + ike_sa->get_unique_id(ike_sa)); + while (enumerator->enumerate(enumerator, &host)) { - case AF_INET: - snprintf(current, sizeof(current), - "PLUTO_DNS4_%d='%H' ", ++v4, host); - break; - case AF_INET6: - snprintf(current, sizeof(current), - "PLUTO_DNS6_%d='%H' ", ++v6, host); - break; - default: - continue; + switch (host->get_family(host)) + { + case AF_INET: + push_env(envp, count, "PLUTO_DNS4_%d=%H", ++v4, host); + break; + case AF_INET6: + push_env(envp, count, "PLUTO_DNS6_%d=%H", ++v6, host); + break; + default: + continue; + } } - strncat(total, current, sizeof(total) - strlen(total) - 1); + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); - - return strdup(total); } /** - * Create variables for local virtual IPs + * Push variables for local virtual IPs */ -static char *make_vip_vars(private_updown_listener_t *this, ike_sa_t *ike_sa) +static void push_vip_env(private_updown_listener_t *this, ike_sa_t *ike_sa, + char *envp[], u_int count) { enumerator_t *enumerator; host_t *host; int v4 = 0, v6 = 0; - char total[512] = "", current[64]; bool first = TRUE; enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE); @@ -151,28 +184,22 @@ static char *make_vip_vars(private_updown_listener_t *this, ike_sa_t *ike_sa) { if (first) { /* legacy variable for first VIP */ - snprintf(current, sizeof(current), - "PLUTO_MY_SOURCEIP='%H' ", host); - strncat(total, current, sizeof(total) - strlen(total) - 1); + first = FALSE; + push_env(envp, count, "PLUTO_MY_SOURCEIP=%H", host); } switch (host->get_family(host)) { case AF_INET: - snprintf(current, sizeof(current), - "PLUTO_MY_SOURCEIP4_%d='%H' ", ++v4, host); + push_env(envp, count, "PLUTO_MY_SOURCEIP4_%d=%H", ++v4, host); break; case AF_INET6: - snprintf(current, sizeof(current), - "PLUTO_MY_SOURCEIP6_%d='%H' ", ++v6, host); + push_env(envp, count, "PLUTO_MY_SOURCEIP6_%d=%H", ++v6, host); break; default: continue; } - strncat(total, current, sizeof(total) - strlen(total) - 1); } enumerator->destroy(enumerator); - - return strdup(total); } /** @@ -196,240 +223,182 @@ static u_int16_t get_port(traffic_selector_t *me, return local ? me->get_from_port(me) : other->get_from_port(other); } -METHOD(listener_t, child_updown, bool, - private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, - bool up) +/** + * Invoke the updown script once for given traffic selectors + */ +static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa, + child_sa_t *child_sa, child_cfg_t *config, bool up, + traffic_selector_t *my_ts, traffic_selector_t *other_ts) { - traffic_selector_t *my_ts, *other_ts; - enumerator_t *enumerator; - child_cfg_t *config; - host_t *me, *other; - char *script; + host_t *me, *other, *host; + char *iface; + u_int8_t mask; + mark_t mark; + bool is_host, is_ipv6; + int out; + FILE *shell; + process_t *process; + char *envp[128] = {}; - config = child_sa->get_config(child_sa); - script = config->get_updown(config); me = ike_sa->get_my_host(ike_sa); other = ike_sa->get_other_host(ike_sa); - if (script == NULL) + push_env(envp, countof(envp), "PLUTO_VERSION=1.1"); + is_host = my_ts->is_host(my_ts, me); + if (is_host) { - return TRUE; + is_ipv6 = me->get_family(me) == AF_INET6; } - - enumerator = child_sa->create_policy_enumerator(child_sa); - while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) + else { - char command[2048]; - host_t *my_client, *other_client; - u_int8_t my_client_mask, other_client_mask; - char *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc, *dns, *xauth; - mark_t mark; - bool is_host, is_ipv6, use_ipcomp; - FILE *shell; - - my_ts->to_subnet(my_ts, &my_client, &my_client_mask); - other_ts->to_subnet(other_ts, &other_client, &other_client_mask); - - virtual_ip = make_vip_vars(this, ike_sa); - - /* check for the presence of an inbound mark */ - mark = config->get_mark(config, TRUE); - if (mark.value) - { - if (asprintf(&mark_in, "PLUTO_MARK_IN='%u/0x%08x' ", - mark.value, mark.mask ) < 0) - { - mark_in = NULL; - } - } - else - { - if (asprintf(&mark_in, "") < 0) - { - mark_in = NULL; - } - } - - /* check for the presence of an outbound mark */ - mark = config->get_mark(config, FALSE); - if (mark.value) - { - if (asprintf(&mark_out, "PLUTO_MARK_OUT='%u/0x%08x' ", - mark.value, mark.mask ) < 0) - { - mark_out = NULL; - } - } - else - { - if (asprintf(&mark_out, "") < 0) - { - mark_out = NULL; - } - } - - /* check for a NAT condition causing ESP_IN_UDP encapsulation */ - if (ike_sa->has_condition(ike_sa, COND_NAT_ANY)) + is_ipv6 = my_ts->get_type(my_ts) == TS_IPV6_ADDR_RANGE; + } + push_env(envp, countof(envp), "PLUTO_VERB=%s%s%s", + up ? "up" : "down", + is_host ? "-host" : "-client", + is_ipv6 ? "-v6" : ""); + push_env(envp, countof(envp), "PLUTO_CONNECTION=%s", + config->get_name(config)); + if (up) + { + if (hydra->kernel_interface->get_interface(hydra->kernel_interface, + me, &iface)) { - if (asprintf(&udp_enc, "PLUTO_UDP_ENC='%u' ", - other->get_port(other)) < 0) - { - udp_enc = NULL; - } - + cache_iface(this, child_sa->get_reqid(child_sa), iface); } else { - if (asprintf(&udp_enc, "") < 0) - { - udp_enc = NULL; - } - + iface = NULL; } + } + else + { + iface = uncache_iface(this, child_sa->get_reqid(child_sa)); + } + push_env(envp, countof(envp), "PLUTO_INTERFACE=%s", + iface ? iface : "unknown"); + push_env(envp, countof(envp), "PLUTO_REQID=%u", + child_sa->get_reqid(child_sa)); + push_env(envp, countof(envp), "PLUTO_PROTO=%s", + child_sa->get_protocol(child_sa) == PROTO_ESP ? "esp" : "ah"); + push_env(envp, countof(envp), "PLUTO_UNIQUEID=%u", + ike_sa->get_unique_id(ike_sa)); + push_env(envp, countof(envp), "PLUTO_ME=%H", me); + push_env(envp, countof(envp), "PLUTO_MY_ID=%Y", ike_sa->get_my_id(ike_sa)); + if (my_ts->to_subnet(my_ts, &host, &mask)) + { + push_env(envp, countof(envp), "PLUTO_MY_CLIENT=%+H/%u", host, mask); + host->destroy(host); + } + push_env(envp, countof(envp), "PLUTO_MY_PORT=%u", + get_port(my_ts, other_ts, TRUE)); + push_env(envp, countof(envp), "PLUTO_MY_PROTOCOL=%u", + my_ts->get_protocol(my_ts)); + push_env(envp, countof(envp), "PLUTO_PEER=%H", other); + push_env(envp, countof(envp), "PLUTO_PEER_ID=%Y", + ike_sa->get_other_id(ike_sa)); + if (other_ts->to_subnet(other_ts, &host, &mask)) + { + push_env(envp, countof(envp), "PLUTO_PEER_CLIENT=%+H/%u", host, mask); + host->destroy(host); + } + push_env(envp, countof(envp), "PLUTO_PEER_PORT=%u", + get_port(my_ts, other_ts, FALSE)); + push_env(envp, countof(envp), "PLUTO_PEER_PROTOCOL=%u", + other_ts->get_protocol(other_ts)); + if (ike_sa->has_condition(ike_sa, COND_EAP_AUTHENTICATED) || + ike_sa->has_condition(ike_sa, COND_XAUTH_AUTHENTICATED)) + { + push_env(envp, countof(envp), "PLUTO_XAUTH_ID=%Y", + ike_sa->get_other_eap_id(ike_sa)); + } + push_vip_env(this, ike_sa, envp, countof(envp)); + mark = config->get_mark(config, TRUE); + if (mark.value) + { + push_env(envp, countof(envp), "PLUTO_MARK_IN=%u/0x%08x", + mark.value, mark.mask); + } + mark = config->get_mark(config, FALSE); + if (mark.value) + { + push_env(envp, countof(envp), "PLUTO_MARK_OUT=%u/0x%08x", + mark.value, mark.mask); + } + if (ike_sa->has_condition(ike_sa, COND_NAT_ANY)) + { + push_env(envp, countof(envp), "PLUTO_UDP_ENC=%u", + other->get_port(other)); + } + if (child_sa->get_ipcomp(child_sa) != IPCOMP_NONE) + { + push_env(envp, countof(envp), "PLUTO_IPCOMP=1"); + } + push_dns_env(this, ike_sa, envp, countof(envp)); + if (config->get_hostaccess(config)) + { + push_env(envp, countof(envp), "PLUTO_HOST_ACCESS=1"); + } - if (ike_sa->has_condition(ike_sa, COND_EAP_AUTHENTICATED) || - ike_sa->has_condition(ike_sa, COND_XAUTH_AUTHENTICATED)) - { - if (asprintf(&xauth, "PLUTO_XAUTH_ID='%Y' ", - ike_sa->get_other_eap_id(ike_sa)) < 0) - { - xauth = NULL; - } - } - else + process = process_start_shell(envp, NULL, &out, NULL, "2>&1 %s", + config->get_updown(config)); + if (process) + { + shell = fdopen(out, "r"); + if (shell) { - if (asprintf(&xauth, "") < 0) + while (TRUE) { - xauth = NULL; - } - } + char resp[128]; - if (up) - { - if (hydra->kernel_interface->get_interface(hydra->kernel_interface, - me, &iface)) - { - cache_iface(this, child_sa->get_reqid(child_sa), iface); - } - else - { - iface = NULL; + if (fgets(resp, sizeof(resp), shell) == NULL) + { + if (ferror(shell)) + { + DBG1(DBG_CHD, "error reading from updown script"); + } + break; + } + else + { + char *e = resp + strlen(resp); + if (e > resp && e[-1] == '\n') + { + e[-1] = '\0'; + } + DBG1(DBG_CHD, "updown: %s", resp); + } } + fclose(shell); } else { - iface = uncache_iface(this, child_sa->get_reqid(child_sa)); + close(out); } + process->wait(process, NULL); + } + free(iface); + free_env(envp); +} - dns = make_dns_vars(this, ike_sa); - - /* check for IPComp */ - use_ipcomp = child_sa->get_ipcomp(child_sa) != IPCOMP_NONE; - - /* determine IPv4/IPv6 and client/host situation */ - is_host = my_ts->is_host(my_ts, me); - is_ipv6 = is_host ? (me->get_family(me) == AF_INET6) : - (my_ts->get_type(my_ts) == TS_IPV6_ADDR_RANGE); - - /* build the command with all env variables. - */ - snprintf(command, sizeof(command), - "2>&1 " - "PLUTO_VERSION='1.1' " - "PLUTO_VERB='%s%s%s' " - "PLUTO_CONNECTION='%s' " - "PLUTO_INTERFACE='%s' " - "PLUTO_REQID='%u' " - "PLUTO_PROTO='%s' " - "PLUTO_UNIQUEID='%u' " - "PLUTO_ME='%H' " - "PLUTO_MY_ID='%Y' " - "PLUTO_MY_CLIENT='%+H/%u' " - "PLUTO_MY_PORT='%u' " - "PLUTO_MY_PROTOCOL='%u' " - "PLUTO_PEER='%H' " - "PLUTO_PEER_ID='%Y' " - "PLUTO_PEER_CLIENT='%+H/%u' " - "PLUTO_PEER_PORT='%u' " - "PLUTO_PEER_PROTOCOL='%u' " - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s", - up ? "up" : "down", - is_host ? "-host" : "-client", - is_ipv6 ? "-v6" : "", - config->get_name(config), - iface ? iface : "unknown", - child_sa->get_reqid(child_sa), - child_sa->get_protocol(child_sa) == PROTO_ESP ? "esp" : "ah", - ike_sa->get_unique_id(ike_sa), - me, ike_sa->get_my_id(ike_sa), - my_client, my_client_mask, - get_port(my_ts, other_ts, TRUE), - my_ts->get_protocol(my_ts), - other, ike_sa->get_other_id(ike_sa), - other_client, other_client_mask, - get_port(my_ts, other_ts, FALSE), - other_ts->get_protocol(other_ts), - xauth, - virtual_ip, - mark_in, - mark_out, - udp_enc, - use_ipcomp ? "PLUTO_IPCOMP='1' " : "", - config->get_hostaccess(config) ? "PLUTO_HOST_ACCESS='1' " : "", - dns, - script); - my_client->destroy(my_client); - other_client->destroy(other_client); - free(virtual_ip); - free(mark_in); - free(mark_out); - free(udp_enc); - free(dns); - free(iface); - free(xauth); - - DBG3(DBG_CHD, "running updown script: %s", command); - shell = popen(command, "r"); - - if (shell == NULL) - { - DBG1(DBG_CHD, "could not execute updown script '%s'", script); - return TRUE; - } +METHOD(listener_t, child_updown, bool, + private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + bool up) +{ + traffic_selector_t *my_ts, *other_ts; + enumerator_t *enumerator; + child_cfg_t *config; - while (TRUE) + config = child_sa->get_config(child_sa); + if (config->get_updown(config)) + { + enumerator = child_sa->create_policy_enumerator(child_sa); + while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { - char resp[128]; - - if (fgets(resp, sizeof(resp), shell) == NULL) - { - if (ferror(shell)) - { - DBG1(DBG_CHD, "error reading output from updown script"); - } - break; - } - else - { - char *e = resp + strlen(resp); - if (e > resp && e[-1] == '\n') - { /* trim trailing '\n' */ - e[-1] = '\0'; - } - DBG1(DBG_CHD, "updown: %s", resp); - } + invoke_once(this, ike_sa, child_sa, config, up, my_ts, other_ts); } - pclose(shell); + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); return TRUE; } diff --git a/src/libcharon/plugins/vici/Makefile.am b/src/libcharon/plugins/vici/Makefile.am index 7e459c58d..da71de394 100644 --- a/src/libcharon/plugins/vici/Makefile.am +++ b/src/libcharon/plugins/vici/Makefile.am @@ -67,3 +67,10 @@ vici_tests_LDFLAGS = @COVERAGE_LDFLAGS@ vici_tests_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ $(top_builddir)/src/libstrongswan/tests/libtest.la + + +SUBDIRS = + +if USE_RUBY_GEMS +SUBDIRS += ruby +endif diff --git a/src/libcharon/plugins/vici/Makefile.in b/src/libcharon/plugins/vici/Makefile.in index e0a6a1b5d..34546b905 100644 --- a/src/libcharon/plugins/vici/Makefile.in +++ b/src/libcharon/plugins/vici/Makefile.in @@ -80,6 +80,7 @@ build_triplet = @build@ host_triplet = @host@ TESTS = vici_tests$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) +@USE_RUBY_GEMS_TRUE@am__append_1 = ruby subdir = src/libcharon/plugins/vici DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -206,11 +207,27 @@ SOURCES = $(libstrongswan_vici_la_SOURCES) $(libvici_la_SOURCES) \ $(vici_tests_SOURCES) DIST_SOURCES = $(libstrongswan_vici_la_SOURCES) $(libvici_la_SOURCES) \ $(vici_tests_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -252,7 +269,33 @@ am__tty_colors = { \ std=''; \ fi; \ } +DIST_SUBDIRS = ruby DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ @@ -284,6 +327,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -344,6 +388,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -409,6 +454,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -456,6 +503,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ @@ -520,7 +571,8 @@ vici_tests_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ $(top_builddir)/src/libstrongswan/tests/libtest.la -all: all-am +SUBDIRS = $(am__append_1) +all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -869,14 +921,61 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am +tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ @@ -889,7 +988,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $$unique; \ fi; \ fi -ctags: ctags-am +ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) @@ -902,7 +1001,7 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am +cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ @@ -1044,24 +1143,50 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am +check: check-recursive all-am: Makefile $(LTLIBRARIES) -installdirs: +installdirs: installdirs-recursive +installdirs-am: for dir in "$(DESTDIR)$(ipseclibdir)" "$(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: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -installcheck: installcheck-am +installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ @@ -1085,96 +1210,97 @@ distclean-generic: 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: clean-recursive clean-am: clean-checkPROGRAMS clean-generic clean-ipseclibLTLIBRARIES \ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ mostlyclean-am -distclean: distclean-am +distclean: distclean-recursive -rm -rf ./$(DEPDIR) suites/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags -dvi: dvi-am +dvi: dvi-recursive dvi-am: -html: html-am +html: html-recursive html-am: -info: info-am +info: info-recursive info-am: install-data-am: install-ipseclibLTLIBRARIES install-pluginLTLIBRARIES -install-dvi: install-dvi-am +install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: -install-html: install-html-am +install-html: install-html-recursive install-html-am: -install-info: install-info-am +install-info: install-info-recursive install-info-am: install-man: -install-pdf: install-pdf-am +install-pdf: install-pdf-recursive install-pdf-am: -install-ps: install-ps-am +install-ps: install-ps-recursive install-ps-am: installcheck-am: -maintainer-clean: maintainer-clean-am +maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) suites/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-am +mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool -pdf: pdf-am +pdf: pdf-recursive pdf-am: -ps: ps-am +ps: ps-recursive ps-am: uninstall-am: uninstall-ipseclibLTLIBRARIES \ uninstall-pluginLTLIBRARIES -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ - clean-checkPROGRAMS clean-generic clean-ipseclibLTLIBRARIES \ - clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ - cscopelist-am ctags ctags-am 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-ipseclibLTLIBRARIES \ - 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 tags-am uninstall uninstall-am \ +.MAKE: $(am__recursive_targets) check-am install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-TESTS check-am clean clean-checkPROGRAMS clean-generic \ + clean-ipseclibLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES cscopelist-am \ + ctags ctags-am 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-ipseclibLTLIBRARIES install-man \ + install-pdf install-pdf-am install-pluginLTLIBRARIES \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ uninstall-ipseclibLTLIBRARIES uninstall-pluginLTLIBRARIES diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md index aeabbbd4d..272491052 100644 --- a/src/libcharon/plugins/vici/README.md +++ b/src/libcharon/plugins/vici/README.md @@ -84,12 +84,12 @@ The message encoding consists of a sequence of elements. Each element starts with the element type, optionally followed by an element name and/or an element value. Currently the following message element types are defined: -* _SECTION_START = 0_: Begin a new section having a name -* _SECTION_END = 1_: End a previously started section -* _KEY_VALUE = 2_: Define a value for a named key in the current section -* _LIST_START = 3_: Begin a named list for list items -* _LIST_ITEM = 4_: Define an unnamed item value in the current list -* _LIST_END = 5_: End a previously started list +* _SECTION_START = 1_: Begin a new section having a name +* _SECTION_END = 2_: End a previously started section +* _KEY_VALUE = 3_: Define a value for a named key in the current section +* _LIST_START = 4_: Begin a named list for list items +* _LIST_ITEM = 5_: Define an unnamed item value in the current list +* _LIST_END = 6_: End a previously started list Types are encoded as 8-bit values. Types having a name (SECTION_START, KEY_VALUE and LIST_START) have an ASCII string following the type, which itself @@ -103,7 +103,8 @@ the length field itself. The interpretation of any value is not defined by the message format; it can take arbitrary blobs. The application may specify types for specific keys, such -as strings or integer representations. +as strings or integer representations. The vici plugin currently uses +non-null terminated strings as values only; numbers get encoded as strings. ### Sections ### @@ -165,6 +166,513 @@ the following C array: 1, }; +## Client-initiated commands ## + +Based on the packet layer, VICI implements commands requested by the client +and responded to by the server using named _CMD_REQUEST_ and _CMD_RESPONSE_ +packets wrapping messages. The request message may contain command arguments, +the response message the reply. + +Some commands use response streaming, that is, a request triggers a series of +events to consecutively stream data to the client before the response message +completes the stream. A client must register for the appropriate event to +receive the stream, and unregister after the response has been received. + +The following client issued commands with the appropriate command input and +output messages are currently defined: + +### version() ### + +Returns daemon and system specific version information. + + {} => { + daemon = + version = + sysname = + release = + machine = + } + +### stats() ### + +Returns IKE daemon statistics and load information. + + {} => { + uptime = { + running = + since = + } + workers = { + total = + idle = + active = { + critical = + high = + medium = + low = + } + } + queues = { + critical = + high = + medium = + low = + } + scheduled = + ikesas = { + total = + half-open = + } + plugins = [ + + ] + mem = { # available if built with leak-detective or on Windows + total = + allocs = + * = { # on Windows only + total = + allocs = + } + } + mallinfo = { # available with mallinfo() support + sbrk = + mmap = + used = + free = + } + } + +### reload-settings() ### + +Reloads _strongswan.conf_ settings and all plugins supporting configuration +reload. + + {} => { + success = + errmsg = + } + +### initiate() ### + +Initiates an SA while streaming _control-log_ events. + + { + child = + timeout = + loglevel = + } => { + success = + errmsg = + } + +### terminate() ### + +Terminates an SA while streaming _control-log_ events. + + { + child = + ike = + child_id = + ike_id = + timeout = + loglevel = + } => { + success = + errmsg = + } + +### install() ### + +Install a trap, drop or bypass policy defined by a CHILD_SA config. + + { + child = + } => { + success = + errmsg = + } + +### uninstall() ### + +Uninstall a trap, drop or bypass policy defined by a CHILD_SA config. + + { + child = + } => { + success = + errmsg = + } + +### list-sas() ### + +Lists currently active IKE_SAs and associated CHILD_SAs by streaming _list-sa_ +events. + + { + noblock = + ike = + ike_id = + } => { + # completes after streaming list-sa events + } + +### list-policies() ### + +List currently installed trap, drop and bypass policies by streaming +_list-policy_ events. + + { + drop = + pass = + trap = + child = + } => { + # completes after streaming list-sa events + } + +### list-conns() ### + +List currently loaded connections by streaming _list-conn_ events. This +call includes all connections known by the daemon, not only those loaded +over vici. + + { + ike = + } => { + # completes after streaming list-conn events + } + +### get-conns() ### + +Return a list of connection names loaded exclusively over vici, not including +connections found in other backends. + + {} => { + conns = [ + + ] + } + +### list-certs() ### + +List currently loaded certificates by streaming _list-cert_ events. This +call includes all certificates known by the daemon, not only those loaded +over vici. + + { + type = + subject = + } => { + # completes after streaming list-cert events + } + +### load-conn() ### + +Load a single connection definition into the daemon. An existing connection +with the same name gets updated or replaced. + + { + = { + # IKE configuration parameters with authentication and CHILD_SA + # subsections. Refer to swanctl.conf(5) for details. + } => { + success = + errmsg = + } + } + +### unload-conn() ### + +Unload a previously loaded connection definition by name. + + { + name = + } => { + success = + errmsg = + } + +### load-cert() ### + +Load a certificate into the daemon. + + { + type = + data = + } => { + success = + errmsg = + } + +### load-key() ### + +Load a private key into the daemon. + + { + type = + data = + } => { + success = + errmsg = + } + +### load-shared() ### + +Load a shared IKE PSK, EAP or XAuth secret into the daemon. + + { + type = + data = + owners = [ + + ] + } => { + success = + errmsg = + } + +### clear-creds() ### + +Clear all loaded certificate, private key and shared key credentials. This +affects only credentials loaded over vici, but additionally flushes the +credential cache. + + {} => { + success = + errmsg = + } + +### load-pool() ### + +Load an in-memory virtual IP and configuration attribute pool. Existing +pools with the same name get updated, if possible. + + { + = { + addrs = + * = [ + # attribute type is one of address, dns, nbns, dhcp, netmask, + # server, subnet, split_include, split_exclude or a numerical + # attribute type identifier. + + ] + } + } => { + success = + errmsg = + } + +### unload-pool() ### + +Unload a previously loaded virtual IP and configuration attribute pool. +Unloading fails for pools with leases currently online. + + { + name = + } => { + success = + errmsg = + } + +### get-pools() ### + +List the currently loaded pools. + + {} => { + * = { + base = + size = + online = + offline = + } + } + +## Server-issued events ## + +Based on the packet layer, the vici plugin raises event messages using named +EVENT packets wrapping messages. The message contains event details. + +### log ### + +The _log_ event is issued to registered clients for each debug log message. +This event is not associated with a command. + + { + group = + level = + thread = + ikesa-name = + ikesa-uniqued = + msg = + } + +### control-log ### + +The _control-log_ event is issued for log events during active _initiate_ or +_terminate_ commands. It is issued only to clients currently having such +a command active. + + { + group = + level = + ikesa-name = + ikesa-uniqued = + msg = + } + +### list-sa ### + +The _list-sa_ event is issued to stream IKE_SAs during an active _list-sas_ +command. + + { + = { + uniqueid = + version = + state = + local-host = + local-id = + remote-host = + remote-id = + remote-xauth-id = + remote-eap-id = + initiator = + initiator-spi = + responder-spi = + encr-alg = + encr-keysize = + integ-alg = + integ-keysize = + prf-alg = + dh-group = + established = + rekey-time = + reauth-time = + tasks-queued = [ + + ] + tasks-active = [ + + ] + tasks-passive = [ + + ] + child-sas = { + * = { + reqid = + state = + mode = + protocol = + encap = + spi-in = + spi-out = + cpi-in = + cpi-out = + encr-alg = + encr-keysize = + integ-alg = + integ-keysize = + prf-alg = + dh-group = + esn = <1 if using extended sequence numbers> + bytes-in = + packets-in = + use-in = + bytes-out = + packets-out = + use-out = + rekey-time = + life-time = + install-time = + local-ts = [ + + ] + remote-ts = [ + + ] + } + } + } + } + +### list-policy ### + +The _list-policy_ event is issued to stream installed policies during an active +_list-policies_ command. + + { + = { + mode = + local-ts = [ + + ] + remote-ts = [ + + ] + } + } + +### list-conn ### + +The _list-conn_ event is issued to stream loaded connection during an active +_list-conns_ command. + + { + = { + local_addrs = [ + + ] + remote_addrs = [ + + ] + version = + + local*, remote* = { # multiple local and remote auth sections + class = + eap-type = + eap-vendor = + xauth = + revocation = + id = + aaa_id = + eap_id = + xauth_id = + groups = [ + + ] + certs = [ + + ] + cacerts = [ + + ] + } + children = { + * = { + mode = + local-ts = [ + + ] + remote-ts = [ + + ] + } + } + } + } + +### list-cert ### + +The _list-cert_ event is issued to stream loaded certificates during an active +_list-certs_ command. + + { + type = + has_privkey = + data = + } + + # libvici C client library # libvici is the reference implementation of a C client library implementing @@ -172,5 +680,177 @@ the vici protocol. It builds upon libstrongswan, but provides a stable API to implement client applications in the C programming language. libvici uses the libstrongswan thread pool to deliver event messages asynchronously. -More information about the libvici API is available in the libvici.h header -file. +## Connecting to the daemon ## + +This example shows how to connect to the daemon using the default URI, and +then perform proper cleanup: + + #include + #include + #include + + #include + + int main(int argc, char *argv[]) + { + vici_conn_t *conn; + int ret = 0; + + vici_init(); + conn = vici_connect(NULL); + if (conn) + { + /* do stuff */ + vici_disconnect(conn); + } + else + { + ret = errno; + fprintf(stderr, "connecting failed: %s\n", strerror(errno)); + } + vici_deinit(); + return ret; + } + +## A simple client request ## + +In the following example, a simple _version_ request is issued to the daemon +and the result is printed: + + int get_version(vici_conn_t *conn) + { + vici_req_t *req; + vici_res_t *res; + int ret = 0; + + req = vici_begin("version"); + res = vici_submit(req, conn); + if (res) + { + printf("%s %s (%s, %s, %s)\n", + vici_find_str(res, "", "daemon"), + vici_find_str(res, "", "version"), + vici_find_str(res, "", "sysname"), + vici_find_str(res, "", "release"), + vici_find_str(res, "", "machine")); + vici_free_res(res); + } + else + { + ret = errno; + fprintf(stderr, "version request failed: %s\n", strerror(errno)); + } + return ret; + } + +## A request with event streaming and callback parsing ## + +In this more advanced example, the _list-conns_ command is used to stream +loaded connections with the _list-conn_ event. The event message is parsed +with a simple callback to print the connection name: + + int conn_cb(void *null, vici_res_t *res, char *name) + { + printf("%s\n", name); + return 0; + } + + void list_cb(void *null, char *name, vici_res_t *res) + { + if (vici_parse_cb(res, conn_cb, NULL, NULL, NULL) != 0) + { + fprintf(stderr, "parsing failed: %s\n", strerror(errno)); + } + } + + int list_conns(vici_conn_t *conn) + { + vici_req_t *req; + vici_res_t *res; + int ret = 0; + + if (vici_register(conn, "list-conn", list_cb, NULL) == 0) + { + req = vici_begin("list-conns"); + res = vici_submit(req, conn); + if (res) + { + vici_free_res(res); + } + else + { + ret = errno; + fprintf(stderr, "request failed: %s\n", strerror(errno)); + } + vici_register(conn, "list-conn", NULL, NULL); + } + else + { + ret = errno; + fprintf(stderr, "registration failed: %s\n", strerror(errno)); + } + return ret; + } + +## API documentation ## + +More information about the libvici API is available in the _libvici.h_ header +file or the generated Doxygen documentation. + +# vici ruby gem # + +The _vici ruby gem_ is a pure ruby implementation of the VICI protocol to +implement client applications. It is provided in the _ruby_ subdirectory, and +gets built and installed if strongSwan has been _./configure_'d with +_--enable-vici_ and _--enable-ruby-gems_. + +The _Connection_ class from the _Vici_ module provides the high level interface, +the underlying classes are usually not required to build ruby applications +using VICI. The _Connection_ class provides methods for the supported VICI +commands and an event listening mechanism. + +To represent the VICI message data tree, the gem converts the binary encoding +to ruby data types. The _Connection_ class takes and returns ruby objects for +the exchanged message data: + * Sections get encoded as Hash, containing other sections as Hash, or + * Key/Values, where the values are Strings as Hash values + * Lists get encoded as Arrays with String values +Non-String values that are not a Hash nor an Array get converted with .to_s +during encoding. + +## Connecting to the daemon ## + +To create a connection to the daemon, a socket must be passed to the +_Connection_ constructor. There is no default, but on Unix systems usually +a Unix socket over _/var/run/charon.vici_ is used: + + require "vici" + require "socket" + + v = Vici::Connection.new(UNIXSocket.new("/var/run/charon.vici")) + +## A simple client request ## + +An example to print the daemon version information is as simple as: + + x = v.version + puts "%s %s (%s, %s, %s)" % [ + x["daemon"], x["version"], x["sysname"], x["release"], x["machine"] + ] + +## A request with closure invocation ## + +The _Connection_ class takes care of event streaming by invoking a closure +for each event. The following example lists all loaded connections using the +_list-conns_ command and implicitly the _list-conn_ event: + + v.list_conns { |conn| + conn.each { |key, value| + puts key + } + } + +## API documentation ## + +For more details about the ruby gem refer to the comments in the gem source +code or the generated documentation. diff --git a/src/libcharon/plugins/vici/libvici.c b/src/libcharon/plugins/vici/libvici.c index a2cbb3082..c0205ccb6 100644 --- a/src/libcharon/plugins/vici/libvici.c +++ b/src/libcharon/plugins/vici/libvici.c @@ -438,7 +438,7 @@ void vici_free_req(vici_req_t *req) free(req); } -int vici_dump(vici_res_t *res, char *label, bool pretty, FILE *out) +int vici_dump(vici_res_t *res, char *label, int pretty, FILE *out) { if (res->message->dump(res->message, label, pretty, out)) { @@ -754,11 +754,14 @@ void vici_init() library_init(NULL, "vici"); if (lib->processor->get_total_threads(lib->processor) < 4) { + dbg_default_set_level(0); lib->processor->set_threads(lib->processor, 4); + dbg_default_set_level(1); } } void vici_deinit() { + lib->processor->cancel(lib->processor); library_deinit(); } diff --git a/src/libcharon/plugins/vici/libvici.h b/src/libcharon/plugins/vici/libvici.h index 58595d8cc..641370efd 100644 --- a/src/libcharon/plugins/vici/libvici.h +++ b/src/libcharon/plugins/vici/libvici.h @@ -75,8 +75,6 @@ #include -#include - /** * Opaque vici connection contex. */ @@ -284,7 +282,7 @@ void vici_free_req(vici_req_t *req); * @param out FILE to dump to * @return 0 if dumped complete message, 1 on error */ -int vici_dump(vici_res_t *res, char *label, bool pretty, FILE *out); +int vici_dump(vici_res_t *res, char *label, int pretty, FILE *out); /** * Parse next element from a vici response message. diff --git a/src/libcharon/plugins/vici/ruby/Makefile.am b/src/libcharon/plugins/vici/ruby/Makefile.am new file mode 100644 index 000000000..ce38e1c3d --- /dev/null +++ b/src/libcharon/plugins/vici/ruby/Makefile.am @@ -0,0 +1,22 @@ +EXTRA_DIST = vici.gemspec.in lib/vici.rb + +vici.gemspec: $(srcdir)/vici.gemspec.in + $(AM_V_GEN) sed \ + -e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \ + $(srcdir)/vici.gemspec.in > $@ + +vici-$(PACKAGE_VERSION).gem: vici.gemspec + $(GEM) build vici.gemspec + +all-local: vici-$(PACKAGE_VERSION).gem + +clean-local: + rm -f vici.gemspec vici-$(PACKAGE_VERSION).gem + +install-data-local: vici-$(PACKAGE_VERSION).gem + $(GEM) install --install-dir $(DESTDIR)$(RUBYGEMDIR) \ + vici-$(PACKAGE_VERSION).gem + +uninstall-local: + $(GEM) uninstall --install-dir $(DESTDIR)$(RUBYGEMDIR) \ + --version $(PACKAGE_VERSION) vici diff --git a/src/libcharon/plugins/vici/ruby/Makefile.in b/src/libcharon/plugins/vici/ruby/Makefile.in new file mode 100644 index 000000000..c8a8c11fb --- /dev/null +++ b/src/libcharon/plugins/vici/ruby/Makefile.in @@ -0,0 +1,556 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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/vici/ruby +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +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/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEM = @GEM@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +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@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB = @OPENSSL_LIB@ +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@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +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_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +aikgen_plugins = @aikgen_plugins@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +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@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +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@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +swanctldir = @swanctldir@ +sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +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@ +EXTRA_DIST = vici.gemspec.in lib/vici.rb +all: all-am + +.SUFFIXES: +$(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/vici/ruby/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/vici/ruby/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): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +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 all-local +installdirs: +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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +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-local mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-data-local + +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 -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-local + +.MAKE: install-am install-strip + +.PHONY: all all-am all-local check check-am clean clean-generic \ + clean-libtool clean-local cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-data-local 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-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-local + + +vici.gemspec: $(srcdir)/vici.gemspec.in + $(AM_V_GEN) sed \ + -e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \ + $(srcdir)/vici.gemspec.in > $@ + +vici-$(PACKAGE_VERSION).gem: vici.gemspec + $(GEM) build vici.gemspec + +all-local: vici-$(PACKAGE_VERSION).gem + +clean-local: + rm -f vici.gemspec vici-$(PACKAGE_VERSION).gem + +install-data-local: vici-$(PACKAGE_VERSION).gem + $(GEM) install --install-dir $(DESTDIR)$(RUBYGEMDIR) \ + vici-$(PACKAGE_VERSION).gem + +uninstall-local: + $(GEM) uninstall --install-dir $(DESTDIR)$(RUBYGEMDIR) \ + --version $(PACKAGE_VERSION) vici + +# 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/vici/ruby/lib/vici.rb b/src/libcharon/plugins/vici/ruby/lib/vici.rb new file mode 100644 index 000000000..e8a9ddca9 --- /dev/null +++ b/src/libcharon/plugins/vici/ruby/lib/vici.rb @@ -0,0 +1,569 @@ +## +# The Vici module implements a native ruby client side library for the +# strongSwan VICI protocol. The Connection class provides a high-level +# interface to issue requests or listen for events. +# +# Copyright (C) 2014 Martin Willi +# Copyright (C) 2014 revosec AG +# +# 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. + +module Vici + + ## + # Vici specific exception all others inherit from + class Error < StandardError + end + + ## + # Error while parsing a vici message from the daemon + class ParseError < Error + end + + ## + # Error while encoding a vici message from ruby data structures + class EncodeError < Error + end + + ## + # Error while exchanging messages over the vici Transport layer + class TransportError < Error + end + + ## + # Generic vici command execution error + class CommandError < Error + end + + ## + # Error if an issued vici command is unknown by the daemon + class CommandUnknownError < CommandError + end + + ## + # Error if a command failed to execute in the daemon + class CommandExecError < CommandError + end + + ## + # Generic vici event handling error + class EventError < Error + end + + ## + # Tried to register to / unregister from an unknown vici event + class EventUnknownError < EventError + end + + ## + # Exception to raise from an event listening closure to stop listening + class StopEventListening < Exception + end + + + ## + # The Message class provides the low level encoding and decoding of vici + # protocol messages. Directly using this class is usually not required. + class Message + + SECTION_START = 1 + SECTION_END = 2 + KEY_VALUE = 3 + LIST_START = 4 + LIST_ITEM = 5 + LIST_END = 6 + + def initialize(data = "") + if data == nil + @root = Hash.new() + elsif data.is_a?(Hash) + @root = data + else + @encoded = data + end + end + + ## + # Get the raw byte encoding of an on-the-wire message + def encoding + if @encoded == nil + @encoded = encode(@root) + end + @encoded + end + + ## + # Get the root element of the parsed ruby data structures + def root + if @root == nil + @root = parse(@encoded) + end + @root + end + + private + + def encode_name(name) + [name.length].pack("c") << name + end + + def encode_value(value) + if value.class != String + value = value.to_s + end + [value.length].pack("n") << value + end + + def encode_kv(encoding, key, value) + encoding << KEY_VALUE << encode_name(key) << encode_value(value) + end + + def encode_section(encoding, key, value) + encoding << SECTION_START << encode_name(key) + encoding << encode(value) << SECTION_END + end + + def encode_list(encoding, key, value) + encoding << LIST_START << encode_name(key) + value.each do |item| + encoding << LIST_ITEM << encode_value(item) + end + encoding << LIST_END + end + + def encode(node) + encoding = "" + node.each do |key, value| + case value.class + when String, Fixnum, true, false + encoding = encode_kv(encoding, key, value) + else + if value.is_a?(Hash) + encoding = encode_section(encoding, key, value) + elsif value.is_a?(Array) + encoding = encode_list(encoding, key, value) + else + encoding = encode_kv(encoding, key, value) + end + end + end + encoding + end + + def parse_name(encoding) + len = encoding.unpack("c")[0] + name = encoding[1, len] + return encoding[(1 + len)..-1], name + end + + def parse_value(encoding) + len = encoding.unpack("n")[0] + value = encoding[2, len] + return encoding[(2 + len)..-1], value + end + + def parse(encoding) + stack = [Hash.new] + list = nil + while encoding.length != 0 do + type = encoding.unpack("c")[0] + encoding = encoding[1..-1] + case type + when SECTION_START + encoding, name = parse_name(encoding) + stack.push(stack[-1][name] = Hash.new) + when SECTION_END + if stack.length() == 1 + raise ParseError, "unexpected section end" + end + stack.pop() + when KEY_VALUE + encoding, name = parse_name(encoding) + encoding, value = parse_value(encoding) + stack[-1][name] = value + when LIST_START + encoding, name = parse_name(encoding) + stack[-1][name] = [] + list = name + when LIST_ITEM + raise ParseError, "unexpected list item" if list == nil + encoding, value = parse_value(encoding) + stack[-1][list].push(value) + when LIST_END + raise ParseError, "unexpected list end" if list == nil + list = nil + else + raise ParseError, "invalid type: #{type}" + end + end + if stack.length() > 1 + raise ParseError, "unexpected message end" + end + stack[0] + end + end + + + ## + # The Transport class implements to low level segmentation of packets + # to the underlying transport stream. Directly using this class is usually + # not required. + class Transport + + CMD_REQUEST = 0 + CMD_RESPONSE = 1 + CMD_UNKNOWN = 2 + EVENT_REGISTER = 3 + EVENT_UNREGISTER = 4 + EVENT_CONFIRM = 5 + EVENT_UNKNOWN = 6 + EVENT = 7 + + ## + # Create a transport layer using a provided socket for communication. + def initialize(socket) + @socket = socket + @events = Hash.new + end + + ## + # Write a packet prefixed by its length over the transport socket. Type + # specifies the message, the optional label and message get appended. + def write(type, label, message) + encoding = "" + if label + encoding << label.length << label + end + if message + encoding << message.encoding + end + @socket.send([encoding.length + 1, type].pack("Nc") + encoding, 0) + end + + ## + # Read a packet from the transport socket. Returns the packet type, and + # if available in the packet a label and the contained message. + def read + len = @socket.recv(4).unpack("N")[0] + encoding = @socket.recv(len) + type = encoding.unpack("c")[0] + len = 1 + case type + when CMD_REQUEST, EVENT_REGISTER, EVENT_UNREGISTER, EVENT + label = encoding[2, encoding[1].unpack("c")[0]] + len += label.length + 1 + when CMD_RESPONSE, CMD_UNKNOWN, EVENT_CONFIRM, EVENT_UNKNOWN + label = nil + else + raise TransportError, "invalid message: #{type}" + end + if encoding.length == len + return type, label, Message.new + end + return type, label, Message.new(encoding[len..-1]) + end + + def dispatch_event(name, message) + @events[name].each do |handler| + handler.call(name, message) + end + end + + def read_and_dispatch_event + type, label, message = read + p + if type == EVENT + dispatch_event(label, message) + else + raise TransportError, "unexpected message: #{type}" + end + end + + def read_and_dispatch_events + loop do + type, label, message = read + if type == EVENT + dispatch_event(label, message) + else + return type, label, message + end + end + end + + ## + # Send a command with a given name, and optionally a message. Returns + # the reply message on success. + def request(name, message = nil) + write(CMD_REQUEST, name, message) + type, label, message = read_and_dispatch_events + case type + when CMD_RESPONSE + return message + when CMD_UNKNOWN + raise CommandUnknownError, name + else + raise CommandError, "invalid response for #{name}" + end + end + + ## + # Register a handler method for the given event name + def register(name, handler) + write(EVENT_REGISTER, name, nil) + type, label, message = read_and_dispatch_events + case type + when EVENT_CONFIRM + if @events.has_key?(name) + @events[name] += [handler] + else + @events[name] = [handler]; + end + when EVENT_UNKNOWN + raise EventUnknownError, name + else + raise EventError, "invalid response for #{name} register" + end + end + + ## + # Unregister a handler method for the given event name + def unregister(name, handler) + write(EVENT_UNREGISTER, name, nil) + type, label, message = read_and_dispatch_events + case type + when EVENT_CONFIRM + @events[name] -= [handler] + when EVENT_UNKNOWN + raise EventUnknownError, name + else + raise EventError, "invalid response for #{name} unregister" + end + end + end + + + ## + # The Connection class provides the high-level interface to monitor, configure + # and control the IKE daemon. It takes a connected stream-oriented Socket for + # the communication with the IKE daemon. + # + # This class takes and returns ruby objects for the exchanged message data. + # * Sections get encoded as Hash, containing other sections as Hash, or + # * Key/Values, where the values are Strings as Hash values + # * Lists get encoded as Arrays with String values + # Non-String values that are not a Hash nor an Array get converted with .to_s + # during encoding. + class Connection + + def initialize(socket) + @transp = Transport.new(socket) + end + + ## + # List matching loaded connections. The provided closure is invoked + # for each matching connection. + def list_conns(match = nil, &block) + call_with_event("list-conns", Message.new(match), "list-conn", &block) + end + + ## + # List matching active SAs. The provided closure is invoked for each + # matching SA. + def list_sas(match = nil, &block) + call_with_event("list-sas", Message.new(match), "list-sa", &block) + end + + ## + # List matching installed policies. The provided closure is invoked + # for each matching policy. + def list_policies(match, &block) + call_with_event("list-policies", Message.new(match), "list-policy", + &block) + end + + ## + # List matching loaded certificates. The provided closure is invoked + # for each matching certificate definition. + def list_certs(match = nil, &block) + call_with_event("list-certs", Message.new(match), "list-cert", &block) + end + + ## + # Load a connection into the daemon. + def load_conn(conn) + check_success(@transp.request("load-conn", Message.new(conn))) + end + + ## + # Unload a connection from the daemon. + def unload_conn(conn) + check_success(@transp.request("unload-conn", Message.new(conn))) + end + + ## + # Get the names of connections managed by vici. + def get_conns() + @transp.request("get-conns").root + end + + ## + # Clear all loaded credentials. + def clear_creds() + check_success(@transp.request("clear-creds")) + end + + ## + # Load a certificate into the daemon. + def load_cert(cert) + check_success(@transp.request("load-cert", Message.new(cert))) + end + + ## + # Load a private key into the daemon. + def load_key(key) + check_success(@transp.request("load-key", Message.new(key))) + end + + ## + # Load a shared key into the daemon. + def load_shared(shared) + check_success(@transp.request("load-shared", Message.new(shared))) + end + + ## + # Load a virtual IP / attribute pool + def load_pool(pool) + check_success(@transp.request("load-pool", Message.new(pool))) + end + + ## + # Unload a virtual IP / attribute pool + def unload_pool(pool) + check_success(@transp.request("unload-pool", Message.new(pool))) + end + + ## + # Get the currently loaded pools. + def get_pools() + @transp.request("get-pools").root + end + + ## + # Initiate a connection. The provided closure is invoked for each log line. + def initiate(options, &block) + check_success(call_with_event("initiate", Message.new(options), + "control-log", &block)) + end + + ## + # Terminate a connection. The provided closure is invoked for each log line. + def terminate(options, &block) + check_success(call_with_event("terminate", Message.new(options), + "control-log", &block)) + end + + ## + # Install a shunt/route policy. + def install(policy) + check_success(@transp.request("install", Message.new(policy))) + end + + ## + # Uninstall a shunt/route policy. + def uninstall(policy) + check_success(@transp.request("uninstall", Message.new(policy))) + end + + ## + # Reload strongswan.conf settings. + def reload_settings + check_success(@transp.request("reload-settings", nil)) + end + + ## + # Get daemon statistics and information. + def stats + @transp.request("stats", nil).root + end + + ## + # Get daemon version information + def version + @transp.request("version", nil).root + end + + ## + # Listen for a set of event messages. This call is blocking, and invokes + # the passed closure for each event received. The closure receives the + # event name and the event message as argument. To stop listening, the + # closure may raise a StopEventListening exception, the only catched + # exception. + def listen_events(events, &block) + self.class.instance_eval do + define_method(:listen_event) do |label, message| + block.call(label, message.root) + end + end + events.each do |event| + @transp.register(event, method(:listen_event)) + end + begin + loop do + @transp.read_and_dispatch_event + end + rescue StopEventListening + ensure + events.each do |event| + @transp.unregister(event, method(:listen_event)) + end + end + end + + ## + # Issue a command request, but register for a specific event while the + # command is active. VICI uses this mechanism to stream potentially large + # data objects continuously. The provided closure is invoked for all + # event messages. + def call_with_event(command, request, event, &block) + self.class.instance_eval do + define_method(:call_event) do |label, message| + block.call(message.root) + end + end + @transp.register(event, method(:call_event)) + begin + reply = @transp.request(command, request) + ensure + @transp.unregister(event, method(:call_event)) + end + reply + end + + ## + # Check if the reply of a command indicates "success", otherwise raise a + # CommandExecError exception + def check_success(reply) + root = reply.root + if root["success"] != "yes" + raise CommandExecError, root["errmsg"] + end + root + end + end +end diff --git a/src/libcharon/plugins/vici/ruby/vici.gemspec.in b/src/libcharon/plugins/vici/ruby/vici.gemspec.in new file mode 100644 index 000000000..5ad61c0a0 --- /dev/null +++ b/src/libcharon/plugins/vici/ruby/vici.gemspec.in @@ -0,0 +1,16 @@ +Gem::Specification.new do |s| + s.name = "vici" + s.version = "@GEM_VERSION@" + s.authors = ["Martin Willi"] + s.email = ["martin@strongswan.ch"] + s.description = %q{ + The strongSwan VICI protocol allows external application to monitor, + configure and control the IKE daemon charon. This ruby gem provides a + native client side implementation of the VICI protocol, well suited to + script automated tasks in a relaible way. + } + s.summary = "Native ruby interface for strongSwan VICI" + s.homepage = "https://wiki.strongswan.org/projects/strongswan/wiki/Vici" + s.license = "MIT" + s.files = "lib/vici.rb" +end diff --git a/src/libcharon/plugins/vici/suites/test_message.c b/src/libcharon/plugins/vici/suites/test_message.c index 293117348..e76d27332 100644 --- a/src/libcharon/plugins/vici/suites/test_message.c +++ b/src/libcharon/plugins/vici/suites/test_message.c @@ -347,7 +347,7 @@ START_TEST(test_get_int) ck_assert_int_eq(m->get_int(m, 2, "section1.key2"), 0x12); ck_assert_int_eq(m->get_int(m, 2, "section1.section2.key3"), -1); ck_assert_int_eq(m->get_int(m, 2, "section1.key4"), 2); - ck_assert_int_eq(m->get_int(m, 2, "key5"), 0); + ck_assert_int_eq(m->get_int(m, 2, "key5"), 2); ck_assert_int_eq(m->get_int(m, 2, "nonexistent"), 2); ck_assert_int_eq(m->get_int(m, 2, "n.o.n.e.x.i.s.t.e.n.t"), 2); diff --git a/src/libcharon/plugins/vici/vici_control.c b/src/libcharon/plugins/vici/vici_control.c index 3cd008162..292a40032 100644 --- a/src/libcharon/plugins/vici/vici_control.c +++ b/src/libcharon/plugins/vici/vici_control.c @@ -450,6 +450,17 @@ CALLBACK(uninstall, vici_message_t*, return send_reply(this, "policy '%s' not found", child); } +CALLBACK(reload_settings, vici_message_t*, + private_vici_control_t *this, char *name, u_int id, vici_message_t *request) +{ + if (lib->settings->load_files(lib->settings, lib->conf, FALSE)) + { + lib->plugins->reload(lib->plugins, NULL); + return send_reply(this, NULL); + } + return send_reply(this, "reloading '%s' failed", lib->conf); +} + static void manage_command(private_vici_control_t *this, char *name, vici_command_cb_t cb, bool reg) { @@ -466,6 +477,7 @@ static void manage_commands(private_vici_control_t *this, bool reg) manage_command(this, "terminate", terminate, reg); manage_command(this, "install", install, reg); manage_command(this, "uninstall", uninstall, reg); + manage_command(this, "reload-settings", reload_settings, reg); this->dispatcher->manage_event(this->dispatcher, "control-log", reg); } diff --git a/src/libcharon/plugins/vici/vici_cred.c b/src/libcharon/plugins/vici/vici_cred.c index cc6434b62..d4c02de6d 100644 --- a/src/libcharon/plugins/vici/vici_cred.c +++ b/src/libcharon/plugins/vici/vici_cred.c @@ -270,13 +270,10 @@ CALLBACK(load_shared, vici_message_t*, CALLBACK(clear_creds, vici_message_t*, private_vici_cred_t *this, char *name, u_int id, vici_message_t *message) { - vici_builder_t *builder; - this->creds->clear(this->creds); lib->credmgr->flush_cache(lib->credmgr, CERT_ANY); - builder = vici_builder_create(); - return builder->finalize(builder); + return create_reply(NULL); } static void manage_command(private_vici_cred_t *this, diff --git a/src/libcharon/plugins/vici/vici_message.c b/src/libcharon/plugins/vici/vici_message.c index dcc175f67..e79fbc8d3 100644 --- a/src/libcharon/plugins/vici/vici_message.c +++ b/src/libcharon/plugins/vici/vici_message.c @@ -355,6 +355,10 @@ METHOD(vici_message_t, vget_int, int, found = find_value(this, &value, fmt, args); if (found) { + if (value.len == 0) + { + return def; + } if (chunk_printable(value, NULL, 0)) { snprintf(buf, sizeof(buf), "%.*s", (int)value.len, value.ptr); diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in index 8a714a9ea..b1cc1d118 100644 --- a/src/libcharon/plugins/whitelist/Makefile.in +++ b/src/libcharon/plugins/whitelist/Makefile.in @@ -242,6 +242,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -302,6 +303,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -367,6 +369,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -414,6 +418,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/xauth_eap/Makefile.in b/src/libcharon/plugins/xauth_eap/Makefile.in index 26bb6fb1a..e393ee163 100644 --- a/src/libcharon/plugins/xauth_eap/Makefile.in +++ b/src/libcharon/plugins/xauth_eap/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/xauth_generic/Makefile.in b/src/libcharon/plugins/xauth_generic/Makefile.in index f06fdb593..f0e772700 100644 --- a/src/libcharon/plugins/xauth_generic/Makefile.in +++ b/src/libcharon/plugins/xauth_generic/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/xauth_noauth/Makefile.in b/src/libcharon/plugins/xauth_noauth/Makefile.in index 72f3dc668..a4c1aaeb2 100644 --- a/src/libcharon/plugins/xauth_noauth/Makefile.in +++ b/src/libcharon/plugins/xauth_noauth/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/plugins/xauth_pam/Makefile.in b/src/libcharon/plugins/xauth_pam/Makefile.in index 9af015e29..296ccaa1c 100644 --- a/src/libcharon/plugins/xauth_pam/Makefile.in +++ b/src/libcharon/plugins/xauth_pam/Makefile.in @@ -235,6 +235,7 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GEM = @GEM@ GENHTML = @GENHTML@ GPERF = @GPERF@ GPRBUILD = @GPRBUILD@ @@ -295,6 +296,7 @@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ RUBYINCLUDE = @RUBYINCLUDE@ RUBYLIB = @RUBYLIB@ SED = @SED@ @@ -360,6 +362,8 @@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -407,6 +411,10 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ systemdsystemunitdir = @systemdsystemunitdir@ t_plugins = @t_plugins@ target_alias = @target_alias@ diff --git a/src/libcharon/processing/jobs/adopt_children_job.c b/src/libcharon/processing/jobs/adopt_children_job.c index f99c0b932..fb480eee2 100644 --- a/src/libcharon/processing/jobs/adopt_children_job.c +++ b/src/libcharon/processing/jobs/adopt_children_job.c @@ -17,6 +17,7 @@ #include #include +#include typedef struct private_adopt_children_job_t private_adopt_children_job_t; @@ -34,11 +35,17 @@ struct private_adopt_children_job_t { * IKE_SA id to adopt children from */ ike_sa_id_t *id; + + /** + * Tasks queued for execution + */ + array_t *tasks; }; METHOD(job_t, destroy, void, private_adopt_children_job_t *this) { + array_destroy_offset(this->tasks, offsetof(task_t, destroy)); this->id->destroy(this->id); free(this); } @@ -149,6 +156,32 @@ METHOD(job_t, execute, job_requeue_t, } } children->destroy_offset(children, offsetof(child_sa_t, destroy)); + + if (array_count(this->tasks)) + { + ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, + this->id); + if (ike_sa) + { + task_t *task; + + while (array_remove(this->tasks, ARRAY_HEAD, &task)) + { + task->migrate(task, ike_sa); + ike_sa->queue_task(ike_sa, task); + } + if (ike_sa->initiate(ike_sa, NULL, 0, NULL, NULL) == DESTROY_ME) + { + charon->ike_sa_manager->checkin_and_destroy( + charon->ike_sa_manager, ike_sa); + } + else + { + charon->ike_sa_manager->checkin(charon->ike_sa_manager, + ike_sa); + } + } + } } return JOB_REQUEUE_NONE; } @@ -159,6 +192,12 @@ METHOD(job_t, get_priority, job_priority_t, return JOB_PRIO_HIGH; } +METHOD(adopt_children_job_t, queue_task, void, + private_adopt_children_job_t *this, task_t *task) +{ + array_insert_create(&this->tasks, ARRAY_TAIL, task); +} + /** * See header */ @@ -173,6 +212,7 @@ adopt_children_job_t *adopt_children_job_create(ike_sa_id_t *id) .get_priority = _get_priority, .destroy = _destroy, }, + .queue_task = _queue_task, }, .id = id->clone(id), ); diff --git a/src/libcharon/processing/jobs/adopt_children_job.h b/src/libcharon/processing/jobs/adopt_children_job.h index 073504abd..ee99ee4e5 100644 --- a/src/libcharon/processing/jobs/adopt_children_job.h +++ b/src/libcharon/processing/jobs/adopt_children_job.h @@ -24,6 +24,7 @@ #include #include #include +#include typedef struct adopt_children_job_t adopt_children_job_t; @@ -36,6 +37,13 @@ struct adopt_children_job_t { * Implements job_t. */ job_t job_interface; + + /** + * Queue a job for execution after completing migration. + * + * @param task task to queue for execution + */ + void (*queue_task)(adopt_children_job_t *this, task_t *task); }; /** diff --git a/src/libcharon/processing/jobs/update_sa_job.c b/src/libcharon/processing/jobs/update_sa_job.c index 694318522..e6d7da2c6 100644 --- a/src/libcharon/processing/jobs/update_sa_job.c +++ b/src/libcharon/processing/jobs/update_sa_job.c @@ -63,12 +63,7 @@ METHOD(job_t, execute, job_requeue_t, } else { - /* we update only if other host is NATed, but not our */ - if (ike_sa->has_condition(ike_sa, COND_NAT_THERE) && - !ike_sa->has_condition(ike_sa, COND_NAT_HERE)) - { - ike_sa->update_hosts(ike_sa, NULL, this->new, FALSE); - } + ike_sa->update_hosts(ike_sa, NULL, this->new, FALSE); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); } return JOB_REQUEUE_NONE; diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index c338cdaef..d92b9df8e 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2013 Tobias Brunner + * Copyright (C) 2006-2014 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (c) 2014 Volker RĂ¼melin + * + * 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 #include #include @@ -251,6 +273,11 @@ struct private_ike_sa_t { * Flush auth configs once established? */ bool flush_auth_cfg; + + /** + * Maximum length of a single fragment, 0 for address-specific defaults + */ + size_t fragment_size; }; /** @@ -909,11 +936,14 @@ METHOD(ike_sa_t, update_hosts, void, update = TRUE; } - if (!other->equals(other, this->other_host)) + if (!other->equals(other, this->other_host) && + (force || has_condition(this, COND_NAT_THERE))) { - /* update others address if we are NOT NATed */ - if ((has_condition(this, COND_NAT_THERE) && - !has_condition(this, COND_NAT_HERE)) || force ) + /* only update other's address if we are behind a static NAT, + * which we assume is the case if we are not initiator */ + if (force || + (!has_condition(this, COND_NAT_HERE) || + !has_condition(this, COND_ORIGINAL_INITIATOR))) { set_other_host(this, other->clone(other)); update = TRUE; @@ -994,6 +1024,69 @@ METHOD(ike_sa_t, generate_message, status_t, return status; } +static bool filter_fragments(private_ike_sa_t *this, packet_t **fragment, + packet_t **packet) +{ + *packet = (*fragment)->clone(*fragment); + set_dscp(this, *packet); + return TRUE; +} + +METHOD(ike_sa_t, generate_message_fragmented, status_t, + private_ike_sa_t *this, message_t *message, enumerator_t **packets) +{ + enumerator_t *fragments; + packet_t *packet; + status_t status; + bool use_frags = FALSE; + + if (this->ike_cfg) + { + switch (this->ike_cfg->fragmentation(this->ike_cfg)) + { + case FRAGMENTATION_FORCE: + use_frags = TRUE; + break; + case FRAGMENTATION_YES: + use_frags = supports_extension(this, EXT_IKE_FRAGMENTATION); + if (use_frags && this->version == IKEV1 && + supports_extension(this, EXT_MS_WINDOWS)) + { + /* It seems Windows 7 and 8 peers only accept proprietary + * fragmented messages if they expect certificates. */ + use_frags = message->get_payload(message, + PLV1_CERTIFICATE) != NULL; + } + break; + default: + break; + } + } + if (!use_frags) + { + status = generate_message(this, message, &packet); + if (status != SUCCESS) + { + return status; + } + *packets = enumerator_create_single(packet, NULL); + return SUCCESS; + } + + this->stats[STAT_OUTBOUND] = time_monotonic(NULL); + message->set_ike_sa_id(message, this->ike_sa_id); + charon->bus->message(charon->bus, message, FALSE, TRUE); + status = message->fragment(message, this->keymat, this->fragment_size, + &fragments); + if (status == SUCCESS) + { + charon->bus->message(charon->bus, message, FALSE, FALSE); + *packets = enumerator_create_filter(fragments, (void*)filter_fragments, + this, NULL); + } + return status; +} + METHOD(ike_sa_t, set_kmaddress, void, private_ike_sa_t *this, host_t *local, host_t *remote) { @@ -1487,6 +1580,14 @@ METHOD(ike_sa_t, reauth, status_t, { return INVALID_STATE; } + if (this->state == IKE_CONNECTING) + { + DBG0(DBG_IKE, "reinitiating IKE_SA %s[%d]", + get_name(this), this->unique_id); + reset(this); + this->task_manager->queue_ike(this->task_manager); + return this->task_manager->initiate(this->task_manager); + } /* we can't reauthenticate as responder when we use EAP or virtual IPs. * If the peer does not support RFC4478, there is no way to keep the * IKE_SA up. */ @@ -1650,6 +1751,7 @@ METHOD(ike_sa_t, reestablish, status_t, new->set_other_host(new, host->clone(host)); host = this->my_host; new->set_my_host(new, host->clone(host)); + charon->bus->ike_reestablish_pre(charon->bus, &this->public, new); /* resolve hosts but use the old addresses above as fallback */ resolve_hosts((private_ike_sa_t*)new); /* if we already have a virtual IP, we reuse it */ @@ -1734,12 +1836,15 @@ METHOD(ike_sa_t, reestablish, status_t, if (status == DESTROY_ME) { + charon->bus->ike_reestablish_post(charon->bus, &this->public, new, + FALSE); charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new); status = FAILED; } else { - charon->bus->ike_reestablish(charon->bus, &this->public, new); + charon->bus->ike_reestablish_post(charon->bus, &this->public, new, + TRUE); charon->ike_sa_manager->checkin(charon->ike_sa_manager, new); status = SUCCESS; } @@ -1899,11 +2004,29 @@ static bool is_any_path_valid(private_ike_sa_t *this) bool valid = FALSE; enumerator_t *enumerator; host_t *src = NULL, *addr; + int family = AF_UNSPEC; + + switch (charon->socket->supported_families(charon->socket)) + { + case SOCKET_FAMILY_IPV4: + family = AF_INET; + break; + case SOCKET_FAMILY_IPV6: + family = AF_INET6; + break; + case SOCKET_FAMILY_BOTH: + case SOCKET_FAMILY_NONE: + break; + } DBG1(DBG_IKE, "old path is not available anymore, try to find another"); enumerator = create_peer_address_enumerator(this); while (enumerator->enumerate(enumerator, &addr)) { + if (family != AF_UNSPEC && addr->get_family(addr) != family) + { + continue; + } DBG1(DBG_IKE, "looking for a route to %H ...", addr); src = hydra->kernel_interface->get_source_addr( hydra->kernel_interface, addr, NULL); @@ -2332,6 +2455,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, .inherit_pre = _inherit_pre, .inherit_post = _inherit_post, .generate_message = _generate_message, + .generate_message_fragmented = _generate_message_fragmented, .reset = _reset, .get_unique_id = _get_unique_id, .add_virtual_ip = _add_virtual_ip, @@ -2377,6 +2501,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, "%s.retry_initiate_interval", 0, lib->ns), .flush_auth_cfg = lib->settings->get_bool(lib->settings, "%s.flush_auth_cfg", FALSE, lib->ns), + .fragment_size = lib->settings->get_int(lib->settings, + "%s.fragment_size", 0, lib->ns), ); if (version == IKEV2) diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 15fb47484..c72d87367 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2012 Tobias Brunner + * Copyright (C) 2006-2014 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -102,7 +102,7 @@ enum ike_extension_t { EXT_EAP_ONLY_AUTHENTICATION = (1<<5), /** - * peer is probably a Windows 7 RAS client + * peer is probably a Windows RAS client */ EXT_MS_WINDOWS = (1<<6), @@ -128,7 +128,7 @@ enum ike_extension_t { EXT_NATT_DRAFT_02_03 = (1<<10), /** - * peer support proprietary IKE fragmentation + * peer supports proprietary IKEv1 or standardized IKEv2 fragmentation */ EXT_IKE_FRAGMENTATION = (1<<11), }; @@ -756,7 +756,7 @@ struct ike_sa_t { status_t (*roam)(ike_sa_t *this, bool address); /** - * Processes a incoming IKEv2-Message. + * Processes an incoming IKE message. * * Message processing may fail. If a critical failure occurs, * process_message() return DESTROY_ME. Then the caller must @@ -768,10 +768,10 @@ struct ike_sa_t { * - FAILED * - DESTROY_ME if this IKE_SA MUST be deleted */ - status_t (*process_message) (ike_sa_t *this, message_t *message); + status_t (*process_message)(ike_sa_t *this, message_t *message); /** - * Generate a IKE message to send it to the peer. + * Generate an IKE message to send it to the peer. * * This method generates all payloads in the message and encrypts/signs * the packet. @@ -783,8 +783,26 @@ struct ike_sa_t { * - FAILED * - DESTROY_ME if this IKE_SA MUST be deleted */ - status_t (*generate_message) (ike_sa_t *this, message_t *message, - packet_t **packet); + status_t (*generate_message)(ike_sa_t *this, message_t *message, + packet_t **packet); + + /** + * Generate an IKE message to send it to the peer. If enabled and supported + * it will be fragmented. + * + * This method generates all payloads in the message and encrypts/signs + * the packet/fragments. + * + * @param message message to generate + * @param packets enumerator of generated packet_t* (are not destroyed + * with the enumerator) + * @return + * - SUCCESS + * - FAILED + * - DESTROY_ME if this IKE_SA MUST be deleted + */ + status_t (*generate_message_fragmented)(ike_sa_t *this, message_t *message, + enumerator_t **packets); /** * Retransmits a request. diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index 8e68e7bee..bdabc59b5 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -383,11 +383,6 @@ struct private_ike_sa_manager_t { */ rng_t *rng; - /** - * SHA1 hasher for IKE_SA_INIT retransmit detection - */ - hasher_t *hasher; - /** * reuse existing IKE_SAs in checkout_by_config */ @@ -962,49 +957,39 @@ static u_int64_t get_spi(private_ike_sa_manager_t *this) * * @returns TRUE on success */ -static bool get_init_hash(private_ike_sa_manager_t *this, message_t *message, - chunk_t *hash) +static bool get_init_hash(hasher_t *hasher, message_t *message, chunk_t *hash) { host_t *src; - if (!this->hasher) - { /* this might be the case when flush() has been called */ - return FALSE; - } if (message->get_first_payload_type(message) == PLV1_FRAGMENT) { /* only hash the source IP, port and SPI for fragmented init messages */ u_int16_t port; u_int64_t spi; src = message->get_source(message); - if (!this->hasher->allocate_hash(this->hasher, - src->get_address(src), NULL)) + if (!hasher->allocate_hash(hasher, src->get_address(src), NULL)) { return FALSE; } port = src->get_port(src); - if (!this->hasher->allocate_hash(this->hasher, - chunk_from_thing(port), NULL)) + if (!hasher->allocate_hash(hasher, chunk_from_thing(port), NULL)) { return FALSE; } spi = message->get_initiator_spi(message); - return this->hasher->allocate_hash(this->hasher, - chunk_from_thing(spi), hash); + return hasher->allocate_hash(hasher, chunk_from_thing(spi), hash); } if (message->get_exchange_type(message) == ID_PROT) { /* include the source for Main Mode as the hash will be the same if * SPIs are reused by two initiators that use the same proposal */ src = message->get_source(message); - if (!this->hasher->allocate_hash(this->hasher, - src->get_address(src), NULL)) + if (!hasher->allocate_hash(hasher, src->get_address(src), NULL)) { return FALSE; } } - return this->hasher->allocate_hash(this->hasher, - message->get_packet_data(message), hash); + return hasher->allocate_hash(hasher, message->get_packet_data(message), hash); } /** @@ -1227,15 +1212,19 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, if (is_init) { + hasher_t *hasher; u_int64_t our_spi; chunk_t hash; - if (!get_init_hash(this, message, &hash)) + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher || !get_init_hash(hasher, message, &hash)) { DBG1(DBG_MGR, "ignoring message, failed to hash message"); + DESTROY_IF(hasher); id->destroy(id); return NULL; } + hasher->destroy(hasher); /* ensure this is not a retransmit of an already handled init message */ switch (check_and_put_init_hash(this, hash, &our_spi)) @@ -1313,8 +1302,9 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, ike_id = entry->ike_sa->get_id(entry->ike_sa); entry->checked_out = TRUE; - if (message->get_first_payload_type(message) != PLV1_FRAGMENT) - { + if (message->get_first_payload_type(message) != PLV1_FRAGMENT && + message->get_first_payload_type(message) != PLV2_FRAGMENT) + { /* TODO-FRAG: this fails if there are unencrypted payloads */ entry->processing = get_message_id_or_hash(message); } if (ike_id->get_responder_spi(ike_id) == 0) @@ -2058,8 +2048,6 @@ METHOD(ike_sa_manager_t, flush, void, this->rng->destroy(this->rng); this->rng = NULL; - this->hasher->destroy(this->hasher); - this->hasher = NULL; } METHOD(ike_sa_manager_t, destroy, void, @@ -2134,18 +2122,10 @@ ike_sa_manager_t *ike_sa_manager_create() }, ); - this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (this->hasher == NULL) - { - DBG1(DBG_MGR, "manager initialization failed, no hasher supported"); - free(this); - return NULL; - } this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); if (this->rng == NULL) { DBG1(DBG_MGR, "manager initialization failed, no RNG supported"); - this->hasher->destroy(this->hasher); free(this); return NULL; } diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c index 114b8a3e4..d01a831f8 100644 --- a/src/libcharon/sa/ikev1/phase1.c +++ b/src/libcharon/sa/ikev1/phase1.c @@ -536,6 +536,7 @@ METHOD(phase1_t, select_config, peer_cfg_t*, enumerator_t *enumerator; peer_cfg_t *current; host_t *me, *other; + int unusable = 0; if (this->peer_cfg) { /* try to find an alternative config */ @@ -571,6 +572,10 @@ METHOD(phase1_t, select_config, peer_cfg_t*, this->candidates->insert_last(this->candidates, current); } } + else + { + unusable++; + } } enumerator->destroy(enumerator); @@ -580,6 +585,13 @@ METHOD(phase1_t, select_config, peer_cfg_t*, this->peer_cfg->get_name(this->peer_cfg)); return this->peer_cfg->get_ref(this->peer_cfg); } + if (unusable) + { + DBG1(DBG_IKE, "found %d matching config%s, but none allows %N " + "authentication using %s Mode", unusable, unusable > 1 ? "s" : "", + auth_method_names, method, aggressive ? "Aggressive" : "Main"); + return NULL; + } DBG1(DBG_IKE, "no peer config found"); return NULL; } diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index 97812a5c5..0f8e8bc6d 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2013 Tobias Brunner + * Copyright (C) 2007-2014 Tobias Brunner * Copyright (C) 2007-2011 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -38,8 +38,7 @@ #include #include -#include -#include +#include /** * Number of old messages hashes we keep for retransmission. @@ -50,20 +49,6 @@ */ #define MAX_OLD_HASHES 2 -/** - * Maximum packet size for fragmented packets (same as in sockets) - */ -#define MAX_PACKET 10000 - -/** - * Maximum size of fragment data when sending packets (currently the same is - * used for IPv4 and IPv6, even though the latter has a higher minimum datagram - * size). 576 (= min. IPv4) - 20 (= IP header) - 8 (= UDP header) - - * - 28 (= IKE header) - 8 (= fragment header) = 512 - * This is reduced by 4 in case of NAT-T (due to the non-ESP marker). - */ -#define MAX_FRAGMENT_SIZE 512 - /** * First sequence number of responding packets. * @@ -127,9 +112,9 @@ struct private_task_manager_t { u_int32_t hash; /** - * packet for retransmission + * packet(s) for retransmission */ - packet_t *packet; + array_t *packets; /** * Sequence number of the last sent message @@ -173,9 +158,9 @@ struct private_task_manager_t { u_int retransmitted; /** - * packet for retransmission + * packet(s) for retransmission */ - packet_t *packet; + array_t *packets; /** * type of the initiated exchange @@ -185,50 +170,9 @@ struct private_task_manager_t { } initiating; /** - * Data used to reassemble a fragmented message + * Message we are currently defragmenting, if any (only one at a time) */ - struct { - - /** - * Fragment ID (currently only one is supported at a time) - */ - u_int16_t id; - - /** - * The number of the last fragment (in case we receive the fragments out - * of order), since the first starts with 1 this defines the number of - * fragments we expect - */ - u_int8_t last; - - /** - * List of fragments (fragment_t*) - */ - linked_list_t *list; - - /** - * Length of all currently received fragments - */ - size_t len; - - /** - * Maximum length of a fragmented packet - */ - size_t max_packet; - - /** - * Maximum length of a single fragment (when sending) - */ - size_t size; - - /** - * The exchange type we use for fragments. Always the initial type even - * for fragmented quick mode or transaction messages (i.e. either - * ID_PROT or AGGRESSIVE) - */ - exchange_type_t exchange; - - } frag; + message_t *defrag; /** * List of queued tasks not yet in action @@ -277,31 +221,16 @@ struct private_task_manager_t { }; /** - * A single fragment within a fragmented message + * Reset retransmission packet list */ -typedef struct { - - /** fragment number */ - u_int8_t num; - - /** fragment data */ - chunk_t data; - -} fragment_t; - -static void fragment_destroy(fragment_t *this) +static void clear_packets(array_t *array) { - chunk_free(&this->data); - free(this); -} + packet_t *packet; -static void clear_fragments(private_task_manager_t *this, u_int16_t id) -{ - DESTROY_FUNCTION_IF(this->frag.list, (void*)fragment_destroy); - this->frag.list = NULL; - this->frag.last = 0; - this->frag.len = 0; - this->frag.id = id; + while (array_remove(array, ARRAY_TAIL, &packet)) + { + packet->destroy(packet); + } } METHOD(task_manager_t, flush_queue, void, @@ -321,8 +250,7 @@ METHOD(task_manager_t, flush_queue, void, list = this->active_tasks; /* cancel pending retransmits */ this->initiating.type = EXCHANGE_TYPE_UNDEFINED; - DESTROY_IF(this->initiating.packet); - this->initiating.packet = NULL; + clear_packets(this->initiating.packets); break; case TASK_QUEUE_PASSIVE: list = this->passive_tasks; @@ -373,110 +301,53 @@ static bool activate_task(private_task_manager_t *this, task_type_t type) } /** - * Send a single fragment with the given data + * Send packets in the given array (they get cloned) */ -static bool send_fragment(private_task_manager_t *this, bool request, - host_t *src, host_t *dst, fragment_payload_t *fragment) +static void send_packets(private_task_manager_t *this, array_t *packets) { - message_t *message; + enumerator_t *enumerator; packet_t *packet; - status_t status; - message = message_create(IKEV1_MAJOR_VERSION, IKEV1_MINOR_VERSION); - /* other implementations seem to just use 0 as message ID, so here we go */ - message->set_message_id(message, 0); - message->set_request(message, request); - message->set_source(message, src->clone(src)); - message->set_destination(message, dst->clone(dst)); - message->set_exchange_type(message, this->frag.exchange); - message->add_payload(message, (payload_t*)fragment); - - status = this->ike_sa->generate_message(this->ike_sa, message, &packet); - if (status != SUCCESS) + enumerator = array_create_enumerator(packets); + while (enumerator->enumerate(enumerator, &packet)) { - DBG1(DBG_IKE, "failed to generate IKE fragment"); - message->destroy(message); - return FALSE; + charon->sender->send(charon->sender, packet->clone(packet)); } - charon->sender->send(charon->sender, packet); - message->destroy(message); - return TRUE; + enumerator->destroy(enumerator); } /** - * Send a packet, if supported and required do so in fragments + * Generates the given message and stores packet(s) in the given array */ -static bool send_packet(private_task_manager_t *this, bool request, - packet_t *packet) +static bool generate_message(private_task_manager_t *this, message_t *message, + array_t **packets) { - bool use_frags = FALSE; - ike_cfg_t *ike_cfg; - chunk_t data; + enumerator_t *fragments; + packet_t *fragment; - ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); - if (ike_cfg) + if (this->ike_sa->generate_message_fragmented(this->ike_sa, message, + &fragments) != SUCCESS) { - switch (ike_cfg->fragmentation(ike_cfg)) - { - case FRAGMENTATION_FORCE: - use_frags = TRUE; - break; - case FRAGMENTATION_YES: - use_frags = this->ike_sa->supports_extension(this->ike_sa, - EXT_IKE_FRAGMENTATION); - break; - default: - break; - } + return FALSE; } - data = packet->get_data(packet); - if (data.len > this->frag.size && use_frags) + while (fragments->enumerate(fragments, &fragment)) { - fragment_payload_t *fragment; - u_int8_t num, count; - size_t len, frag_size; - host_t *src, *dst; - - src = packet->get_source(packet); - dst = packet->get_destination(packet); - - frag_size = this->frag.size; - if (dst->get_port(dst) != IKEV2_UDP_PORT && - src->get_port(src) != IKEV2_UDP_PORT) - { /* reduce size due to non-ESP marker */ - frag_size -= 4; - } - count = data.len / frag_size + (data.len % frag_size ? 1 : 0); - - DBG1(DBG_IKE, "sending IKE message with length of %zu bytes in " - "%hhu fragments", data.len, count); - for (num = 1; num <= count; num++) - { - len = min(data.len, frag_size); - fragment = fragment_payload_create_from_data(num, num == count, - chunk_create(data.ptr, len)); - if (!send_fragment(this, request, src, dst, fragment)) - { - packet->destroy(packet); - return FALSE; - } - data = chunk_skip(data, len); - } - packet->destroy(packet); - return TRUE; + array_insert_create(packets, ARRAY_TAIL, fragment); } - charon->sender->send(charon->sender, packet); + fragments->destroy(fragments); return TRUE; } /** - * Retransmit a packet, either as initiator or as responder + * Retransmit a packet (or its fragments) */ -static status_t retransmit_packet(private_task_manager_t *this, bool request, - u_int32_t seqnr, u_int mid, u_int retransmitted, packet_t *packet) +static status_t retransmit_packet(private_task_manager_t *this, u_int32_t seqnr, + u_int mid, u_int retransmitted, array_t *packets) { + packet_t *packet; u_int32_t t; + array_get(packets, 0, &packet); if (retransmitted > this->retransmit_tries) { DBG1(DBG_IKE, "giving up after %u retransmits", retransmitted - 1); @@ -492,10 +363,7 @@ static status_t retransmit_packet(private_task_manager_t *this, bool request, mid, seqnr < RESPONDING_SEQ ? seqnr : seqnr - RESPONDING_SEQ); charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND, packet); } - if (!send_packet(this, request, packet->clone(packet))) - { - return DESTROY_ME; - } + send_packets(this, packets); lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*) retransmit_job_create(seqnr, this->ike_sa->get_id(this->ike_sa)), t); return NEED_MORE; @@ -506,20 +374,22 @@ METHOD(task_manager_t, retransmit, status_t, { status_t status = SUCCESS; - if (seqnr == this->initiating.seqnr && this->initiating.packet) + if (seqnr == this->initiating.seqnr && + array_count(this->initiating.packets)) { - status = retransmit_packet(this, TRUE, seqnr, this->initiating.mid, - this->initiating.retransmitted, this->initiating.packet); + status = retransmit_packet(this, seqnr, this->initiating.mid, + this->initiating.retransmitted, this->initiating.packets); if (status == NEED_MORE) { this->initiating.retransmitted++; status = SUCCESS; } } - if (seqnr == this->responding.seqnr && this->responding.packet) + if (seqnr == this->responding.seqnr && + array_count(this->responding.packets)) { - status = retransmit_packet(this, FALSE, seqnr, this->responding.mid, - this->responding.retransmitted, this->responding.packet); + status = retransmit_packet(this, seqnr, this->responding.mid, + this->responding.retransmitted, this->responding.packets); if (status == NEED_MORE) { this->responding.retransmitted++; @@ -586,7 +456,6 @@ METHOD(task_manager_t, initiate, status_t, task_t *task; message_t *message; host_t *me, *other; - status_t status; exchange_type_t exchange = EXCHANGE_TYPE_UNDEFINED; bool new_mid = FALSE, expect_response = FALSE, cancelled = FALSE, keep = FALSE; @@ -790,10 +659,8 @@ METHOD(task_manager_t, initiate, status_t, return initiate(this); } - DESTROY_IF(this->initiating.packet); - status = this->ike_sa->generate_message(this->ike_sa, message, - &this->initiating.packet); - if (status != SUCCESS) + clear_packets(this->initiating.packets); + if (!generate_message(this, message, &this->initiating.packets)) { /* message generation failed. There is nothing more to do than to * close the SA */ @@ -811,13 +678,12 @@ METHOD(task_manager_t, initiate, status_t, } if (keep) { /* keep the packet for retransmission, the responder might request it */ - send_packet(this, TRUE, - this->initiating.packet->clone(this->initiating.packet)); + send_packets(this, this->initiating.packets); } else { - send_packet(this, TRUE, this->initiating.packet); - this->initiating.packet = NULL; + send_packets(this, this->initiating.packets); + clear_packets(this->initiating.packets); } message->destroy(message); @@ -848,7 +714,6 @@ static status_t build_response(private_task_manager_t *this, message_t *request) message_t *message; host_t *me, *other; bool delete = FALSE, cancelled = FALSE, expect_request = FALSE; - status_t status; me = request->get_destination(request); other = request->get_source(request); @@ -900,28 +765,25 @@ static status_t build_response(private_task_manager_t *this, message_t *request) } enumerator->destroy(enumerator); - DESTROY_IF(this->responding.packet); - this->responding.packet = NULL; + clear_packets(this->responding.packets); if (cancelled) { message->destroy(message); return initiate(this); } - status = this->ike_sa->generate_message(this->ike_sa, message, - &this->responding.packet); - message->destroy(message); - if (status != SUCCESS) + if (!generate_message(this, message, &this->responding.packets)) { + message->destroy(message); charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); return DESTROY_ME; } + message->destroy(message); if (expect_request && !delete) { return retransmit(this, this->responding.seqnr); } - send_packet(this, FALSE, - this->responding.packet->clone(this->responding.packet)); + send_packets(this, this->responding.packets); if (delete) { return DESTROY_ME; @@ -937,7 +799,7 @@ static void send_notify(private_task_manager_t *this, message_t *request, notify_type_t type) { message_t *response; - packet_t *packet; + array_t *packets = NULL; host_t *me, *other; u_int32_t mid; @@ -973,11 +835,12 @@ static void send_notify(private_task_manager_t *this, message_t *request, } response->set_source(response, me->clone(me)); response->set_destination(response, other->clone(other)); - if (this->ike_sa->generate_message(this->ike_sa, response, - &packet) == SUCCESS) + if (generate_message(this, response, &packets)) { - send_packet(this, TRUE, packet); + send_packets(this, packets); } + clear_packets(packets); + array_destroy(packets); response->destroy(response); } @@ -1075,7 +938,6 @@ static status_t process_request(private_task_manager_t *this, this->passive_tasks->insert_last(this->passive_tasks, task); task = (task_t *)isakmp_natd_create(this->ike_sa, FALSE); this->passive_tasks->insert_last(this->passive_tasks, task); - this->frag.exchange = AGGRESSIVE; break; case QUICK_MODE: if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED) @@ -1164,8 +1026,7 @@ static status_t process_request(private_task_manager_t *this, else { /* We don't send a response, so don't retransmit one if we get * the same message again. */ - DESTROY_IF(this->responding.packet); - this->responding.packet = NULL; + clear_packets(this->responding.packets); } if (this->passive_tasks->get_count(this->passive_tasks) == 0 && this->queued_tasks->get_count(this->queued_tasks) > 0) @@ -1237,8 +1098,7 @@ static status_t process_response(private_task_manager_t *this, enumerator->destroy(enumerator); this->initiating.type = EXCHANGE_TYPE_UNDEFINED; - DESTROY_IF(this->initiating.packet); - this->initiating.packet = NULL; + clear_packets(this->initiating.packets); if (this->queued && this->active_tasks->get_count(this->active_tasks) == 0) { @@ -1258,107 +1118,23 @@ static status_t process_response(private_task_manager_t *this, static status_t handle_fragment(private_task_manager_t *this, message_t *msg) { - fragment_payload_t *payload; - enumerator_t *enumerator; - fragment_t *fragment; - status_t status = SUCCESS; - chunk_t data; - u_int8_t num; - - payload = (fragment_payload_t*)msg->get_payload(msg, PLV1_FRAGMENT); - if (!payload) - { - return FAILED; - } - - if (!this->frag.list || this->frag.id != payload->get_id(payload)) - { - clear_fragments(this, payload->get_id(payload)); - this->frag.list = linked_list_create(); - } - - num = payload->get_number(payload); - if (!this->frag.last && payload->is_last(payload)) - { - this->frag.last = num; - } + status_t status; - enumerator = this->frag.list->create_enumerator(this->frag.list); - while (enumerator->enumerate(enumerator, &fragment)) + if (!this->defrag) { - if (fragment->num == num) - { /* ignore a duplicate fragment */ - DBG1(DBG_IKE, "received duplicate fragment #%hhu", num); - enumerator->destroy(enumerator); - return NEED_MORE; - } - if (fragment->num > num) + this->defrag = message_create_defrag(msg); + if (!this->defrag) { - break; + return FAILED; } } - - data = payload->get_data(payload); - this->frag.len += data.len; - if (this->frag.len > this->frag.max_packet) - { - DBG1(DBG_IKE, "fragmented IKE message is too large"); - enumerator->destroy(enumerator); - clear_fragments(this, 0); - return FAILED; - } - - INIT(fragment, - .num = num, - .data = chunk_clone(data), - ); - - this->frag.list->insert_before(this->frag.list, enumerator, fragment); - enumerator->destroy(enumerator); - - if (this->frag.list->get_count(this->frag.list) == this->frag.last) + status = this->defrag->add_fragment(this->defrag, msg); + if (status == SUCCESS) { - message_t *message; - packet_t *pkt; - host_t *src, *dst; - bio_writer_t *writer; - - writer = bio_writer_create(this->frag.len); - DBG1(DBG_IKE, "received fragment #%hhu, reassembling fragmented IKE " - "message", num); - enumerator = this->frag.list->create_enumerator(this->frag.list); - while (enumerator->enumerate(enumerator, &fragment)) - { - writer->write_data(writer, fragment->data); - } - enumerator->destroy(enumerator); - - src = msg->get_source(msg); - dst = msg->get_destination(msg); - pkt = packet_create_from_data(src->clone(src), dst->clone(dst), - writer->extract_buf(writer)); - writer->destroy(writer); - - message = message_create_from_packet(pkt); - if (message->parse_header(message) != SUCCESS) - { - DBG1(DBG_IKE, "failed to parse header of reassembled IKE message"); - message->destroy(message); - status = FAILED; - } - else - { - lib->processor->queue_job(lib->processor, - (job_t*)process_message_job_create(message)); - status = NEED_MORE; - - } - clear_fragments(this, 0); - } - else - { /* there are some fragments missing */ - DBG1(DBG_IKE, "received fragment #%hhu, waiting for complete IKE " - "message", num); + lib->processor->queue_job(lib->processor, + (job_t*)process_message_job_create(this->defrag)); + this->defrag = NULL; + /* do not process the last fragment */ status = NEED_MORE; } return status; @@ -1435,15 +1211,14 @@ METHOD(task_manager_t, process_message, status_t, { if (this->initiating.old_hashes[i] == hash) { - if (this->initiating.packet && + if (array_count(this->initiating.packets) && i == (this->initiating.old_hash_pos % MAX_OLD_HASHES) && (msg->get_exchange_type(msg) == QUICK_MODE || msg->get_exchange_type(msg) == AGGRESSIVE)) { DBG1(DBG_IKE, "received retransmit of response with ID %u, " "resending last request", mid); - send_packet(this, TRUE, - this->initiating.packet->clone(this->initiating.packet)); + send_packets(this, this->initiating.packets); return SUCCESS; } DBG1(DBG_IKE, "received retransmit of response with ID %u, " @@ -1484,20 +1259,18 @@ METHOD(task_manager_t, process_message, status_t, { if (hash == this->responding.hash) { - if (this->responding.packet) + if (array_count(this->responding.packets)) { DBG1(DBG_IKE, "received retransmit of request with ID %u, " "retransmitting response", mid); - send_packet(this, FALSE, - this->responding.packet->clone(this->responding.packet)); + send_packets(this, this->responding.packets); } - else if (this->initiating.packet && + else if (array_count(this->initiating.packets) && this->initiating.type == INFORMATIONAL_V1) { DBG1(DBG_IKE, "received retransmit of DPD request, " "retransmitting response"); - send_packet(this, TRUE, - this->initiating.packet->clone(this->initiating.packet)); + send_packets(this, this->initiating.packets); } else { @@ -1593,13 +1366,6 @@ METHOD(task_manager_t, process_message, status_t, return SUCCESS; } -METHOD(task_manager_t, queue_task, void, - private_task_manager_t *this, task_t *task) -{ - DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task)); - this->queued_tasks->insert_last(this->queued_tasks, task); -} - /** * Check if a given task has been queued already */ @@ -1622,6 +1388,28 @@ static bool has_queued(private_task_manager_t *this, task_type_t type) return found; } +METHOD(task_manager_t, queue_task, void, + private_task_manager_t *this, task_t *task) +{ + task_type_t type = task->get_type(task); + + switch (type) + { + case TASK_MODE_CONFIG: + case TASK_XAUTH: + if (has_queued(this, type)) + { + task->destroy(task); + return; + } + break; + default: + break; + } + DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task)); + this->queued_tasks->insert_last(this->queued_tasks, task); +} + METHOD(task_manager_t, queue_ike, void, private_task_manager_t *this) { @@ -1642,7 +1430,6 @@ METHOD(task_manager_t, queue_ike, void, { queue_task(this, (task_t*)aggressive_mode_create(this->ike_sa, TRUE)); } - this->frag.exchange = AGGRESSIVE; } else { @@ -1969,17 +1756,16 @@ METHOD(task_manager_t, reset, void, task_t *task; /* reset message counters and retransmit packets */ - DESTROY_IF(this->responding.packet); - DESTROY_IF(this->initiating.packet); - this->responding.packet = NULL; + clear_packets(this->responding.packets); + clear_packets(this->initiating.packets); this->responding.seqnr = RESPONDING_SEQ; this->responding.retransmitted = 0; - this->initiating.packet = NULL; this->initiating.mid = 0; this->initiating.seqnr = 0; this->initiating.retransmitted = 0; this->initiating.type = EXCHANGE_TYPE_UNDEFINED; - clear_fragments(this, 0); + DESTROY_IF(this->defrag); + this->defrag = NULL; if (initiate != UINT_MAX) { this->dpd_send = initiate; @@ -2030,11 +1816,13 @@ METHOD(task_manager_t, destroy, void, this->active_tasks->destroy(this->active_tasks); this->queued_tasks->destroy(this->queued_tasks); this->passive_tasks->destroy(this->passive_tasks); - clear_fragments(this, 0); + DESTROY_IF(this->defrag); DESTROY_IF(this->queued); - DESTROY_IF(this->responding.packet); - DESTROY_IF(this->initiating.packet); + clear_packets(this->responding.packets); + array_destroy(this->responding.packets); + clear_packets(this->initiating.packets); + array_destroy(this->initiating.packets); DESTROY_IF(this->rng); free(this); } @@ -2079,13 +1867,6 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa) .responding = { .seqnr = RESPONDING_SEQ, }, - .frag = { - .exchange = ID_PROT, - .max_packet = lib->settings->get_int(lib->settings, - "%s.max_packet", MAX_PACKET, lib->ns), - .size = lib->settings->get_int(lib->settings, - "%s.fragment_size", MAX_FRAGMENT_SIZE, lib->ns), - }, .ike_sa = ike_sa, .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK), .queued_tasks = linked_list_create(), diff --git a/src/libcharon/sa/ikev1/tasks/aggressive_mode.c b/src/libcharon/sa/ikev1/tasks/aggressive_mode.c index 7009ae95d..710bf1cd2 100644 --- a/src/libcharon/sa/ikev1/tasks/aggressive_mode.c +++ b/src/libcharon/sa/ikev1/tasks/aggressive_mode.c @@ -475,6 +475,9 @@ METHOD(task_t, process_r, status_t, } case AM_AUTH: { + adopt_children_job_t *job = NULL; + xauth_t *xauth = NULL; + while (TRUE) { if (this->ph1->verify_auth(this->ph1, this->method, message, @@ -504,8 +507,8 @@ METHOD(task_t, process_r, status_t, case AUTH_XAUTH_INIT_PSK: case AUTH_XAUTH_INIT_RSA: case AUTH_HYBRID_INIT_RSA: - this->ike_sa->queue_task(this->ike_sa, - (task_t*)xauth_create(this->ike_sa, TRUE)); + xauth = xauth_create(this->ike_sa, TRUE); + this->ike_sa->queue_task(this->ike_sa, (task_t*)xauth); break; case AUTH_XAUTH_RESP_PSK: case AUTH_XAUTH_RESP_RSA: @@ -524,9 +527,8 @@ METHOD(task_t, process_r, status_t, { return send_delete(this); } - lib->processor->queue_job(lib->processor, (job_t*) - adopt_children_job_create( - this->ike_sa->get_id(this->ike_sa))); + job = adopt_children_job_create( + this->ike_sa->get_id(this->ike_sa)); break; } /* check for and prepare mode config push/pull */ @@ -542,10 +544,26 @@ METHOD(task_t, process_r, status_t, { if (!this->peer_cfg->use_pull_mode(this->peer_cfg)) { - this->ike_sa->queue_task(this->ike_sa, - (task_t*)mode_config_create(this->ike_sa, TRUE, FALSE)); + if (job) + { + job->queue_task(job, (task_t*) + mode_config_create(this->ike_sa, TRUE, FALSE)); + } + else if (xauth) + { + xauth->queue_mode_config_push(xauth); + } + else + { + this->ike_sa->queue_task(this->ike_sa, (task_t*) + mode_config_create(this->ike_sa, TRUE, FALSE)); + } } } + if (job) + { + lib->processor->queue_job(lib->processor, (job_t*)job); + } return SUCCESS; } default: diff --git a/src/libcharon/sa/ikev1/tasks/informational.c b/src/libcharon/sa/ikev1/tasks/informational.c index b742dbef9..2798978b2 100644 --- a/src/libcharon/sa/ikev1/tasks/informational.c +++ b/src/libcharon/sa/ikev1/tasks/informational.c @@ -112,16 +112,16 @@ METHOD(task_t, process_r, status_t, IKEV2_UDP_PORT); if (redirect) { /* treat the redirect as reauthentication */ - DBG1(DBG_IKE, "received %N notify. redirected to %H", + DBG1(DBG_IKE, "received %N notify, redirected to %H", notify_type_names, type, redirect); /* Cisco boxes reject the first message from 4500 */ me = this->ike_sa->get_my_host(this->ike_sa); me->set_port(me, charon->socket->get_port( charon->socket, FALSE)); this->ike_sa->set_other_host(this->ike_sa, redirect); - this->ike_sa->reauth(this->ike_sa); + status = this->ike_sa->reauth(this->ike_sa); enumerator->destroy(enumerator); - return DESTROY_ME; + return status; } else { diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c b/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c index 426c4bd69..0162fd84e 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_vendor.c @@ -15,7 +15,7 @@ */ /* - * Copyright (C) 2012 Volker RĂ¼melin + * Copyright (C) 2012-2014 Volker RĂ¼melin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -106,10 +106,15 @@ static struct { "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00"}, /* Proprietary IKE fragmentation extension. Capabilities are handled - * specially on receipt of this VID. */ + * specially on receipt of this VID. Windows peers send this VID + * without capabilities, but accept it with and without capabilities. */ { "FRAGMENTATION", EXT_IKE_FRAGMENTATION, FALSE, 20, "\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\x00\xd6\xc2\xd3\x80\x00\x00\x00"}, + /* Windows peers send this VID and a version number */ + { "MS NT5 ISAKMPOAKLEY", EXT_MS_WINDOWS, FALSE, 20, + "\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00\x00\x00"}, + }, vendor_natt_ids[] = { /* NAT-Traversal VIDs ordered by preference */ @@ -167,15 +172,27 @@ static struct { */ static const u_int32_t fragmentation_ike = 0x80000000; -/** - * Check if the given vendor ID indicate support for fragmentation - */ -static bool fragmentation_supported(chunk_t data, int i) +static bool is_known_vid(chunk_t data, int i) { - if (vendor_ids[i].extension == EXT_IKE_FRAGMENTATION && - data.len == 20 && memeq(data.ptr, vendor_ids[i].id, 16)) + switch (vendor_ids[i].extension) { - return untoh32(&data.ptr[16]) & fragmentation_ike; + case EXT_IKE_FRAGMENTATION: + if (data.len >= 16 && memeq(data.ptr, vendor_ids[i].id, 16)) + { + switch (data.len) + { + case 16: + return TRUE; + case 20: + return untoh32(&data.ptr[16]) & fragmentation_ike; + } + } + break; + case EXT_MS_WINDOWS: + return data.len == 20 && memeq(data.ptr, vendor_ids[i].id, 16); + default: + return chunk_equals(data, chunk_create(vendor_ids[i].id, + vendor_ids[i].len)); } return FALSE; } @@ -251,9 +268,7 @@ static void process(private_isakmp_vendor_t *this, message_t *message) for (i = 0; i < countof(vendor_ids); i++) { - if (chunk_equals(data, chunk_create(vendor_ids[i].id, - vendor_ids[i].len)) || - fragmentation_supported(data, i)) + if (is_known_vid(data, i)) { DBG1(DBG_IKE, "received %s vendor ID", vendor_ids[i].desc); if (vendor_ids[i].extension) diff --git a/src/libcharon/sa/ikev1/tasks/main_mode.c b/src/libcharon/sa/ikev1/tasks/main_mode.c index 8a5d9ae16..2fb4c6935 100644 --- a/src/libcharon/sa/ikev1/tasks/main_mode.c +++ b/src/libcharon/sa/ikev1/tasks/main_mode.c @@ -479,6 +479,8 @@ METHOD(task_t, build_r, status_t, { id_payload_t *id_payload; identification_t *id; + adopt_children_job_t *job = NULL; + xauth_t *xauth = NULL; id = this->ph1->get_id(this->ph1, this->peer_cfg, TRUE); if (!id) @@ -502,8 +504,8 @@ METHOD(task_t, build_r, status_t, case AUTH_XAUTH_INIT_PSK: case AUTH_XAUTH_INIT_RSA: case AUTH_HYBRID_INIT_RSA: - this->ike_sa->queue_task(this->ike_sa, - (task_t*)xauth_create(this->ike_sa, TRUE)); + xauth = xauth_create(this->ike_sa, TRUE); + this->ike_sa->queue_task(this->ike_sa, (task_t*)xauth); break; case AUTH_XAUTH_RESP_PSK: case AUTH_XAUTH_RESP_RSA: @@ -522,9 +524,8 @@ METHOD(task_t, build_r, status_t, { return send_notify(this, AUTHENTICATION_FAILED); } - lib->processor->queue_job(lib->processor, (job_t*) - adopt_children_job_create( - this->ike_sa->get_id(this->ike_sa))); + job = adopt_children_job_create( + this->ike_sa->get_id(this->ike_sa)); break; } if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg)) @@ -539,10 +540,26 @@ METHOD(task_t, build_r, status_t, { if (!this->peer_cfg->use_pull_mode(this->peer_cfg)) { - this->ike_sa->queue_task(this->ike_sa, - (task_t*)mode_config_create(this->ike_sa, TRUE, FALSE)); + if (job) + { + job->queue_task(job, (task_t*) + mode_config_create(this->ike_sa, TRUE, FALSE)); + } + else if (xauth) + { + xauth->queue_mode_config_push(xauth); + } + else + { + this->ike_sa->queue_task(this->ike_sa, (task_t*) + mode_config_create(this->ike_sa, TRUE, FALSE)); + } } } + if (job) + { + lib->processor->queue_job(lib->processor, (job_t*)job); + } return SUCCESS; } default: diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index e6273682d..1133aab65 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -1030,7 +1030,8 @@ METHOD(task_t, process_r, status_t, } tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); - if (!this->config || !this->tsi || !this->tsr) + if (!this->config || !this->tsi || !this->tsr || + this->mode != this->config->get_mode(this->config)) { DBG1(DBG_IKE, "no matching CHILD_SA config found"); return send_notify(this, INVALID_ID_INFORMATION); @@ -1117,11 +1118,22 @@ METHOD(task_t, process_r, status_t, } case QM_NEGOTIATED: { - if (message->get_exchange_type(message) == INFORMATIONAL_V1 || - has_notify_errors(this, message)) + if (has_notify_errors(this, message)) { return SUCCESS; } + if (message->get_exchange_type(message) == INFORMATIONAL_V1) + { + if (message->get_payload(message, PLV1_DELETE)) + { + /* If the DELETE for a Quick Mode follows immediately + * after rekeying, we might receive it before the + * third completing Quick Mode message. Ignore it, as + * it gets handled by a separately queued delete task. */ + return NEED_MORE; + } + return SUCCESS; + } if (!install(this)) { ike_sa_t *ike_sa = this->ike_sa; @@ -1198,6 +1210,14 @@ METHOD(task_t, build_r, status_t, this->state = QM_NEGOTIATED; return NEED_MORE; } + case QM_NEGOTIATED: + if (message->get_exchange_type(message) == INFORMATIONAL_V1) + { + /* skip INFORMATIONAL response if we received a INFORMATIONAL + * delete, see process_r() */ + return ALREADY_DONE; + } + /* fall */ default: return FAILED; } diff --git a/src/libcharon/sa/ikev1/tasks/xauth.c b/src/libcharon/sa/ikev1/tasks/xauth.c index bdc5d67f7..a770e90ff 100644 --- a/src/libcharon/sa/ikev1/tasks/xauth.c +++ b/src/libcharon/sa/ikev1/tasks/xauth.c @@ -19,6 +19,7 @@ #include #include #include +#include typedef struct private_xauth_t private_xauth_t; @@ -74,6 +75,11 @@ struct private_xauth_t { * status of Xauth exchange */ xauth_status_t status; + + /** + * Queue a Mode Config Push mode after completing XAuth? + */ + bool mode_config_push; }; /** @@ -290,6 +296,7 @@ METHOD(task_t, process_i_status, status_t, private_xauth_t *this, message_t *message) { cp_payload_t *cp; + adopt_children_job_t *job; cp = (cp_payload_t*)message->get_payload(message, PLV1_CONFIGURATION); if (!cp || cp->get_type(cp) != CFG_ACK) @@ -307,8 +314,13 @@ METHOD(task_t, process_i_status, status_t, return FAILED; } this->ike_sa->set_condition(this->ike_sa, COND_XAUTH_AUTHENTICATED, TRUE); - lib->processor->queue_job(lib->processor, (job_t*) - adopt_children_job_create(this->ike_sa->get_id(this->ike_sa))); + job = adopt_children_job_create(this->ike_sa->get_id(this->ike_sa)); + if (this->mode_config_push) + { + job->queue_task(job, + (task_t*)mode_config_create(this->ike_sa, TRUE, FALSE)); + } + lib->processor->queue_job(lib->processor, (job_t*)job); return SUCCESS; } @@ -511,6 +523,12 @@ METHOD(task_t, migrate, void, } } +METHOD(xauth_t, queue_mode_config_push, void, + private_xauth_t *this) +{ + this->mode_config_push = TRUE; +} + METHOD(task_t, destroy, void, private_xauth_t *this) { @@ -533,6 +551,7 @@ xauth_t *xauth_create(ike_sa_t *ike_sa, bool initiator) .migrate = _migrate, .destroy = _destroy, }, + .queue_mode_config_push = _queue_mode_config_push, }, .initiator = initiator, .ike_sa = ike_sa, diff --git a/src/libcharon/sa/ikev1/tasks/xauth.h b/src/libcharon/sa/ikev1/tasks/xauth.h index 303eb31ce..ffaf32a32 100644 --- a/src/libcharon/sa/ikev1/tasks/xauth.h +++ b/src/libcharon/sa/ikev1/tasks/xauth.h @@ -36,6 +36,11 @@ struct xauth_t { * Implements the task_t interface */ task_t task; + + /** + * Queue a Mode Config in Push mode after completing XAuth. + */ + void (*queue_mode_config_push)(xauth_t *this); }; /** diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index ada798bdc..eb7df3516 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2011 Tobias Brunner + * Copyright (C) 2007-2014 Tobias Brunner * Copyright (C) 2007-2010 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -90,9 +90,14 @@ struct private_task_manager_t { u_int32_t mid; /** - * packet for retransmission + * packet(s) for retransmission */ - packet_t *packet; + array_t *packets; + + /** + * Helper to defragment the request + */ + message_t *defrag; } responding; @@ -111,15 +116,25 @@ struct private_task_manager_t { u_int retransmitted; /** - * packet for retransmission + * packet(s) for retransmission */ - packet_t *packet; + array_t *packets; /** * type of the initated exchange */ exchange_type_t type; + /** + * TRUE if exchange was deferred because no path was available + */ + bool deferred; + + /** + * Helper to defragment the response + */ + message_t *defrag; + } initiating; /** @@ -158,6 +173,19 @@ struct private_task_manager_t { double retransmit_base; }; +/** + * Reset retransmission packet list + */ +static void clear_packets(array_t *array) +{ + packet_t *packet; + + while (array_remove(array, ARRAY_TAIL, &packet)) + { + packet->destroy(packet); + } +} + METHOD(task_manager_t, flush_queue, void, private_task_manager_t *this, task_queue_t queue) { @@ -217,10 +245,60 @@ static bool activate_task(private_task_manager_t *this, task_type_t type) return found; } +/** + * Send packets in the given array (they get cloned). Optionally, the + * source and destination addresses are changed before sending it. + */ +static void send_packets(private_task_manager_t *this, array_t *packets, + host_t *src, host_t *dst) +{ + packet_t *packet, *clone; + int i; + + for (i = 0; i < array_count(packets); i++) + { + array_get(packets, i, &packet); + clone = packet->clone(packet); + if (src) + { + clone->set_source(clone, src->clone(src)); + } + if (dst) + { + clone->set_destination(clone, dst->clone(dst)); + } + charon->sender->send(charon->sender, clone); + } +} + +/** + * Generates the given message and stores packet(s) in the given array + */ +static bool generate_message(private_task_manager_t *this, message_t *message, + array_t **packets) +{ + enumerator_t *fragments; + packet_t *fragment; + + if (this->ike_sa->generate_message_fragmented(this->ike_sa, message, + &fragments) != SUCCESS) + { + return FALSE; + } + while (fragments->enumerate(fragments, &fragment)) + { + array_insert_create(packets, ARRAY_TAIL, fragment); + } + fragments->destroy(fragments); + array_compress(*packets); + return TRUE; +} + METHOD(task_manager_t, retransmit, status_t, private_task_manager_t *this, u_int32_t message_id) { - if (this->initiating.packet && message_id == this->initiating.mid) + if (message_id == this->initiating.mid && + array_count(this->initiating.packets)) { u_int32_t timeout; job_t *job; @@ -229,23 +307,24 @@ METHOD(task_manager_t, retransmit, status_t, task_t *task; ike_mobike_t *mobike = NULL; + array_get(this->initiating.packets, 0, &packet); + /* check if we are retransmitting a MOBIKE routability check */ - enumerator = array_create_enumerator(this->active_tasks); - while (enumerator->enumerate(enumerator, (void*)&task)) + if (this->initiating.type == INFORMATIONAL) { - if (task->get_type(task) == TASK_IKE_MOBIKE) + enumerator = array_create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, (void*)&task)) { - mobike = (ike_mobike_t*)task; - if (!mobike->is_probing(mobike)) + if (task->get_type(task) == TASK_IKE_MOBIKE) { - mobike = NULL; + mobike = (ike_mobike_t*)task; + break; } - break; } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); - if (mobike == NULL) + if (!mobike || !mobike->is_probing(mobike)) { if (this->initiating.retransmitted <= this->retransmit_tries) { @@ -257,7 +336,7 @@ METHOD(task_manager_t, retransmit, status_t, DBG1(DBG_IKE, "giving up after %d retransmits", this->initiating.retransmitted - 1); charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_TIMEOUT, - this->initiating.packet); + packet); return DESTROY_ME; } @@ -265,11 +344,29 @@ METHOD(task_manager_t, retransmit, status_t, { DBG1(DBG_IKE, "retransmit %d of request with message ID %d", this->initiating.retransmitted, message_id); - charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND, - this->initiating.packet); + charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND, packet); + } + if (!mobike) + { + send_packets(this, this->initiating.packets, + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa)); + } + else + { + if (!mobike->transmit(mobike, packet)) + { + DBG1(DBG_IKE, "no route found to reach peer, MOBIKE update " + "deferred"); + this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE); + this->initiating.deferred = TRUE; + return SUCCESS; + } + else if (mobike->is_probing(mobike)) + { + timeout = ROUTEABILITY_CHECK_INTERVAL; + } } - packet = this->initiating.packet->clone(this->initiating.packet); - charon->sender->send(charon->sender, packet); } else { /* for routeability checks, we use a more aggressive behavior */ @@ -289,7 +386,16 @@ METHOD(task_manager_t, retransmit, status_t, DBG1(DBG_IKE, "path probing attempt %d", this->initiating.retransmitted); } - mobike->transmit(mobike, this->initiating.packet); + /* TODO-FRAG: presumably these small packets are not fragmented, + * we should maybe ensure this is the case when generating them */ + if (!mobike->transmit(mobike, packet)) + { + DBG1(DBG_IKE, "no route found to reach peer, path probing " + "deferred"); + this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE); + this->initiating.deferred = TRUE; + return SUCCESS; + } } this->initiating.retransmitted++; @@ -307,7 +413,6 @@ METHOD(task_manager_t, initiate, status_t, task_t *task; message_t *message; host_t *me, *other; - status_t status; exchange_type_t exchange = 0; if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED) @@ -315,6 +420,12 @@ METHOD(task_manager_t, initiate, status_t, DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress", exchange_type_names, this->initiating.type); /* do not initiate if we already have a message in the air */ + if (this->initiating.deferred) + { /* re-initiate deferred exchange */ + this->initiating.deferred = FALSE; + this->initiating.retransmitted = 0; + return retransmit(this, this->initiating.mid); + } return SUCCESS; } @@ -347,39 +458,39 @@ METHOD(task_manager_t, initiate, status_t, } break; case IKE_ESTABLISHED: - if (activate_task(this, TASK_CHILD_CREATE)) + if (activate_task(this, TASK_IKE_MOBIKE)) { - exchange = CREATE_CHILD_SA; + exchange = INFORMATIONAL; break; } - if (activate_task(this, TASK_CHILD_DELETE)) + if (activate_task(this, TASK_IKE_DELETE)) { exchange = INFORMATIONAL; break; } - if (activate_task(this, TASK_CHILD_REKEY)) + if (activate_task(this, TASK_CHILD_DELETE)) { - exchange = CREATE_CHILD_SA; + exchange = INFORMATIONAL; break; } - if (activate_task(this, TASK_IKE_DELETE)) + if (activate_task(this, TASK_IKE_REAUTH)) { exchange = INFORMATIONAL; break; } - if (activate_task(this, TASK_IKE_REKEY)) + if (activate_task(this, TASK_CHILD_CREATE)) { exchange = CREATE_CHILD_SA; break; } - if (activate_task(this, TASK_IKE_REAUTH)) + if (activate_task(this, TASK_CHILD_REKEY)) { - exchange = INFORMATIONAL; + exchange = CREATE_CHILD_SA; break; } - if (activate_task(this, TASK_IKE_MOBIKE)) + if (activate_task(this, TASK_IKE_REKEY)) { - exchange = INFORMATIONAL; + exchange = CREATE_CHILD_SA; break; } if (activate_task(this, TASK_IKE_DPD)) @@ -458,6 +569,7 @@ METHOD(task_manager_t, initiate, status_t, message->set_exchange_type(message, exchange); this->initiating.type = exchange; this->initiating.retransmitted = 0; + this->initiating.deferred = FALSE; enumerator = array_create_enumerator(this->active_tasks); while (enumerator->enumerate(enumerator, &task)) @@ -493,9 +605,7 @@ METHOD(task_manager_t, initiate, status_t, /* update exchange type if a task changed it */ this->initiating.type = message->get_exchange_type(message); - status = this->ike_sa->generate_message(this->ike_sa, message, - &this->initiating.packet); - if (status != SUCCESS) + if (!generate_message(this, message, &this->initiating.packets)) { /* message generation failed. There is nothing more to do than to * close the SA */ @@ -567,8 +677,7 @@ static status_t process_response(private_task_manager_t *this, this->initiating.mid++; this->initiating.type = EXCHANGE_TYPE_UNDEFINED; - this->initiating.packet->destroy(this->initiating.packet); - this->initiating.packet = NULL; + clear_packets(this->initiating.packets); array_compress(this->active_tasks); @@ -636,8 +745,8 @@ static status_t build_response(private_task_manager_t *this, message_t *request) host_t *me, *other; bool delete = FALSE, hook = FALSE; ike_sa_id_t *id = NULL; - u_int64_t responder_spi; - status_t status; + u_int64_t responder_spi = 0; + bool result; me = request->get_destination(request); other = request->get_source(request); @@ -699,23 +808,20 @@ static status_t build_response(private_task_manager_t *this, message_t *request) } /* message complete, send it */ - DESTROY_IF(this->responding.packet); - this->responding.packet = NULL; - status = this->ike_sa->generate_message(this->ike_sa, message, - &this->responding.packet); + clear_packets(this->responding.packets); + result = generate_message(this, message, &this->responding.packets); message->destroy(message); if (id) { id->set_responder_spi(id, responder_spi); } - if (status != SUCCESS) + if (!result) { charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); return DESTROY_ME; } - charon->sender->send(charon->sender, - this->responding.packet->clone(this->responding.packet)); + send_packets(this, this->responding.packets, NULL, NULL); if (delete) { if (hook) @@ -963,6 +1069,48 @@ METHOD(task_manager_t, incr_mid, void, } } +/** + * Handle the given IKE fragment, if it is one. + * + * Returns SUCCESS if the message is not a fragment, and NEED_MORE if it was + * handled properly. Error states are returned if the fragment was invalid or + * the reassembled message could not have been processed properly. + */ +static status_t handle_fragment(private_task_manager_t *this, + message_t **defrag, message_t *msg) +{ + message_t *reassembled; + status_t status; + + if (!msg->get_payload(msg, PLV2_FRAGMENT)) + { + return SUCCESS; + } + if (!*defrag) + { + *defrag = message_create_defrag(msg); + if (!*defrag) + { + return FAILED; + } + } + status = (*defrag)->add_fragment(*defrag, msg); + if (status == SUCCESS) + { + /* reinject the reassembled message */ + reassembled = *defrag; + *defrag = NULL; + status = this->ike_sa->process_message(this->ike_sa, reassembled); + if (status == SUCCESS) + { + /* avoid processing the last fragment */ + status = NEED_MORE; + } + reassembled->destroy(reassembled); + } + return status; +} + /** * Send a notify back to the sender */ @@ -1156,6 +1304,11 @@ METHOD(task_manager_t, process_message, status_t, { /* with MOBIKE, we do no implicit updates */ this->ike_sa->update_hosts(this->ike_sa, me, other, mid == 1); } + status = handle_fragment(this, &this->responding.defrag, msg); + if (status != SUCCESS) + { + return status; + } charon->bus->message(charon->bus, msg, TRUE, TRUE); if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED) { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ @@ -1168,20 +1321,19 @@ METHOD(task_manager_t, process_message, status_t, } this->responding.mid++; } - else if ((mid == this->responding.mid - 1) && this->responding.packet) + else if ((mid == this->responding.mid - 1) && + array_count(this->responding.packets)) { - packet_t *clone; - host_t *host; - + status = handle_fragment(this, &this->responding.defrag, msg); + if (status != SUCCESS) + { + return status; + } DBG1(DBG_IKE, "received retransmit of request with ID %d, " "retransmitting response", mid); charon->bus->alert(charon->bus, ALERT_RETRANSMIT_RECEIVE, msg); - clone = this->responding.packet->clone(this->responding.packet); - host = msg->get_destination(msg); - clone->set_source(clone, host->clone(host)); - host = msg->get_source(msg); - clone->set_destination(clone, host->clone(host)); - charon->sender->send(charon->sender, clone); + send_packets(this, this->responding.packets, + msg->get_destination(msg), msg->get_source(msg)); } else { @@ -1209,6 +1361,11 @@ METHOD(task_manager_t, process_message, status_t, this->ike_sa->update_hosts(this->ike_sa, NULL, other, FALSE); } } + status = handle_fragment(this, &this->initiating.defrag, msg); + if (status != SUCCESS) + { + return status; + } charon->bus->message(charon->bus, msg, TRUE, TRUE); if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED) { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ @@ -1368,7 +1525,25 @@ METHOD(task_manager_t, queue_mobike, void, mobike = ike_mobike_create(this->ike_sa, TRUE); if (roam) { + enumerator_t *enumerator; + task_t *current; + mobike->roam(mobike, address); + + /* enable path probing for a currently active MOBIKE task. This might + * not be the case if an address appeared on a new interface while the + * current address is not working but has not yet disappeared. */ + enumerator = array_create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (current->get_type(current) == TASK_IKE_MOBIKE) + { + ike_mobike_t *active = (ike_mobike_t*)current; + active->enable_probing(active); + break; + } + } + enumerator->destroy(enumerator); } else { @@ -1485,10 +1660,12 @@ METHOD(task_manager_t, reset, void, task_t *task; /* reset message counters and retransmit packets */ - DESTROY_IF(this->responding.packet); - DESTROY_IF(this->initiating.packet); - this->responding.packet = NULL; - this->initiating.packet = NULL; + clear_packets(this->responding.packets); + clear_packets(this->initiating.packets); + DESTROY_IF(this->responding.defrag); + DESTROY_IF(this->initiating.defrag); + this->responding.defrag = NULL; + this->initiating.defrag = NULL; if (initiate != UINT_MAX) { this->initiating.mid = initiate; @@ -1542,8 +1719,12 @@ METHOD(task_manager_t, destroy, void, array_destroy(this->queued_tasks); array_destroy(this->passive_tasks); - DESTROY_IF(this->responding.packet); - DESTROY_IF(this->initiating.packet); + clear_packets(this->responding.packets); + array_destroy(this->responding.packets); + clear_packets(this->initiating.packets); + array_destroy(this->initiating.packets); + DESTROY_IF(this->responding.defrag); + DESTROY_IF(this->initiating.defrag); free(this); } diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index e3c18ea0f..71c5f22fa 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -161,6 +161,19 @@ static void build_payloads(private_ike_init_t *this, message_t *message) message->add_payload(message, (payload_t*)ke_payload); message->add_payload(message, (payload_t*)nonce_payload); } + + /* negotiate fragmentation if we are not rekeying */ + if (!this->old_sa && + this->config->fragmentation(this->config) != FRAGMENTATION_NO) + { + if (this->initiator || + this->ike_sa->supports_extension(this->ike_sa, + EXT_IKE_FRAGMENTATION)) + { + message->add_notify(message, FALSE, FRAGMENTATION_SUPPORTED, + chunk_empty); + } + } } /** @@ -220,6 +233,16 @@ static void process_payloads(private_ike_init_t *this, message_t *message) this->other_nonce = nonce_payload->get_nonce(nonce_payload); break; } + case PLV2_NOTIFY: + { + notify_payload_t *notify = (notify_payload_t*)payload; + + if (notify->get_notify_type(notify) == FRAGMENTATION_SUPPORTED) + { + this->ike_sa->enable_extension(this->ike_sa, + EXT_IKE_FRAGMENTATION); + } + } default: break; } diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index 00ca615d8..d91fa5862 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Tobias Brunner + * Copyright (C) 2010-2014 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -77,6 +77,11 @@ struct private_ike_mobike_t { * additional addresses got updated */ bool addresses_updated; + + /** + * whether the pending updates counter was increased + */ + bool pending_update; }; /** @@ -301,35 +306,61 @@ static void apply_port(host_t *host, host_t *old, u_int16_t port, bool local) host->set_port(host, port); } -METHOD(ike_mobike_t, transmit, void, +METHOD(ike_mobike_t, transmit, bool, private_ike_mobike_t *this, packet_t *packet) { host_t *me, *other, *me_old, *other_old; enumerator_t *enumerator; ike_cfg_t *ike_cfg; packet_t *copy; + int family = AF_UNSPEC; + bool found = FALSE; + + me_old = this->ike_sa->get_my_host(this->ike_sa); + other_old = this->ike_sa->get_other_host(this->ike_sa); + ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); if (!this->check) { - return; + me = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, + other_old, me_old); + if (me) + { + if (me->ip_equals(me, me_old)) + { + charon->sender->send(charon->sender, packet->clone(packet)); + me->destroy(me); + return TRUE; + } + me->destroy(me); + } + this->check = TRUE; } - me_old = this->ike_sa->get_my_host(this->ike_sa); - other_old = this->ike_sa->get_other_host(this->ike_sa); - ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); + switch (charon->socket->supported_families(charon->socket)) + { + case SOCKET_FAMILY_IPV4: + family = AF_INET; + break; + case SOCKET_FAMILY_IPV6: + family = AF_INET6; + break; + case SOCKET_FAMILY_BOTH: + case SOCKET_FAMILY_NONE: + break; + } enumerator = this->ike_sa->create_peer_address_enumerator(this->ike_sa); while (enumerator->enumerate(enumerator, (void**)&other)) { + if (family != AF_UNSPEC && other->get_family(other) != family) + { + continue; + } me = hydra->kernel_interface->get_source_addr( hydra->kernel_interface, other, NULL); if (me) { - if (me->get_family(me) != other->get_family(other)) - { - me->destroy(me); - continue; - } /* reuse port for an active address, 4500 otherwise */ apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg), TRUE); other = other->clone(other); @@ -339,9 +370,11 @@ METHOD(ike_mobike_t, transmit, void, copy->set_source(copy, me); copy->set_destination(copy, other); charon->sender->send(charon->sender, copy); + found = TRUE; } } enumerator->destroy(enumerator); + return found; } METHOD(task_t, build_i, status_t, @@ -481,9 +514,7 @@ METHOD(task_t, process_i, status_t, } else if (message->get_exchange_type(message) == INFORMATIONAL) { - u_int32_t updates = this->ike_sa->get_pending_updates(this->ike_sa) - 1; - this->ike_sa->set_pending_updates(this->ike_sa, updates); - if (updates > 0) + if (this->ike_sa->get_pending_updates(this->ike_sa) > 1) { /* newer update queued, ignore this one */ return SUCCESS; @@ -560,7 +591,6 @@ METHOD(task_t, process_i, status_t, 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; } } @@ -573,8 +603,12 @@ METHOD(ike_mobike_t, addresses, void, private_ike_mobike_t *this) { this->address = TRUE; - this->ike_sa->set_pending_updates(this->ike_sa, + if (!this->pending_update) + { + this->pending_update = 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, @@ -582,8 +616,12 @@ METHOD(ike_mobike_t, roam, void, { this->check = TRUE; this->address = address; - this->ike_sa->set_pending_updates(this->ike_sa, + if (!this->pending_update) + { + this->pending_update = TRUE; + this->ike_sa->set_pending_updates(this->ike_sa, this->ike_sa->get_pending_updates(this->ike_sa) + 1); + } } METHOD(ike_mobike_t, dpd, void, @@ -593,8 +631,12 @@ METHOD(ike_mobike_t, dpd, void, { this->natd = ike_natd_create(this->ike_sa, this->initiator); } - this->ike_sa->set_pending_updates(this->ike_sa, + if (!this->pending_update) + { + this->pending_update = TRUE; + this->ike_sa->set_pending_updates(this->ike_sa, this->ike_sa->get_pending_updates(this->ike_sa) + 1); + } } METHOD(ike_mobike_t, is_probing, bool, @@ -603,6 +645,12 @@ METHOD(ike_mobike_t, is_probing, bool, return this->check; } +METHOD(ike_mobike_t, enable_probing, void, + private_ike_mobike_t *this) +{ + this->check = TRUE; +} + METHOD(task_t, get_type, task_type_t, private_ike_mobike_t *this) { @@ -618,11 +666,21 @@ METHOD(task_t, migrate, void, { this->natd->task.migrate(&this->natd->task, ike_sa); } + if (this->pending_update) + { + this->ike_sa->set_pending_updates(this->ike_sa, + this->ike_sa->get_pending_updates(this->ike_sa) + 1); + } } METHOD(task_t, destroy, void, private_ike_mobike_t *this) { + if (this->pending_update) + { + this->ike_sa->set_pending_updates(this->ike_sa, + this->ike_sa->get_pending_updates(this->ike_sa) - 1); + } chunk_free(&this->cookie2); if (this->natd) { @@ -650,6 +708,7 @@ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator) .dpd = _dpd, .transmit = _transmit, .is_probing = _is_probing, + .enable_probing = _enable_probing, }, .ike_sa = ike_sa, .initiator = initiator, diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.h b/src/libcharon/sa/ikev2/tasks/ike_mobike.h index b145a9a8b..bb2318c9c 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.h +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.h @@ -70,8 +70,9 @@ struct ike_mobike_t { * probing. * * @param packet the packet to transmit + * @return TRUE if transmitted, FALSE if no path found */ - void (*transmit)(ike_mobike_t *this, packet_t *packet); + bool (*transmit)(ike_mobike_t *this, packet_t *packet); /** * Check if this task is probing for routability. @@ -79,6 +80,11 @@ struct ike_mobike_t { * @return TRUE if task is probing */ bool (*is_probing)(ike_mobike_t *this); + + /** + * Enable probing for routability. + */ + void (*enable_probing)(ike_mobike_t *this); }; /** -- cgit v1.2.3