From 518dd33c94e041db0444c7d1f33da363bb8e3faf Mon Sep 17 00:00:00 2001 From: Yves-Alexis Perez Date: Thu, 24 Mar 2016 11:59:32 +0100 Subject: Imported Upstream version 5.4.0 --- Android.common.mk | 2 +- Android.mk | 1 - Makefile.in | 2 + NEWS | 40 + conf/Makefile.am | 1 + conf/Makefile.in | 3 + conf/format-options.py | 42 +- conf/options/charon.conf | 8 +- conf/options/charon.opt | 13 +- conf/plugins/p-cscf.conf | 18 + conf/plugins/p-cscf.opt | 11 + conf/strongswan.conf.5.main | 24 +- config.h.in | 3 + configure | 588 +++- configure.ac | 74 +- init/Makefile.in | 2 + init/systemd-swanctl/Makefile.in | 2 + init/systemd-swanctl/strongswan-swanctl.service.in | 3 + init/systemd/Makefile.in | 2 + man/Makefile.in | 2 + man/ipsec.conf.5.in | 21 +- scripts/Makefile.in | 2 + src/Makefile.am | 4 - src/Makefile.in | 82 +- src/_copyright/Makefile.in | 2 + src/_updown/Makefile.in | 2 + src/aikgen/Makefile.in | 2 + src/charon-cmd/Makefile.am | 2 - src/charon-cmd/Makefile.in | 5 +- src/charon-cmd/charon-cmd.c | 6 - src/charon-nm/Makefile.am | 2 - src/charon-nm/Makefile.in | 5 +- src/charon-nm/charon-nm.c | 11 - src/charon-svc/Makefile.am | 2 - src/charon-svc/Makefile.in | 5 +- src/charon-svc/charon-svc.c | 32 +- src/charon-systemd/Makefile.am | 6 +- src/charon-systemd/Makefile.in | 12 +- src/charon-systemd/charon-systemd.c | 16 +- src/charon-tkm/Makefile.am | 6 +- src/charon-tkm/Makefile.in | 8 +- src/charon-tkm/src/charon-tkm.c | 10 - src/charon-tkm/src/ees/ees_callbacks.c | 8 +- src/charon-tkm/tests/keymat_tests.c | 1 - src/charon-tkm/tests/tests.c | 5 - src/charon/Android.mk | 3 +- src/charon/Makefile.am | 2 - src/charon/Makefile.in | 5 +- src/charon/charon.c | 11 - src/checksum/Makefile.am | 10 - src/checksum/Makefile.in | 79 +- src/checksum/checksum_builder.c | 7 +- src/conftest/Makefile.am | 2 - src/conftest/Makefile.in | 5 +- src/conftest/conftest.c | 8 - src/conftest/conftest.h | 1 - src/dumm/Makefile.in | 2 + src/include/Makefile.in | 2 + src/ipsec/Makefile.in | 2 + src/ipsec/_ipsec.8 | 2 +- src/ipsec/_ipsec.in | 9 +- src/libcharon/Android.mk | 20 +- src/libcharon/Makefile.am | 42 +- src/libcharon/Makefile.in | 339 ++- src/libcharon/attributes/attributes.c | 16 +- src/libcharon/attributes/attributes.h | 3 + src/libcharon/attributes/mem_pool.c | 1 - src/libcharon/bus/listeners/custom_logger.h | 65 + src/libcharon/config/child_cfg.c | 54 +- src/libcharon/config/child_cfg.h | 10 +- src/libcharon/config/ike_cfg.c | 24 +- src/libcharon/config/peer_cfg.c | 157 +- src/libcharon/config/peer_cfg.h | 16 +- src/libcharon/config/proposal.c | 180 +- src/libcharon/daemon.c | 278 +- src/libcharon/daemon.h | 53 +- src/libcharon/encoding/message.c | 12 +- .../encoding/payloads/configuration_attribute.c | 9 + src/libcharon/kernel/kernel_handler.c | 7 +- src/libcharon/kernel/kernel_handler.h | 2 +- src/libcharon/kernel/kernel_interface.c | 1085 +++++++ src/libcharon/kernel/kernel_interface.h | 655 +++++ src/libcharon/kernel/kernel_ipsec.c | 36 + src/libcharon/kernel/kernel_ipsec.h | 297 ++ src/libcharon/kernel/kernel_listener.h | 107 + src/libcharon/kernel/kernel_net.c | 36 + src/libcharon/kernel/kernel_net.h | 196 ++ src/libcharon/network/receiver.c | 6 +- src/libcharon/plugins/addrblock/Makefile.am | 1 - src/libcharon/plugins/addrblock/Makefile.in | 3 +- src/libcharon/plugins/android_dns/Makefile.am | 1 - src/libcharon/plugins/android_dns/Makefile.in | 3 +- src/libcharon/plugins/android_log/Makefile.am | 1 - src/libcharon/plugins/android_log/Makefile.in | 3 +- src/libcharon/plugins/attr/Makefile.am | 1 - src/libcharon/plugins/attr/Makefile.in | 3 +- src/libcharon/plugins/attr/attr_provider.c | 67 +- src/libcharon/plugins/attr_sql/Makefile.am | 1 - src/libcharon/plugins/attr_sql/Makefile.in | 3 +- src/libcharon/plugins/certexpire/Makefile.am | 1 - src/libcharon/plugins/certexpire/Makefile.in | 3 +- src/libcharon/plugins/connmark/Makefile.am | 1 - src/libcharon/plugins/connmark/Makefile.in | 3 +- src/libcharon/plugins/connmark/connmark_listener.c | 354 ++- src/libcharon/plugins/coupling/Makefile.am | 1 - src/libcharon/plugins/coupling/Makefile.in | 3 +- src/libcharon/plugins/dhcp/Makefile.am | 1 - src/libcharon/plugins/dhcp/Makefile.in | 3 +- src/libcharon/plugins/dhcp/dhcp_socket.c | 4 +- src/libcharon/plugins/dnscert/Makefile.am | 1 - src/libcharon/plugins/dnscert/Makefile.in | 3 +- src/libcharon/plugins/duplicheck/Makefile.am | 1 - src/libcharon/plugins/duplicheck/Makefile.in | 3 +- src/libcharon/plugins/duplicheck/duplicheck.c | 2 + src/libcharon/plugins/eap_aka/Makefile.am | 1 - src/libcharon/plugins/eap_aka/Makefile.in | 3 +- src/libcharon/plugins/eap_aka_3gpp2/Makefile.am | 1 - src/libcharon/plugins/eap_aka_3gpp2/Makefile.in | 3 +- src/libcharon/plugins/eap_dynamic/Makefile.am | 1 - src/libcharon/plugins/eap_dynamic/Makefile.in | 3 +- src/libcharon/plugins/eap_gtc/Makefile.am | 1 - src/libcharon/plugins/eap_gtc/Makefile.in | 3 +- src/libcharon/plugins/eap_identity/Makefile.am | 1 - src/libcharon/plugins/eap_identity/Makefile.in | 3 +- src/libcharon/plugins/eap_md5/Makefile.am | 1 - src/libcharon/plugins/eap_md5/Makefile.in | 3 +- src/libcharon/plugins/eap_mschapv2/Makefile.am | 1 - src/libcharon/plugins/eap_mschapv2/Makefile.in | 3 +- src/libcharon/plugins/eap_peap/Makefile.am | 1 - src/libcharon/plugins/eap_peap/Makefile.in | 3 +- src/libcharon/plugins/eap_radius/Makefile.am | 1 - src/libcharon/plugins/eap_radius/Makefile.in | 3 +- src/libcharon/plugins/eap_sim/Makefile.am | 1 - src/libcharon/plugins/eap_sim/Makefile.in | 3 +- src/libcharon/plugins/eap_sim_file/Makefile.am | 1 - src/libcharon/plugins/eap_sim_file/Makefile.in | 3 +- src/libcharon/plugins/eap_sim_pcsc/Makefile.am | 1 - src/libcharon/plugins/eap_sim_pcsc/Makefile.in | 3 +- .../plugins/eap_simaka_pseudonym/Makefile.am | 1 - .../plugins/eap_simaka_pseudonym/Makefile.in | 3 +- .../plugins/eap_simaka_reauth/Makefile.am | 1 - .../plugins/eap_simaka_reauth/Makefile.in | 3 +- src/libcharon/plugins/eap_simaka_sql/Makefile.am | 1 - src/libcharon/plugins/eap_simaka_sql/Makefile.in | 3 +- src/libcharon/plugins/eap_tls/Makefile.am | 1 - src/libcharon/plugins/eap_tls/Makefile.in | 3 +- src/libcharon/plugins/eap_tnc/Makefile.am | 1 - src/libcharon/plugins/eap_tnc/Makefile.in | 3 +- src/libcharon/plugins/eap_tnc/eap_tnc.c | 2 +- src/libcharon/plugins/eap_ttls/Makefile.am | 1 - src/libcharon/plugins/eap_ttls/Makefile.in | 3 +- src/libcharon/plugins/error_notify/Makefile.am | 1 - src/libcharon/plugins/error_notify/Makefile.in | 3 +- src/libcharon/plugins/ext_auth/Makefile.am | 1 - src/libcharon/plugins/ext_auth/Makefile.in | 3 +- src/libcharon/plugins/farp/Makefile.am | 1 - src/libcharon/plugins/farp/Makefile.in | 3 +- src/libcharon/plugins/forecast/Makefile.am | 1 - src/libcharon/plugins/forecast/Makefile.in | 3 +- .../plugins/forecast/forecast_forwarder.c | 8 +- src/libcharon/plugins/forecast/forecast_listener.c | 252 +- src/libcharon/plugins/ha/Makefile.am | 1 - src/libcharon/plugins/ha/Makefile.in | 3 +- src/libcharon/plugins/ha/ha_child.c | 4 + src/libcharon/plugins/ha/ha_dispatcher.c | 17 +- src/libcharon/plugins/ha/ha_ike.c | 32 +- src/libcharon/plugins/ha/ha_message.c | 2 + src/libcharon/plugins/ha/ha_message.h | 2 + src/libcharon/plugins/ipseckey/Makefile.am | 1 - src/libcharon/plugins/ipseckey/Makefile.in | 3 +- src/libcharon/plugins/kernel_iph/Makefile.am | 1 - src/libcharon/plugins/kernel_iph/Makefile.in | 3 +- src/libcharon/plugins/kernel_iph/kernel_iph_net.c | 4 +- .../plugins/kernel_iph/kernel_iph_plugin.c | 2 - src/libcharon/plugins/kernel_libipsec/Makefile.am | 1 - src/libcharon/plugins/kernel_libipsec/Makefile.in | 3 +- .../kernel_libipsec/kernel_libipsec_ipsec.c | 63 +- .../kernel_libipsec/kernel_libipsec_router.c | 7 +- src/libcharon/plugins/kernel_netlink/Makefile.am | 44 + src/libcharon/plugins/kernel_netlink/Makefile.in | 1007 +++++++ .../plugins/kernel_netlink/kernel_netlink_ipsec.c | 2975 +++++++++++++++++++ .../plugins/kernel_netlink/kernel_netlink_ipsec.h | 46 + .../plugins/kernel_netlink/kernel_netlink_net.c | 2686 +++++++++++++++++ .../plugins/kernel_netlink/kernel_netlink_net.h | 46 + .../plugins/kernel_netlink/kernel_netlink_plugin.c | 85 + .../plugins/kernel_netlink/kernel_netlink_plugin.h | 42 + .../plugins/kernel_netlink/kernel_netlink_shared.c | 655 +++++ .../plugins/kernel_netlink/kernel_netlink_shared.h | 104 + .../plugins/kernel_netlink/suites/test_socket.c | 302 ++ src/libcharon/plugins/kernel_netlink/tests.c | 47 + src/libcharon/plugins/kernel_netlink/tests.h | 16 + src/libcharon/plugins/kernel_pfkey/Makefile.am | 19 + src/libcharon/plugins/kernel_pfkey/Makefile.in | 782 +++++ .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 3094 +++++++++++++++++++ .../plugins/kernel_pfkey/kernel_pfkey_ipsec.h | 46 + .../plugins/kernel_pfkey/kernel_pfkey_plugin.c | 80 + .../plugins/kernel_pfkey/kernel_pfkey_plugin.h | 42 + src/libcharon/plugins/kernel_pfroute/Makefile.am | 19 + src/libcharon/plugins/kernel_pfroute/Makefile.in | 782 +++++ .../plugins/kernel_pfroute/kernel_pfroute_net.c | 1902 ++++++++++++ .../plugins/kernel_pfroute/kernel_pfroute_net.h | 46 + .../plugins/kernel_pfroute/kernel_pfroute_plugin.c | 74 + .../plugins/kernel_pfroute/kernel_pfroute_plugin.h | 42 + src/libcharon/plugins/kernel_wfp/Makefile.am | 1 - src/libcharon/plugins/kernel_wfp/Makefile.in | 3 +- .../plugins/kernel_wfp/kernel_wfp_ipsec.c | 25 +- src/libcharon/plugins/led/Makefile.am | 1 - src/libcharon/plugins/led/Makefile.in | 3 +- src/libcharon/plugins/load_tester/Makefile.am | 1 - src/libcharon/plugins/load_tester/Makefile.in | 3 +- .../plugins/load_tester/load_tester_config.c | 13 +- .../plugins/load_tester/load_tester_plugin.c | 22 +- src/libcharon/plugins/lookip/Makefile.am | 1 - src/libcharon/plugins/lookip/Makefile.in | 3 +- src/libcharon/plugins/maemo/Makefile.am | 1 - src/libcharon/plugins/maemo/Makefile.in | 3 +- src/libcharon/plugins/medcli/Makefile.am | 1 - src/libcharon/plugins/medcli/Makefile.in | 3 +- src/libcharon/plugins/medsrv/Makefile.am | 1 - src/libcharon/plugins/medsrv/Makefile.in | 3 +- src/libcharon/plugins/osx_attr/Makefile.am | 1 - src/libcharon/plugins/osx_attr/Makefile.in | 3 +- src/libcharon/plugins/p_cscf/Makefile.am | 19 + src/libcharon/plugins/p_cscf/Makefile.in | 782 +++++ src/libcharon/plugins/p_cscf/p_cscf_handler.c | 173 ++ src/libcharon/plugins/p_cscf/p_cscf_handler.h | 49 + src/libcharon/plugins/p_cscf/p_cscf_plugin.c | 101 + src/libcharon/plugins/p_cscf/p_cscf_plugin.h | 43 + src/libcharon/plugins/radattr/Makefile.am | 1 - src/libcharon/plugins/radattr/Makefile.in | 3 +- src/libcharon/plugins/resolve/Makefile.am | 1 - src/libcharon/plugins/resolve/Makefile.in | 3 +- src/libcharon/plugins/resolve/resolve_handler.c | 1 - src/libcharon/plugins/smp/Makefile.am | 1 - src/libcharon/plugins/smp/Makefile.in | 3 +- src/libcharon/plugins/smp/smp.c | 8 +- src/libcharon/plugins/socket_default/Makefile.am | 1 - src/libcharon/plugins/socket_default/Makefile.in | 3 +- .../plugins/socket_default/socket_default_socket.c | 8 +- src/libcharon/plugins/socket_dynamic/Makefile.am | 1 - src/libcharon/plugins/socket_dynamic/Makefile.in | 3 +- .../plugins/socket_dynamic/socket_dynamic_socket.c | 7 +- src/libcharon/plugins/socket_win/Makefile.am | 1 - src/libcharon/plugins/socket_win/Makefile.in | 3 +- .../plugins/socket_win/socket_win_socket.c | 7 +- src/libcharon/plugins/sql/Makefile.am | 1 - src/libcharon/plugins/sql/Makefile.in | 3 +- src/libcharon/plugins/stroke/Makefile.am | 1 - src/libcharon/plugins/stroke/Makefile.in | 3 +- src/libcharon/plugins/stroke/stroke_config.c | 123 +- src/libcharon/plugins/stroke/stroke_control.c | 1 - src/libcharon/plugins/stroke/stroke_list.c | 619 +--- src/libcharon/plugins/stroke/stroke_socket.c | 13 +- src/libcharon/plugins/systime_fix/Makefile.am | 1 - src/libcharon/plugins/systime_fix/Makefile.in | 3 +- src/libcharon/plugins/tnc_ifmap/Makefile.am | 1 - src/libcharon/plugins/tnc_ifmap/Makefile.in | 3 +- .../plugins/tnc_ifmap/tnc_ifmap_listener.c | 5 +- src/libcharon/plugins/tnc_pdp/Makefile.am | 1 - src/libcharon/plugins/tnc_pdp/Makefile.in | 3 +- src/libcharon/plugins/uci/Makefile.am | 1 - src/libcharon/plugins/uci/Makefile.in | 3 +- src/libcharon/plugins/unity/Makefile.am | 1 - src/libcharon/plugins/unity/Makefile.in | 3 +- src/libcharon/plugins/updown/Makefile.am | 1 - src/libcharon/plugins/updown/Makefile.in | 3 +- src/libcharon/plugins/updown/updown_listener.c | 70 +- src/libcharon/plugins/vici/Makefile.am | 8 +- src/libcharon/plugins/vici/Makefile.in | 22 +- src/libcharon/plugins/vici/README.md | 98 +- src/libcharon/plugins/vici/perl/Makefile.am | 27 + src/libcharon/plugins/vici/perl/Makefile.in | 567 ++++ .../plugins/vici/perl/Vici-Session/Changes | 6 + .../plugins/vici/perl/Vici-Session/MANIFEST | 9 + .../plugins/vici/perl/Vici-Session/Makefile.PL | 11 + .../plugins/vici/perl/Vici-Session/README.pod | 649 ++++ .../vici/perl/Vici-Session/lib/Vici/Message.pm | 256 ++ .../vici/perl/Vici-Session/lib/Vici/Packet.pm | 191 ++ .../vici/perl/Vici-Session/lib/Vici/Session.pm | 204 ++ .../vici/perl/Vici-Session/lib/Vici/Transport.pm | 88 + .../vici/perl/Vici-Session/t/Vici-Session.t | 18 + src/libcharon/plugins/vici/python/Makefile.in | 2 + src/libcharon/plugins/vici/python/vici/session.py | 8 + src/libcharon/plugins/vici/ruby/Makefile.in | 2 + src/libcharon/plugins/vici/ruby/lib/vici.rb | 6 + src/libcharon/plugins/vici/vici_cert_info.c | 57 + src/libcharon/plugins/vici/vici_cert_info.h | 32 + src/libcharon/plugins/vici/vici_config.c | 359 ++- src/libcharon/plugins/vici/vici_config.h | 5 +- src/libcharon/plugins/vici/vici_control.c | 187 +- src/libcharon/plugins/vici/vici_cred.c | 69 +- src/libcharon/plugins/vici/vici_plugin.c | 3 +- src/libcharon/plugins/vici/vici_query.c | 374 ++- src/libcharon/plugins/vici/vici_tests.c | 1 - src/libcharon/plugins/whitelist/Makefile.am | 1 - src/libcharon/plugins/whitelist/Makefile.in | 3 +- src/libcharon/plugins/xauth_eap/Makefile.am | 1 - src/libcharon/plugins/xauth_eap/Makefile.in | 3 +- src/libcharon/plugins/xauth_generic/Makefile.am | 1 - src/libcharon/plugins/xauth_generic/Makefile.in | 3 +- src/libcharon/plugins/xauth_noauth/Makefile.am | 1 - src/libcharon/plugins/xauth_noauth/Makefile.in | 3 +- src/libcharon/plugins/xauth_pam/Makefile.am | 1 - src/libcharon/plugins/xauth_pam/Makefile.in | 3 +- src/libcharon/processing/jobs/adopt_children_job.c | 1 - src/libcharon/processing/jobs/redirect_job.c | 106 + src/libcharon/processing/jobs/redirect_job.h | 51 + src/libcharon/processing/jobs/send_keepalive_job.c | 2 +- src/libcharon/sa/child_sa.c | 82 +- src/libcharon/sa/ike_sa.c | 557 +++- src/libcharon/sa/ike_sa.h | 65 +- src/libcharon/sa/ike_sa_manager.c | 97 +- .../ikev1/authenticators/pubkey_v1_authenticator.c | 4 +- src/libcharon/sa/ikev1/phase1.c | 2 +- src/libcharon/sa/ikev1/tasks/isakmp_natd.c | 3 +- src/libcharon/sa/ikev1/tasks/mode_config.c | 37 +- src/libcharon/sa/ikev1/tasks/quick_mode.c | 18 +- src/libcharon/sa/ikev1/tasks/xauth.c | 1 - .../sa/ikev2/authenticators/pubkey_authenticator.c | 23 +- src/libcharon/sa/ikev2/task_manager_v2.c | 102 +- src/libcharon/sa/ikev2/tasks/child_create.c | 7 +- src/libcharon/sa/ikev2/tasks/child_rekey.c | 11 +- src/libcharon/sa/ikev2/tasks/ike_auth.c | 144 +- src/libcharon/sa/ikev2/tasks/ike_config.c | 5 + src/libcharon/sa/ikev2/tasks/ike_init.c | 146 +- src/libcharon/sa/ikev2/tasks/ike_me.c | 5 +- src/libcharon/sa/ikev2/tasks/ike_mobike.c | 13 +- src/libcharon/sa/ikev2/tasks/ike_natd.c | 9 +- src/libcharon/sa/ikev2/tasks/ike_redirect.c | 150 + src/libcharon/sa/ikev2/tasks/ike_redirect.h | 54 + src/libcharon/sa/ikev2/tasks/ike_vendor.c | 56 +- .../sa/ikev2/tasks/ike_verify_peer_cert.c | 117 + .../sa/ikev2/tasks/ike_verify_peer_cert.h | 54 + src/libcharon/sa/redirect_manager.c | 274 ++ src/libcharon/sa/redirect_manager.h | 109 + src/libcharon/sa/redirect_provider.h | 59 + src/libcharon/sa/shunt_manager.c | 25 +- src/libcharon/sa/task.c | 2 + src/libcharon/sa/task.h | 18 +- src/libcharon/sa/trap_manager.c | 4 +- src/libcharon/tests/Makefile.am | 2 - src/libcharon/tests/Makefile.in | 5 +- src/libcharon/tests/libcharon_tests.c | 3 - src/libfast/Makefile.in | 2 + src/libhydra/Android.mk | 37 - src/libhydra/Makefile.am | 60 - src/libhydra/Makefile.in | 922 ------ src/libhydra/hydra.c | 93 - src/libhydra/hydra.h | 71 - src/libhydra/kernel/kernel_interface.c | 1086 ------- src/libhydra/kernel/kernel_interface.h | 655 ----- src/libhydra/kernel/kernel_ipsec.c | 38 - src/libhydra/kernel/kernel_ipsec.h | 297 -- src/libhydra/kernel/kernel_listener.h | 107 - src/libhydra/kernel/kernel_net.c | 38 - src/libhydra/kernel/kernel_net.h | 196 -- src/libhydra/plugins/kernel_netlink/Makefile.am | 44 - src/libhydra/plugins/kernel_netlink/Makefile.in | 1005 ------- .../plugins/kernel_netlink/kernel_netlink_ipsec.c | 2966 ------------------- .../plugins/kernel_netlink/kernel_netlink_ipsec.h | 46 - .../plugins/kernel_netlink/kernel_netlink_net.c | 2685 ----------------- .../plugins/kernel_netlink/kernel_netlink_net.h | 46 - .../plugins/kernel_netlink/kernel_netlink_plugin.c | 87 - .../plugins/kernel_netlink/kernel_netlink_plugin.h | 42 - .../plugins/kernel_netlink/kernel_netlink_shared.c | 655 ----- .../plugins/kernel_netlink/kernel_netlink_shared.h | 96 - .../plugins/kernel_netlink/suites/test_socket.c | 302 -- src/libhydra/plugins/kernel_netlink/tests.c | 49 - src/libhydra/plugins/kernel_netlink/tests.h | 16 - src/libhydra/plugins/kernel_pfkey/Makefile.am | 19 - src/libhydra/plugins/kernel_pfkey/Makefile.in | 780 ----- .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 3102 -------------------- .../plugins/kernel_pfkey/kernel_pfkey_ipsec.h | 46 - .../plugins/kernel_pfkey/kernel_pfkey_plugin.c | 82 - .../plugins/kernel_pfkey/kernel_pfkey_plugin.h | 42 - src/libhydra/plugins/kernel_pfroute/Makefile.am | 19 - src/libhydra/plugins/kernel_pfroute/Makefile.in | 780 ----- .../plugins/kernel_pfroute/kernel_pfroute_net.c | 1903 ------------ .../plugins/kernel_pfroute/kernel_pfroute_net.h | 46 - .../plugins/kernel_pfroute/kernel_pfroute_plugin.c | 76 - .../plugins/kernel_pfroute/kernel_pfroute_plugin.h | 42 - src/libhydra/tests/Makefile.am | 18 - src/libhydra/tests/Makefile.in | 839 ------ src/libhydra/tests/hydra_tests.c | 53 - src/libhydra/tests/hydra_tests.h | 14 - src/libimcv/Makefile.in | 2 + src/libimcv/imc/imc_os_info.c | 12 +- src/libimcv/plugins/imc_attestation/Makefile.in | 2 + src/libimcv/plugins/imc_hcd/Makefile.in | 2 + src/libimcv/plugins/imc_os/Makefile.in | 2 + src/libimcv/plugins/imc_scanner/Makefile.in | 2 + src/libimcv/plugins/imc_swid/Makefile.in | 2 + src/libimcv/plugins/imc_test/Makefile.in | 2 + src/libimcv/plugins/imv_attestation/Makefile.in | 2 + .../imv_attestation/imv_attestation_agent.c | 6 +- .../imv_attestation/imv_attestation_state.h | 2 +- src/libimcv/plugins/imv_hcd/Makefile.in | 2 + src/libimcv/plugins/imv_os/Makefile.in | 2 + src/libimcv/plugins/imv_scanner/Makefile.in | 2 + src/libimcv/plugins/imv_swid/Makefile.in | 2 + src/libimcv/plugins/imv_swid/imv_swid_agent.c | 11 +- src/libimcv/plugins/imv_swid/imv_swid_state.c | 19 +- src/libimcv/plugins/imv_swid/imv_swid_state.h | 37 +- src/libimcv/plugins/imv_test/Makefile.in | 2 + src/libimcv/pts/components/pts_component_manager.h | 4 +- src/libipsec/Makefile.in | 2 + src/libipsec/ipsec_policy_mgr.c | 11 +- src/libipsec/ipsec_policy_mgr.h | 11 +- src/libipsec/tests/Makefile.in | 2 + src/libpttls/Makefile.in | 2 + src/libradius/Makefile.in | 2 + src/libsimaka/Makefile.am | 1 - src/libsimaka/Makefile.in | 3 +- src/libstrongswan/Android.mk | 3 +- src/libstrongswan/Makefile.am | 4 +- src/libstrongswan/Makefile.in | 18 + src/libstrongswan/asn1/asn1.h | 1 + src/libstrongswan/asn1/oid.c | 889 +++--- src/libstrongswan/asn1/oid.h | 429 +-- src/libstrongswan/asn1/oid.txt | 1 + src/libstrongswan/collections/array.c | 10 + src/libstrongswan/collections/array.h | 15 + src/libstrongswan/collections/linked_list.c | 54 +- src/libstrongswan/collections/linked_list.h | 23 +- src/libstrongswan/credentials/auth_cfg.c | 248 +- src/libstrongswan/credentials/auth_cfg.h | 13 + .../credentials/certificates/certificate.c | 9 +- .../credentials/certificates/certificate_printer.c | 753 +++++ .../credentials/certificates/certificate_printer.h | 70 + .../credentials/certificates/ocsp_response.h | 7 + src/libstrongswan/credentials/certificates/x509.c | 27 + src/libstrongswan/credentials/certificates/x509.h | 4 + src/libstrongswan/credentials/credential_manager.c | 8 +- src/libstrongswan/credentials/credential_manager.h | 7 +- src/libstrongswan/library.c | 33 +- src/libstrongswan/library.h | 12 +- src/libstrongswan/plugins/acert/Makefile.in | 2 + src/libstrongswan/plugins/aes/Makefile.in | 2 + src/libstrongswan/plugins/aesni/Makefile.in | 2 + src/libstrongswan/plugins/af_alg/Makefile.in | 2 + src/libstrongswan/plugins/agent/Makefile.in | 2 + src/libstrongswan/plugins/bliss/Makefile.in | 2 + src/libstrongswan/plugins/bliss/tests/Makefile.in | 2 + src/libstrongswan/plugins/blowfish/Makefile.in | 2 + src/libstrongswan/plugins/ccm/Makefile.in | 2 + src/libstrongswan/plugins/chapoly/Makefile.in | 2 + .../plugins/chapoly/chapoly_drv_portable.c | 21 - src/libstrongswan/plugins/cmac/Makefile.in | 2 + src/libstrongswan/plugins/constraints/Makefile.in | 2 + src/libstrongswan/plugins/ctr/Makefile.in | 2 + src/libstrongswan/plugins/curl/Makefile.in | 2 + src/libstrongswan/plugins/des/Makefile.in | 2 + src/libstrongswan/plugins/dnskey/Makefile.in | 2 + src/libstrongswan/plugins/files/Makefile.in | 2 + src/libstrongswan/plugins/fips_prf/Makefile.in | 2 + src/libstrongswan/plugins/gcm/Makefile.in | 2 + src/libstrongswan/plugins/gcrypt/Makefile.in | 2 + src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c | 8 +- src/libstrongswan/plugins/gmp/Makefile.in | 2 + src/libstrongswan/plugins/gmp/gmp_plugin.c | 16 +- src/libstrongswan/plugins/hmac/Makefile.in | 2 + src/libstrongswan/plugins/keychain/Makefile.in | 2 + src/libstrongswan/plugins/ldap/Makefile.in | 2 + src/libstrongswan/plugins/md4/Makefile.in | 2 + src/libstrongswan/plugins/md5/Makefile.in | 2 + src/libstrongswan/plugins/mysql/Makefile.in | 2 + src/libstrongswan/plugins/nonce/Makefile.in | 2 + src/libstrongswan/plugins/ntru/Makefile.in | 2 + src/libstrongswan/plugins/openssl/Makefile.in | 2 + src/libstrongswan/plugins/openssl/openssl_plugin.c | 46 +- src/libstrongswan/plugins/padlock/Makefile.in | 2 + src/libstrongswan/plugins/pem/Makefile.in | 2 + src/libstrongswan/plugins/pgp/Makefile.in | 2 + src/libstrongswan/plugins/pkcs1/Makefile.in | 2 + src/libstrongswan/plugins/pkcs11/Makefile.in | 2 + src/libstrongswan/plugins/pkcs12/Makefile.in | 2 + src/libstrongswan/plugins/pkcs7/Makefile.in | 2 + src/libstrongswan/plugins/pkcs8/Makefile.in | 2 + src/libstrongswan/plugins/pubkey/Makefile.in | 2 + src/libstrongswan/plugins/pubkey/pubkey_cert.c | 8 + src/libstrongswan/plugins/pubkey/pubkey_cert.h | 7 + src/libstrongswan/plugins/random/Makefile.in | 2 + src/libstrongswan/plugins/rc2/Makefile.in | 2 + src/libstrongswan/plugins/rdrand/Makefile.in | 2 + src/libstrongswan/plugins/revocation/Makefile.in | 2 + src/libstrongswan/plugins/sha1/Makefile.in | 2 + src/libstrongswan/plugins/sha2/Makefile.in | 2 + src/libstrongswan/plugins/sha3/Makefile.in | 2 + src/libstrongswan/plugins/soup/Makefile.in | 2 + src/libstrongswan/plugins/sqlite/Makefile.in | 2 + src/libstrongswan/plugins/sshkey/Makefile.in | 2 + src/libstrongswan/plugins/test_vectors/Makefile.in | 2 + src/libstrongswan/plugins/unbound/Makefile.in | 2 + src/libstrongswan/plugins/winhttp/Makefile.in | 2 + src/libstrongswan/plugins/x509/Makefile.in | 2 + src/libstrongswan/plugins/x509/x509_cert.c | 4 +- .../plugins/x509/x509_ocsp_response.c | 42 +- src/libstrongswan/plugins/xcbc/Makefile.in | 2 + src/libstrongswan/processing/watcher.c | 7 + src/libstrongswan/tests/Makefile.am | 1 + src/libstrongswan/tests/Makefile.in | 21 + src/libstrongswan/tests/suites/test_array.c | 43 + src/libstrongswan/tests/suites/test_auth_cfg.c | 122 + .../tests/suites/test_identification.c | 261 +- src/libstrongswan/tests/suites/test_linked_list.c | 91 + src/libstrongswan/tests/tests.h | 1 + src/libstrongswan/threading/thread.c | 34 +- src/libstrongswan/threading/thread.h | 8 +- src/libstrongswan/threading/windows/thread.c | 4 + src/libstrongswan/utils/compat/windows.c | 1 - src/libstrongswan/utils/debug.c | 6 +- src/libstrongswan/utils/identification.c | 389 ++- src/libstrongswan/utils/identification.h | 2 + src/libstrongswan/utils/utils/byteorder.h | 78 +- src/libtls/Makefile.in | 2 + src/libtls/tests/Makefile.in | 2 + src/libtls/tls_peer.c | 3 +- src/libtls/tls_server.c | 2 +- src/libtnccs/Makefile.in | 2 + src/libtnccs/plugins/tnc_imc/Makefile.in | 2 + src/libtnccs/plugins/tnc_imv/Makefile.in | 2 + src/libtnccs/plugins/tnc_tnccs/Makefile.in | 2 + src/libtnccs/plugins/tnccs_11/Makefile.in | 2 + src/libtnccs/plugins/tnccs_20/Makefile.in | 2 + src/libtnccs/plugins/tnccs_20/tnccs_20.c | 38 +- src/libtnccs/plugins/tnccs_dynamic/Makefile.in | 2 + src/libtncif/Makefile.in | 2 + src/manager/Makefile.in | 2 + src/medsrv/Makefile.in | 2 + src/pki/Makefile.am | 5 +- src/pki/Makefile.in | 12 +- src/pki/command.c | 11 +- src/pki/command.h | 2 +- src/pki/commands/print.c | 543 +--- src/pki/man/Makefile.in | 2 + src/pool/Makefile.am | 2 - src/pool/Makefile.in | 5 +- src/pt-tls-client/Makefile.in | 2 + src/scepclient/Makefile.am | 1 - src/scepclient/Makefile.in | 3 +- src/starter/Android.mk | 3 +- src/starter/Makefile.am | 4 +- src/starter/Makefile.in | 8 +- src/starter/confread.c | 4 +- src/starter/netkey.c | 1 - src/starter/starter.c | 4 - src/starter/tests/Makefile.in | 2 + src/stroke/Makefile.in | 2 + src/stroke/stroke.c | 13 +- src/swanctl/Makefile.am | 8 +- src/swanctl/Makefile.in | 28 +- src/swanctl/command.c | 11 +- src/swanctl/command.h | 4 +- src/swanctl/commands/list_algs.c | 104 + src/swanctl/commands/list_certs.c | 603 +--- src/swanctl/commands/list_sas.c | 13 +- src/swanctl/commands/load_conns.c | 9 +- src/swanctl/commands/load_creds.c | 47 +- src/swanctl/commands/redirect.c | 132 + src/swanctl/commands/stats.c | 12 + src/swanctl/swanctl.8.in | 9 +- src/swanctl/swanctl.conf | 22 +- src/swanctl/swanctl.conf.5.main | 139 +- src/swanctl/swanctl.h | 18 + src/swanctl/swanctl.opt | 99 +- testing/Makefile.in | 2 + testing/do-tests | 31 +- testing/hosts/alice/etc/ipsec.d/ipsec.sql | 4 +- testing/hosts/bob/etc/ipsec.d/ipsec.sql | 4 +- testing/hosts/carol/etc/ipsec.d/ipsec.sql | 4 +- testing/hosts/dave/etc/ipsec.d/ipsec.sql | 4 +- .../hosts/default/usr/local/bin/expect-connection | 8 +- testing/hosts/moon/etc/ipsec.d/ipsec.sql | 4 +- testing/hosts/sun/etc/ipsec.d/ipsec.sql | 4 +- testing/hosts/venus/etc/ipsec.d/ipsec.sql | 4 +- testing/hosts/winnetou/etc/openssl/generate-crl | 3 + testing/scripts/recipes/013_strongswan.mk | 1 - testing/tests/af-alg/alg-camellia/description.txt | 5 +- testing/tests/af-alg/alg-camellia/evaltest.dat | 8 +- .../af-alg/alg-camellia/hosts/carol/etc/ipsec.conf | 22 - .../alg-camellia/hosts/carol/etc/strongswan.conf | 7 +- .../hosts/carol/etc/swanctl/swanctl.conf | 27 + .../af-alg/alg-camellia/hosts/moon/etc/ipsec.conf | 21 - .../alg-camellia/hosts/moon/etc/strongswan.conf | 7 +- .../hosts/moon/etc/swanctl/swanctl.conf | 25 + testing/tests/af-alg/alg-camellia/posttest.dat | 5 +- testing/tests/af-alg/alg-camellia/pretest.dat | 7 +- testing/tests/af-alg/alg-camellia/test.conf | 4 + testing/tests/af-alg/rw-cert/description.txt | 4 +- testing/tests/af-alg/rw-cert/evaltest.dat | 13 +- .../af-alg/rw-cert/hosts/carol/etc/ipsec.conf | 22 - .../af-alg/rw-cert/hosts/carol/etc/strongswan.conf | 7 +- .../rw-cert/hosts/carol/etc/swanctl/swanctl.conf | 27 + .../tests/af-alg/rw-cert/hosts/dave/etc/ipsec.conf | 22 - .../af-alg/rw-cert/hosts/dave/etc/strongswan.conf | 8 +- .../rw-cert/hosts/dave/etc/swanctl/swanctl.conf | 27 + .../tests/af-alg/rw-cert/hosts/moon/etc/ipsec.conf | 21 - .../af-alg/rw-cert/hosts/moon/etc/strongswan.conf | 7 +- .../rw-cert/hosts/moon/etc/swanctl/swanctl.conf | 25 + testing/tests/af-alg/rw-cert/posttest.dat | 8 +- testing/tests/af-alg/rw-cert/pretest.dat | 14 +- testing/tests/af-alg/rw-cert/test.conf | 4 + .../tests/gcrypt-ikev2/alg-camellia/evaltest.dat | 4 +- .../alg-camellia/hosts/carol/etc/ipsec.conf | 2 +- .../alg-camellia/hosts/moon/etc/ipsec.conf | 2 +- testing/tests/gcrypt-ikev2/rw-cert/pretest.dat | 1 + testing/tests/ha/active-passive/pretest.dat | 1 - testing/tests/ikev1/alg-3des-md5/evaltest.dat | 4 +- testing/tests/ikev1/alg-sha256/evaltest.dat | 8 +- .../ikev1/alg-sha256/hosts/carol/etc/ipsec.conf | 4 +- .../ikev1/alg-sha256/hosts/moon/etc/ipsec.conf | 4 +- testing/tests/ikev1/alg-sha384/evaltest.dat | 4 +- testing/tests/ikev1/alg-sha512/evaltest.dat | 4 +- .../ip-pool-db/hosts/moon/etc/strongswan.conf | 2 - .../ikev1/xauth-rsa-eap-md5-radius/evaltest.dat | 2 +- testing/tests/ikev1/xauth-rsa-radius/evaltest.dat | 2 +- testing/tests/ikev2/alg-aes-xcbc/evaltest.dat | 4 +- .../ikev2/alg-aes-xcbc/hosts/carol/etc/ipsec.conf | 4 +- .../ikev2/alg-aes-xcbc/hosts/moon/etc/ipsec.conf | 4 +- testing/tests/ikev2/alg-sha256-96/evaltest.dat | 4 +- .../ikev2/alg-sha256-96/hosts/carol/etc/ipsec.conf | 4 +- .../ikev2/alg-sha256-96/hosts/moon/etc/ipsec.conf | 4 +- testing/tests/ikev2/alg-sha256/evaltest.dat | 4 +- .../ikev2/alg-sha256/hosts/carol/etc/ipsec.conf | 4 +- .../ikev2/alg-sha256/hosts/moon/etc/ipsec.conf | 4 +- .../ip-pool-db/hosts/moon/etc/strongswan.conf | 2 - .../hosts/moon/etc/strongswan.conf | 2 - .../ip-two-pools-db/hosts/moon/etc/strongswan.conf | 2 - .../hosts/moon/etc/strongswan.conf | 2 - .../hosts/moon/etc/strongswan.conf | 2 - testing/tests/ikev2/ip-two-pools/pretest.dat | 2 +- .../tests/ikev2/reauth-mbb-revoked/description.txt | 15 + .../tests/ikev2/reauth-mbb-revoked/evaltest.dat | 10 + .../reauth-mbb-revoked/hosts/carol/etc/ipsec.conf | 21 + .../hosts/carol/etc/strongswan.conf | 7 + .../reauth-mbb-revoked/hosts/moon/etc/ipsec.conf | 19 + .../hosts/moon/etc/strongswan.conf | 5 + .../tests/ikev2/reauth-mbb-revoked/posttest.dat | 3 + testing/tests/ikev2/reauth-mbb-revoked/pretest.dat | 4 + testing/tests/ikev2/reauth-mbb-revoked/test.conf | 21 + .../tests/ikev2/redirect-active/description.txt | 8 + testing/tests/ikev2/redirect-active/evaltest.dat | 28 + .../redirect-active/hosts/alice/etc/ipsec.conf | 19 + .../hosts/alice/etc/ipsec.d/certs/marsCert.pem | 25 + .../hosts/alice/etc/ipsec.d/private/marsKey.pem | 27 + .../redirect-active/hosts/alice/etc/ipsec.secrets | 3 + .../redirect-active/hosts/alice/etc/iptables.rules | 34 + .../hosts/alice/etc/strongswan.conf | 6 + .../redirect-active/hosts/carol/etc/ipsec.conf | 19 + .../hosts/carol/etc/strongswan.conf | 5 + .../redirect-active/hosts/dave/etc/ipsec.conf | 19 + .../redirect-active/hosts/dave/etc/strongswan.conf | 6 + .../redirect-active/hosts/moon/etc/ipsec.conf | 18 + .../hosts/moon/etc/ipsec.d/certs/marsCert.pem | 25 + .../hosts/moon/etc/ipsec.d/private/marsKey.pem | 27 + .../redirect-active/hosts/moon/etc/ipsec.secrets | 3 + .../redirect-active/hosts/moon/etc/strongswan.conf | 6 + testing/tests/ikev2/redirect-active/posttest.dat | 10 + testing/tests/ikev2/redirect-active/pretest.dat | 13 + testing/tests/ikev2/redirect-active/test.conf | 21 + testing/tests/ikev2/rw-dnssec/pretest.dat | 2 +- testing/tests/ikev2/trap-any/evaltest.dat | 10 +- testing/tests/libipsec/net2net-null/evaltest.dat | 4 +- .../net2net-null/hosts/moon/etc/ipsec.conf | 4 +- .../libipsec/net2net-null/hosts/sun/etc/ipsec.conf | 4 +- .../tests/openssl-ikev1/alg-camellia/evaltest.dat | 12 +- .../alg-camellia/hosts/carol/etc/ipsec.conf | 4 +- .../alg-camellia/hosts/moon/etc/ipsec.conf | 4 +- .../tests/openssl-ikev1/ecdsa-certs/evaltest.dat | 8 +- .../tests/openssl-ikev2/alg-camellia/evaltest.dat | 12 +- .../alg-camellia/hosts/carol/etc/ipsec.conf | 4 +- .../alg-camellia/hosts/moon/etc/ipsec.conf | 4 +- testing/tests/pfkey/alg-aes-xcbc/evaltest.dat | 4 +- .../pfkey/alg-aes-xcbc/hosts/carol/etc/ipsec.conf | 4 +- .../pfkey/alg-aes-xcbc/hosts/moon/etc/ipsec.conf | 4 +- testing/tests/sql/ip-pool-db-expired/evaltest.dat | 12 +- .../hosts/carol/etc/ipsec.d/data.sql | 2 +- .../hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../hosts/dave/etc/ipsec.d/data.sql | 2 +- .../hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../hosts/moon/etc/ipsec.d/data.sql | 2 +- .../hosts/moon/etc/strongswan.conf | 8 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/ip-pool-db-expired/posttest.dat | 8 +- testing/tests/sql/ip-pool-db-expired/pretest.dat | 14 +- testing/tests/sql/ip-pool-db-expired/test.conf | 4 + testing/tests/sql/ip-pool-db-restart/evaltest.dat | 12 +- .../hosts/carol/etc/ipsec.d/data.sql | 2 +- .../hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../hosts/dave/etc/ipsec.d/data.sql | 2 +- .../hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../hosts/moon/etc/ipsec.d/data.sql | 2 +- .../hosts/moon/etc/strongswan.conf | 8 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/ip-pool-db-restart/posttest.dat | 8 +- testing/tests/sql/ip-pool-db-restart/pretest.dat | 14 +- testing/tests/sql/ip-pool-db-restart/test.conf | 4 + testing/tests/sql/ip-pool-db/evaltest.dat | 12 +- .../ip-pool-db/hosts/carol/etc/ipsec.d/data.sql | 2 +- .../sql/ip-pool-db/hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../sql/ip-pool-db/hosts/dave/etc/ipsec.d/data.sql | 2 +- .../sql/ip-pool-db/hosts/dave/etc/strongswan.conf | 2 +- .../ip-pool-db/hosts/dave/etc/swanctl/swanctl.conf | 1 + .../sql/ip-pool-db/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../sql/ip-pool-db/hosts/moon/etc/strongswan.conf | 8 +- .../ip-pool-db/hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/ip-pool-db/posttest.dat | 11 +- testing/tests/sql/ip-pool-db/pretest.dat | 14 +- testing/tests/sql/ip-pool-db/test.conf | 4 + .../sql/ip-split-pools-db-restart/evaltest.dat | 12 +- .../hosts/carol/etc/ipsec.d/data.sql | 2 +- .../hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../hosts/dave/etc/ipsec.d/data.sql | 2 +- .../hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../hosts/moon/etc/ipsec.d/data.sql | 2 +- .../hosts/moon/etc/strongswan.conf | 8 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + .../sql/ip-split-pools-db-restart/posttest.dat | 8 +- .../sql/ip-split-pools-db-restart/pretest.dat | 14 +- .../tests/sql/ip-split-pools-db-restart/test.conf | 4 + testing/tests/sql/ip-split-pools-db/evaltest.dat | 11 +- .../hosts/carol/etc/ipsec.d/data.sql | 2 +- .../hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../hosts/dave/etc/ipsec.d/data.sql | 2 +- .../hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../hosts/moon/etc/ipsec.d/data.sql | 2 +- .../hosts/moon/etc/strongswan.conf | 8 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/ip-split-pools-db/posttest.dat | 8 +- testing/tests/sql/ip-split-pools-db/pretest.dat | 14 +- testing/tests/sql/ip-split-pools-db/test.conf | 3 + testing/tests/sql/multi-level-ca/evaltest.dat | 16 +- .../hosts/carol/etc/ipsec.d/data.sql | 2 +- .../multi-level-ca/hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../multi-level-ca/hosts/dave/etc/ipsec.d/data.sql | 2 +- .../multi-level-ca/hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../multi-level-ca/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../multi-level-ca/hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/multi-level-ca/posttest.dat | 8 +- testing/tests/sql/multi-level-ca/pretest.dat | 14 +- testing/tests/sql/multi-level-ca/test.conf | 4 + testing/tests/sql/net2net-cert/evaltest.dat | 6 +- .../net2net-cert/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../net2net-cert/hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + .../net2net-cert/hosts/sun/etc/ipsec.d/data.sql | 2 +- .../sql/net2net-cert/hosts/sun/etc/strongswan.conf | 2 +- .../hosts/sun/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/net2net-cert/posttest.dat | 4 +- testing/tests/sql/net2net-cert/pretest.dat | 11 +- testing/tests/sql/net2net-cert/test.conf | 4 + testing/tests/sql/net2net-psk/evaltest.dat | 6 +- .../net2net-psk/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../sql/net2net-psk/hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + .../sql/net2net-psk/hosts/sun/etc/ipsec.d/data.sql | 2 +- .../sql/net2net-psk/hosts/sun/etc/strongswan.conf | 2 +- .../net2net-psk/hosts/sun/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/net2net-psk/posttest.dat | 4 +- testing/tests/sql/net2net-psk/pretest.dat | 11 +- testing/tests/sql/net2net-psk/test.conf | 4 + testing/tests/sql/net2net-route-pem/evaltest.dat | 12 +- .../hosts/moon/etc/ipsec.d/data.sql | 6 +- .../hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + .../hosts/sun/etc/ipsec.d/data.sql | 6 +- .../hosts/sun/etc/strongswan.conf | 2 +- .../hosts/sun/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/net2net-route-pem/posttest.dat | 4 +- testing/tests/sql/net2net-route-pem/pretest.dat | 10 +- testing/tests/sql/net2net-route-pem/test.conf | 4 + testing/tests/sql/net2net-start-pem/evaltest.dat | 10 +- .../hosts/moon/etc/ipsec.d/data.sql | 14 +- .../hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + .../hosts/sun/etc/ipsec.d/data.sql | 14 +- .../hosts/sun/etc/strongswan.conf | 2 +- .../hosts/sun/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/net2net-start-pem/posttest.dat | 4 +- testing/tests/sql/net2net-start-pem/pretest.dat | 10 +- testing/tests/sql/net2net-start-pem/test.conf | 4 + testing/tests/sql/rw-cert/evaltest.dat | 12 +- .../sql/rw-cert/hosts/carol/etc/ipsec.d/data.sql | 2 +- .../sql/rw-cert/hosts/carol/etc/strongswan.conf | 2 +- .../rw-cert/hosts/carol/etc/swanctl/swanctl.conf | 1 + .../sql/rw-cert/hosts/dave/etc/ipsec.d/data.sql | 2 +- .../sql/rw-cert/hosts/dave/etc/strongswan.conf | 2 +- .../rw-cert/hosts/dave/etc/swanctl/swanctl.conf | 1 + .../sql/rw-cert/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../sql/rw-cert/hosts/moon/etc/strongswan.conf | 2 +- .../rw-cert/hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/rw-cert/posttest.dat | 8 +- testing/tests/sql/rw-cert/pretest.dat | 14 +- testing/tests/sql/rw-cert/test.conf | 4 + testing/tests/sql/rw-eap-aka-rsa/evaltest.dat | 8 +- .../hosts/carol/etc/ipsec.d/data.sql | 2 +- .../rw-eap-aka-rsa/hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../rw-eap-aka-rsa/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../rw-eap-aka-rsa/hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/rw-eap-aka-rsa/posttest.dat | 5 +- testing/tests/sql/rw-eap-aka-rsa/pretest.dat | 9 +- testing/tests/sql/rw-eap-aka-rsa/test.conf | 4 + testing/tests/sql/rw-psk-ipv4/evaltest.dat | 13 +- .../rw-psk-ipv4/hosts/carol/etc/ipsec.d/data.sql | 2 +- .../rw-psk-ipv4/hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../rw-psk-ipv4/hosts/dave/etc/ipsec.d/data.sql | 2 +- .../sql/rw-psk-ipv4/hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../rw-psk-ipv4/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../sql/rw-psk-ipv4/hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/rw-psk-ipv4/posttest.dat | 8 +- testing/tests/sql/rw-psk-ipv4/pretest.dat | 14 +- testing/tests/sql/rw-psk-ipv4/test.conf | 4 + testing/tests/sql/rw-psk-ipv6/evaltest.dat | 13 +- .../rw-psk-ipv6/hosts/carol/etc/ipsec.d/data.sql | 2 +- .../rw-psk-ipv6/hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../rw-psk-ipv6/hosts/dave/etc/ipsec.d/data.sql | 2 +- .../sql/rw-psk-ipv6/hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../rw-psk-ipv6/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../sql/rw-psk-ipv6/hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/rw-psk-ipv6/posttest.dat | 8 +- testing/tests/sql/rw-psk-ipv6/pretest.dat | 14 +- testing/tests/sql/rw-psk-ipv6/test.conf | 6 +- testing/tests/sql/rw-psk-rsa-split/evaltest.dat | 12 +- .../hosts/carol/etc/ipsec.d/data.sql | 2 +- .../hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../hosts/dave/etc/ipsec.d/data.sql | 2 +- .../hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../hosts/moon/etc/ipsec.d/data.sql | 2 +- .../hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/rw-psk-rsa-split/posttest.dat | 8 +- testing/tests/sql/rw-psk-rsa-split/pretest.dat | 14 +- testing/tests/sql/rw-psk-rsa-split/test.conf | 4 + testing/tests/sql/rw-rsa-keyid/evaltest.dat | 12 +- .../rw-rsa-keyid/hosts/carol/etc/ipsec.d/data.sql | 2 +- .../rw-rsa-keyid/hosts/carol/etc/strongswan.conf | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../rw-rsa-keyid/hosts/dave/etc/ipsec.d/data.sql | 2 +- .../rw-rsa-keyid/hosts/dave/etc/strongswan.conf | 2 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../rw-rsa-keyid/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../rw-rsa-keyid/hosts/moon/etc/strongswan.conf | 2 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/rw-rsa-keyid/posttest.dat | 8 +- testing/tests/sql/rw-rsa-keyid/pretest.dat | 14 +- testing/tests/sql/rw-rsa-keyid/test.conf | 4 + testing/tests/sql/rw-rsa/evaltest.dat | 12 +- .../sql/rw-rsa/hosts/carol/etc/ipsec.d/data.sql | 2 +- .../sql/rw-rsa/hosts/carol/etc/strongswan.conf | 2 +- .../rw-rsa/hosts/carol/etc/swanctl/swanctl.conf | 1 + .../sql/rw-rsa/hosts/dave/etc/ipsec.d/data.sql | 2 +- .../sql/rw-rsa/hosts/dave/etc/strongswan.conf | 2 +- .../sql/rw-rsa/hosts/dave/etc/swanctl/swanctl.conf | 1 + .../sql/rw-rsa/hosts/moon/etc/ipsec.d/data.sql | 2 +- .../sql/rw-rsa/hosts/moon/etc/strongswan.conf | 2 +- .../sql/rw-rsa/hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/sql/rw-rsa/posttest.dat | 8 +- testing/tests/sql/rw-rsa/pretest.dat | 14 +- testing/tests/sql/rw-rsa/test.conf | 4 + .../tests/sql/shunt-policies-nat-rw/evaltest.dat | 13 +- .../hosts/alice/etc/ipsec.conf | 3 - .../hosts/alice/etc/ipsec.secrets | 3 - .../hosts/alice/etc/strongswan.conf | 2 +- .../hosts/alice/etc/swanctl/swanctl.conf | 1 + .../shunt-policies-nat-rw/hosts/sun/etc/ipsec.conf | 3 - .../hosts/sun/etc/ipsec.d/data.sql | 2 +- .../hosts/sun/etc/ipsec.secrets | 3 - .../hosts/sun/etc/strongswan.conf | 2 +- .../hosts/sun/etc/swanctl/swanctl.conf | 1 + .../hosts/venus/etc/ipsec.conf | 3 - .../hosts/venus/etc/ipsec.secrets | 3 - .../hosts/venus/etc/strongswan.conf | 2 +- .../hosts/venus/etc/swanctl/swanctl.conf | 1 + .../tests/sql/shunt-policies-nat-rw/posttest.dat | 8 +- .../tests/sql/shunt-policies-nat-rw/pretest.dat | 15 +- testing/tests/sql/shunt-policies-nat-rw/test.conf | 4 + .../tests/swanctl/config-payload/description.txt | 8 + testing/tests/swanctl/config-payload/evaltest.dat | 16 + .../config-payload/hosts/carol/etc/strongswan.conf | 14 + .../hosts/carol/etc/swanctl/swanctl.conf | 28 + .../config-payload/hosts/dave/etc/strongswan.conf | 14 + .../hosts/dave/etc/swanctl/swanctl.conf | 28 + .../config-payload/hosts/moon/etc/strongswan.conf | 15 + .../hosts/moon/etc/swanctl/swanctl.conf | 34 + .../hosts/moon/etc/swanctl/swanctl_base.conf | 17 + testing/tests/swanctl/config-payload/posttest.dat | 8 + testing/tests/swanctl/config-payload/pretest.dat | 12 + testing/tests/swanctl/config-payload/test.conf | 25 + testing/tests/swanctl/dhcp-dynamic/description.txt | 8 + testing/tests/swanctl/dhcp-dynamic/evaltest.dat | 22 + .../dhcp-dynamic/hosts/carol/etc/strongswan.conf | 14 + .../hosts/carol/etc/swanctl/swanctl.conf | 28 + .../dhcp-dynamic/hosts/dave/etc/strongswan.conf | 14 + .../hosts/dave/etc/swanctl/swanctl.conf | 28 + .../swanctl/dhcp-dynamic/hosts/moon/etc/dhcpd.conf | 9 + .../dhcp-dynamic/hosts/moon/etc/iptables.rules | 39 + .../dhcp-dynamic/hosts/moon/etc/strongswan.conf | 20 + .../hosts/moon/etc/swanctl/swanctl.conf | 26 + .../dhcp-dynamic/hosts/venus/etc/dhcp/dhcpd.conf | 14 + .../dhcp-dynamic/hosts/venus/etc/dnsmasq.conf | 7 + testing/tests/swanctl/dhcp-dynamic/posttest.dat | 12 + testing/tests/swanctl/dhcp-dynamic/pretest.dat | 13 + testing/tests/swanctl/dhcp-dynamic/test.conf | 25 + testing/tests/swanctl/frags-ipv4/description.txt | 8 +- testing/tests/swanctl/frags-ipv4/evaltest.dat | 8 +- .../hosts/carol/etc/swanctl/swanctl.conf | 5 - .../frags-ipv4/hosts/dave/etc/swanctl/swanctl.conf | 5 - .../frags-ipv4/hosts/moon/etc/swanctl/swanctl.conf | 5 - testing/tests/swanctl/frags-ipv4/pretest.dat | 4 +- testing/tests/swanctl/frags-ipv6/evaltest.dat | 8 +- .../hosts/carol/etc/swanctl/swanctl.conf | 5 - .../frags-ipv6/hosts/dave/etc/swanctl/swanctl.conf | 5 - .../frags-ipv6/hosts/moon/etc/swanctl/swanctl.conf | 5 - testing/tests/swanctl/frags-ipv6/pretest.dat | 4 +- testing/tests/swanctl/ip-pool-db/evaltest.dat | 8 +- .../hosts/carol/etc/swanctl/swanctl.conf | 9 +- .../ip-pool-db/hosts/dave/etc/swanctl/swanctl.conf | 9 +- .../ip-pool-db/hosts/moon/etc/swanctl/swanctl.conf | 9 +- testing/tests/swanctl/ip-pool-db/pretest.dat | 6 +- testing/tests/swanctl/ip-pool/evaltest.dat | 8 +- .../ip-pool/hosts/carol/etc/swanctl/swanctl.conf | 9 +- .../ip-pool/hosts/dave/etc/swanctl/swanctl.conf | 9 +- .../ip-pool/hosts/moon/etc/swanctl/swanctl.conf | 9 +- testing/tests/swanctl/ip-pool/pretest.dat | 4 +- .../mult-auth-rsa-eap-sim-id/description.txt | 17 + .../swanctl/mult-auth-rsa-eap-sim-id/evaltest.dat | 20 + .../hosts/alice/etc/freeradius/eap.conf | 5 + .../hosts/alice/etc/freeradius/modules/sim_files | 3 + .../hosts/alice/etc/freeradius/proxy.conf | 5 + .../alice/etc/freeradius/sites-available/default | 61 + .../hosts/alice/etc/freeradius/triplets.dat | 6 + .../hosts/alice/etc/freeradius/users | 0 .../hosts/carol/etc/ipsec.d/triplets.dat | 3 + .../hosts/carol/etc/strongswan.conf | 10 + .../hosts/carol/etc/swanctl/swanctl.conf | 32 + .../hosts/dave/etc/ipsec.d/triplets.dat | 3 + .../hosts/dave/etc/strongswan.conf | 10 + .../hosts/dave/etc/swanctl/swanctl.conf | 32 + .../hosts/moon/etc/iptables.rules | 32 + .../hosts/moon/etc/strongswan.conf | 17 + .../hosts/moon/etc/swanctl/swanctl.conf | 30 + .../swanctl/mult-auth-rsa-eap-sim-id/posttest.dat | 4 + .../swanctl/mult-auth-rsa-eap-sim-id/pretest.dat | 15 + .../swanctl/mult-auth-rsa-eap-sim-id/test.conf | 30 + testing/tests/swanctl/multi-level-ca/evaltest.dat | 12 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 - .../hosts/dave/etc/swanctl/swanctl.conf | 1 - .../hosts/moon/etc/swanctl/swanctl.conf | 2 - testing/tests/swanctl/multi-level-ca/pretest.dat | 4 +- testing/tests/swanctl/net2net-cert/evaltest.dat | 4 +- .../hosts/moon/etc/swanctl/swanctl.conf | 9 +- .../hosts/sun/etc/swanctl/swanctl.conf | 9 +- testing/tests/swanctl/net2net-cert/pretest.dat | 3 +- .../tests/swanctl/net2net-pubkey/description.txt | 7 + testing/tests/swanctl/net2net-pubkey/evaltest.dat | 5 + .../net2net-pubkey/hosts/moon/etc/strongswan.conf | 10 + .../hosts/moon/etc/swanctl/pubkey/moonPub.pem | 9 + .../hosts/moon/etc/swanctl/pubkey/sunPub.pem | 9 + .../hosts/moon/etc/swanctl/swanctl.conf | 30 + .../net2net-pubkey/hosts/sun/etc/strongswan.conf | 10 + .../hosts/sun/etc/swanctl/pubkey/moonPub.pem | 9 + .../hosts/sun/etc/swanctl/pubkey/sunPub.pem | 9 + .../hosts/sun/etc/swanctl/swanctl.conf | 30 + testing/tests/swanctl/net2net-pubkey/posttest.dat | 7 + testing/tests/swanctl/net2net-pubkey/pretest.dat | 8 + testing/tests/swanctl/net2net-pubkey/test.conf | 25 + testing/tests/swanctl/net2net-route/evaltest.dat | 4 +- .../hosts/moon/etc/swanctl/swanctl.conf | 8 +- .../hosts/sun/etc/swanctl/swanctl.conf | 8 +- testing/tests/swanctl/net2net-route/pretest.dat | 5 +- testing/tests/swanctl/net2net-start/evaltest.dat | 4 +- .../hosts/moon/etc/swanctl/swanctl.conf | 8 +- .../hosts/sun/etc/swanctl/swanctl.conf | 8 +- testing/tests/swanctl/net2net-start/pretest.dat | 2 +- .../tests/swanctl/ocsp-multi-level/evaltest.dat | 22 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 - .../hosts/dave/etc/swanctl/swanctl.conf | 1 - .../hosts/moon/etc/swanctl/swanctl.conf | 2 - testing/tests/swanctl/ocsp-multi-level/pretest.dat | 4 +- .../tests/swanctl/protoport-dual/description.txt | 7 + testing/tests/swanctl/protoport-dual/evaltest.dat | 7 + .../protoport-dual/hosts/carol/etc/strongswan.conf | 10 + .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../protoport-dual/hosts/moon/etc/strongswan.conf | 10 + .../hosts/moon/etc/swanctl/swanctl.conf | 35 + testing/tests/swanctl/protoport-dual/posttest.dat | 5 + testing/tests/swanctl/protoport-dual/pretest.dat | 8 + testing/tests/swanctl/protoport-dual/test.conf | 25 + .../tests/swanctl/protoport-range/description.txt | 7 + testing/tests/swanctl/protoport-range/evaltest.dat | 7 + .../hosts/carol/etc/strongswan.conf | 10 + .../hosts/carol/etc/swanctl/swanctl.conf | 42 + .../protoport-range/hosts/moon/etc/strongswan.conf | 10 + .../hosts/moon/etc/swanctl/swanctl.conf | 43 + testing/tests/swanctl/protoport-range/posttest.dat | 5 + testing/tests/swanctl/protoport-range/pretest.dat | 10 + testing/tests/swanctl/protoport-range/test.conf | 25 + testing/tests/swanctl/rw-cert/evaltest.dat | 8 +- .../hosts/carol/etc/swanctl/rsa/carolKey.pem | 30 + .../rw-cert/hosts/carol/etc/swanctl/swanctl.conf | 17 +- .../rw-cert/hosts/dave/etc/swanctl/swanctl.conf | 9 +- .../rw-cert/hosts/moon/etc/swanctl/swanctl.conf | 9 +- testing/tests/swanctl/rw-cert/pretest.dat | 4 +- testing/tests/swanctl/rw-dnssec/description.txt | 10 + testing/tests/swanctl/rw-dnssec/evaltest.dat | 20 + .../rw-dnssec/hosts/carol/etc/iptables.rules | 28 + .../swanctl/rw-dnssec/hosts/carol/etc/resolv.conf | 1 + .../rw-dnssec/hosts/carol/etc/strongswan.conf | 19 + .../rw-dnssec/hosts/carol/etc/swanctl/dnssec.keys | 10 + .../hosts/carol/etc/swanctl/pubkey/carolPub.der | Bin 0 -> 294 bytes .../rw-dnssec/hosts/carol/etc/swanctl/swanctl.conf | 28 + .../rw-dnssec/hosts/dave/etc/iptables.rules | 28 + .../swanctl/rw-dnssec/hosts/dave/etc/resolv.conf | 1 + .../rw-dnssec/hosts/dave/etc/strongswan.conf | 19 + .../rw-dnssec/hosts/dave/etc/swanctl/dnssec.keys | 10 + .../hosts/dave/etc/swanctl/pubkey/davePub.der | Bin 0 -> 294 bytes .../rw-dnssec/hosts/dave/etc/swanctl/swanctl.conf | 28 + .../rw-dnssec/hosts/moon/etc/iptables.rules | 28 + .../swanctl/rw-dnssec/hosts/moon/etc/resolv.conf | 1 + .../rw-dnssec/hosts/moon/etc/strongswan.conf | 22 + .../rw-dnssec/hosts/moon/etc/swanctl/dnssec.keys | 10 + .../hosts/moon/etc/swanctl/pubkey/moonPub.der | Bin 0 -> 294 bytes .../rw-dnssec/hosts/moon/etc/swanctl/swanctl.conf | 32 + testing/tests/swanctl/rw-dnssec/posttest.dat | 11 + testing/tests/swanctl/rw-dnssec/pretest.dat | 14 + testing/tests/swanctl/rw-dnssec/test.conf | 25 + testing/tests/swanctl/rw-hash-and-url/evaltest.dat | 8 +- .../hosts/carol/etc/swanctl/swanctl.conf | 9 +- .../hosts/dave/etc/swanctl/swanctl.conf | 9 +- .../hosts/moon/etc/swanctl/swanctl.conf | 9 +- testing/tests/swanctl/rw-hash-and-url/pretest.dat | 4 +- .../tests/swanctl/rw-ntru-bliss/description.txt | 14 + testing/tests/swanctl/rw-ntru-bliss/evaltest.dat | 18 + .../rw-ntru-bliss/hosts/carol/etc/strongswan.conf | 13 + .../hosts/carol/etc/swanctl/bliss/carolKey.der | Bin 0 -> 1182 bytes .../hosts/carol/etc/swanctl/swanctl.conf | 30 + .../hosts/carol/etc/swanctl/x509/carolCert.der | Bin 0 -> 2175 bytes .../etc/swanctl/x509ca/strongswan_blissCert.der | Bin 0 -> 2086 bytes .../rw-ntru-bliss/hosts/dave/etc/strongswan.conf | 13 + .../hosts/dave/etc/swanctl/bliss/daveKey.der | Bin 0 -> 1310 bytes .../hosts/dave/etc/swanctl/swanctl.conf | 30 + .../hosts/dave/etc/swanctl/x509/daveCert.der | Bin 0 -> 2179 bytes .../etc/swanctl/x509ca/strongswan_blissCert.der | Bin 0 -> 2086 bytes .../rw-ntru-bliss/hosts/moon/etc/strongswan.conf | 14 + .../hosts/moon/etc/swanctl/bliss/moonKey.der | Bin 0 -> 1310 bytes .../hosts/moon/etc/swanctl/swanctl.conf | 34 + .../hosts/moon/etc/swanctl/x509/moonCert.der | Bin 0 -> 2200 bytes .../etc/swanctl/x509ca/strongswan_blissCert.der | Bin 0 -> 2086 bytes testing/tests/swanctl/rw-ntru-bliss/posttest.dat | 9 + testing/tests/swanctl/rw-ntru-bliss/pretest.dat | 14 + testing/tests/swanctl/rw-ntru-bliss/test.conf | 25 + testing/tests/swanctl/rw-psk-fqdn/evaltest.dat | 8 +- .../hosts/carol/etc/swanctl/swanctl.conf | 9 +- .../hosts/dave/etc/swanctl/swanctl.conf | 9 +- .../hosts/moon/etc/swanctl/swanctl.conf | 9 +- testing/tests/swanctl/rw-psk-fqdn/pretest.dat | 4 +- testing/tests/swanctl/rw-psk-ikev1/description.txt | 16 + testing/tests/swanctl/rw-psk-ikev1/evaltest.dat | 14 + .../rw-psk-ikev1/hosts/carol/etc/strongswan.conf | 23 + .../hosts/carol/etc/swanctl/swanctl.conf | 33 + .../rw-psk-ikev1/hosts/dave/etc/strongswan.conf | 23 + .../hosts/dave/etc/swanctl/swanctl.conf | 32 + .../rw-psk-ikev1/hosts/moon/etc/strongswan.conf | 23 + .../hosts/moon/etc/swanctl/swanctl.conf | 67 + testing/tests/swanctl/rw-psk-ikev1/posttest.dat | 8 + testing/tests/swanctl/rw-psk-ikev1/pretest.dat | 15 + testing/tests/swanctl/rw-psk-ikev1/test.conf | 25 + testing/tests/swanctl/rw-psk-ipv4/evaltest.dat | 8 +- .../hosts/carol/etc/swanctl/swanctl.conf | 9 +- .../hosts/dave/etc/swanctl/swanctl.conf | 9 +- .../hosts/moon/etc/swanctl/swanctl.conf | 9 +- testing/tests/swanctl/rw-psk-ipv4/pretest.dat | 4 +- .../tests/swanctl/rw-pubkey-anon/description.txt | 9 + testing/tests/swanctl/rw-pubkey-anon/evaltest.dat | 10 + .../rw-pubkey-anon/hosts/carol/etc/strongswan.conf | 14 + .../hosts/carol/etc/swanctl/pubkey/carolPub.pem | 9 + .../hosts/carol/etc/swanctl/pubkey/moonPub.pem | 9 + .../hosts/carol/etc/swanctl/rsa/carolKey.pem | 30 + .../hosts/carol/etc/swanctl/swanctl.conf | 34 + .../rw-pubkey-anon/hosts/dave/etc/strongswan.conf | 14 + .../hosts/dave/etc/swanctl/pubkey/davePub.pem | 9 + .../hosts/dave/etc/swanctl/pubkey/moonPub.pem | 9 + .../hosts/dave/etc/swanctl/swanctl.conf | 26 + .../rw-pubkey-anon/hosts/moon/etc/strongswan.conf | 14 + .../hosts/moon/etc/swanctl/pubkey/carolPub.pem | 9 + .../hosts/moon/etc/swanctl/pubkey/davePub.pem | 9 + .../hosts/moon/etc/swanctl/pubkey/moonPub.pem | 9 + .../hosts/moon/etc/swanctl/pubkey/sunPub.pem | 9 + .../hosts/moon/etc/swanctl/swanctl.conf | 24 + testing/tests/swanctl/rw-pubkey-anon/posttest.dat | 11 + testing/tests/swanctl/rw-pubkey-anon/pretest.dat | 14 + testing/tests/swanctl/rw-pubkey-anon/test.conf | 25 + .../tests/swanctl/rw-pubkey-keyid/description.txt | 8 + testing/tests/swanctl/rw-pubkey-keyid/evaltest.dat | 10 + .../hosts/carol/etc/strongswan.conf | 14 + .../hosts/carol/etc/swanctl/pubkey/carolPub.pem | 9 + .../hosts/carol/etc/swanctl/pubkey/moonPub.pem | 9 + .../hosts/carol/etc/swanctl/rsa/carolKey.pem | 30 + .../hosts/carol/etc/swanctl/swanctl.conf | 34 + .../rw-pubkey-keyid/hosts/dave/etc/strongswan.conf | 14 + .../hosts/dave/etc/swanctl/pubkey/davePub.pem | 9 + .../hosts/dave/etc/swanctl/pubkey/moonPub.pem | 9 + .../hosts/dave/etc/swanctl/swanctl.conf | 26 + .../rw-pubkey-keyid/hosts/moon/etc/strongswan.conf | 14 + .../hosts/moon/etc/swanctl/pubkey/carolPub.pem | 9 + .../hosts/moon/etc/swanctl/pubkey/davePub.pem | 9 + .../hosts/moon/etc/swanctl/pubkey/moonPub.pem | 9 + .../hosts/moon/etc/swanctl/swanctl.conf | 20 + .../hosts/moon/etc/swanctl/swanctl_base.conf | 16 + testing/tests/swanctl/rw-pubkey-keyid/posttest.dat | 11 + testing/tests/swanctl/rw-pubkey-keyid/pretest.dat | 15 + testing/tests/swanctl/rw-pubkey-keyid/test.conf | 25 + .../swanctl/shunt-policies-nat-rw/description.txt | 7 + .../swanctl/shunt-policies-nat-rw/evaltest.dat | 14 + .../hosts/alice/etc/strongswan.conf | 11 + .../hosts/alice/etc/swanctl/swanctl.conf | 40 + .../hosts/sun/etc/iptables.rules | 24 + .../hosts/sun/etc/strongswan.conf | 11 + .../hosts/sun/etc/swanctl/swanctl.conf | 32 + .../hosts/venus/etc/strongswan.conf | 11 + .../hosts/venus/etc/swanctl/swanctl.conf | 40 + .../swanctl/shunt-policies-nat-rw/posttest.dat | 5 + .../swanctl/shunt-policies-nat-rw/pretest.dat | 11 + .../tests/swanctl/shunt-policies-nat-rw/test.conf | 25 + testing/tests/swanctl/xauth-rsa/description.txt | 9 + testing/tests/swanctl/xauth-rsa/evaltest.dat | 12 + .../xauth-rsa/hosts/carol/etc/strongswan.conf | 10 + .../xauth-rsa/hosts/carol/etc/swanctl/swanctl.conf | 38 + .../xauth-rsa/hosts/dave/etc/strongswan.conf | 10 + .../xauth-rsa/hosts/dave/etc/swanctl/swanctl.conf | 38 + .../xauth-rsa/hosts/moon/etc/strongswan.conf | 10 + .../xauth-rsa/hosts/moon/etc/swanctl/swanctl.conf | 40 + testing/tests/swanctl/xauth-rsa/posttest.dat | 8 + testing/tests/swanctl/xauth-rsa/pretest.dat | 11 + testing/tests/swanctl/xauth-rsa/test.conf | 25 + testing/tests/tnc/tnccs-11-fhh/evaltest.dat | 13 +- .../tnc/tnccs-11-fhh/hosts/carol/etc/init.d/charon | 158 + .../tnc/tnccs-11-fhh/hosts/carol/etc/ipsec.conf | 23 - .../tnc/tnccs-11-fhh/hosts/carol/etc/ipsec.secrets | 3 - .../tnccs-11-fhh/hosts/carol/etc/strongswan.conf | 18 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-11-fhh/hosts/dave/etc/init.d/charon | 158 + .../tnc/tnccs-11-fhh/hosts/dave/etc/ipsec.conf | 23 - .../tnc/tnccs-11-fhh/hosts/dave/etc/ipsec.secrets | 3 - .../tnccs-11-fhh/hosts/dave/etc/strongswan.conf | 18 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-11-fhh/hosts/moon/etc/init.d/charon | 158 + .../tnc/tnccs-11-fhh/hosts/moon/etc/ipsec.conf | 34 - .../tnc/tnccs-11-fhh/hosts/moon/etc/ipsec.secrets | 6 - .../tnccs-11-fhh/hosts/moon/etc/strongswan.conf | 18 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-11-fhh/posttest.dat | 6 +- testing/tests/tnc/tnccs-11-fhh/pretest.dat | 14 +- testing/tests/tnc/tnccs-11-fhh/test.conf | 4 +- .../tests/tnc/tnccs-11-radius-block/evaltest.dat | 9 +- .../freeradius/sites-available/inner-tunnel-second | 13 + .../hosts/alice/etc/strongswan.conf | 10 +- .../hosts/carol/etc/ipsec.conf | 23 - .../hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 15 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../hosts/dave/etc/ipsec.conf | 23 - .../hosts/dave/etc/ipsec.secrets | 3 - .../hosts/dave/etc/strongswan.conf | 18 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../hosts/moon/etc/ipsec.conf | 23 - .../hosts/moon/etc/ipsec.secrets | 3 - .../hosts/moon/etc/strongswan.conf | 11 +- .../hosts/moon/etc/swanctl/swanctl.conf | 27 + .../tests/tnc/tnccs-11-radius-block/posttest.dat | 7 +- .../tests/tnc/tnccs-11-radius-block/pretest.dat | 18 +- testing/tests/tnc/tnccs-11-radius-block/test.conf | 7 +- testing/tests/tnc/tnccs-11-radius-pts/evaltest.dat | 13 +- .../tnccs-11-radius-pts/hosts/carol/etc/ipsec.conf | 23 - .../hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 23 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnccs-11-radius-pts/hosts/dave/etc/ipsec.conf | 23 - .../hosts/dave/etc/ipsec.secrets | 3 - .../hosts/dave/etc/strongswan.conf | 27 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnccs-11-radius-pts/hosts/moon/etc/ipsec.conf | 33 - .../hosts/moon/etc/ipsec.secrets | 3 - .../hosts/moon/etc/strongswan.conf | 10 +- .../hosts/moon/etc/swanctl/swanctl.conf | 53 + testing/tests/tnc/tnccs-11-radius-pts/posttest.dat | 6 +- testing/tests/tnc/tnccs-11-radius-pts/pretest.dat | 16 +- testing/tests/tnc/tnccs-11-radius-pts/test.conf | 4 + testing/tests/tnc/tnccs-11-radius/evaltest.dat | 13 +- .../hosts/alice/etc/strongswan.conf | 1 + .../tnc/tnccs-11-radius/hosts/carol/etc/ipsec.conf | 23 - .../tnccs-11-radius/hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 15 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-11-radius/hosts/dave/etc/ipsec.conf | 23 - .../tnccs-11-radius/hosts/dave/etc/ipsec.secrets | 3 - .../tnccs-11-radius/hosts/dave/etc/strongswan.conf | 15 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-11-radius/hosts/moon/etc/ipsec.conf | 33 - .../tnccs-11-radius/hosts/moon/etc/ipsec.secrets | 3 - .../tnccs-11-radius/hosts/moon/etc/strongswan.conf | 10 +- .../hosts/moon/etc/swanctl/swanctl.conf | 53 + testing/tests/tnc/tnccs-11-radius/posttest.dat | 6 +- testing/tests/tnc/tnccs-11-radius/pretest.dat | 14 +- testing/tests/tnc/tnccs-11-radius/test.conf | 3 + .../hosts/alice/etc/strongswan.conf | 1 + .../tnccs-11-supplicant/hosts/carol/etc/ipsec.conf | 1 - .../hosts/carol/etc/ipsec.secrets | 1 - .../hosts/carol/etc/strongswan.conf | 1 + .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../tnccs-11-supplicant/hosts/dave/etc/ipsec.conf | 1 - .../hosts/dave/etc/ipsec.secrets | 1 - .../hosts/dave/etc/strongswan.conf | 1 + .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../tnccs-11-supplicant/hosts/moon/etc/ipsec.conf | 33 - .../hosts/moon/etc/ipsec.secrets | 3 - .../hosts/moon/etc/iptables.rules | 32 - .../hosts/moon/etc/strongswan.conf | 13 - testing/tests/tnc/tnccs-11-supplicant/test.conf | 7 +- testing/tests/tnc/tnccs-11/evaltest.dat | 13 +- .../tests/tnc/tnccs-11/hosts/carol/etc/ipsec.conf | 23 - .../tnc/tnccs-11/hosts/carol/etc/ipsec.secrets | 3 - .../tnc/tnccs-11/hosts/carol/etc/strongswan.conf | 19 +- .../tnccs-11/hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tests/tnc/tnccs-11/hosts/dave/etc/ipsec.conf | 23 - .../tnc/tnccs-11/hosts/dave/etc/ipsec.secrets | 3 - .../tnc/tnccs-11/hosts/dave/etc/strongswan.conf | 19 +- .../tnccs-11/hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tests/tnc/tnccs-11/hosts/moon/etc/ipsec.conf | 34 - .../tnc/tnccs-11/hosts/moon/etc/ipsec.secrets | 6 - .../tnc/tnccs-11/hosts/moon/etc/strongswan.conf | 19 +- .../tnccs-11/hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-11/posttest.dat | 6 +- testing/tests/tnc/tnccs-11/pretest.dat | 14 +- testing/tests/tnc/tnccs-11/test.conf | 4 + testing/tests/tnc/tnccs-20-block/evaltest.dat | 8 +- .../tnc/tnccs-20-block/hosts/carol/etc/ipsec.conf | 23 - .../tnccs-20-block/hosts/carol/etc/ipsec.secrets | 3 - .../tnccs-20-block/hosts/carol/etc/strongswan.conf | 19 +- .../hosts/carol/etc/swanctl/swanctl.conf | 34 + .../tnc/tnccs-20-block/hosts/dave/etc/ipsec.conf | 23 - .../tnccs-20-block/hosts/dave/etc/ipsec.secrets | 3 - .../tnccs-20-block/hosts/dave/etc/strongswan.conf | 19 +- .../hosts/dave/etc/swanctl/swanctl.conf | 34 + .../tnc/tnccs-20-block/hosts/moon/etc/ipsec.conf | 24 - .../tnccs-20-block/hosts/moon/etc/ipsec.secrets | 6 - .../tnccs-20-block/hosts/moon/etc/strongswan.conf | 25 +- .../hosts/moon/etc/swanctl/swanctl.conf | 39 + testing/tests/tnc/tnccs-20-block/posttest.dat | 7 +- testing/tests/tnc/tnccs-20-block/pretest.dat | 15 +- testing/tests/tnc/tnccs-20-block/test.conf | 3 + .../tests/tnc/tnccs-20-client-retry/evaltest.dat | 14 +- .../hosts/carol/etc/ipsec.conf | 23 - .../hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 20 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../hosts/dave/etc/ipsec.conf | 23 - .../hosts/dave/etc/ipsec.secrets | 3 - .../hosts/dave/etc/strongswan.conf | 19 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../hosts/moon/etc/ipsec.conf | 34 - .../hosts/moon/etc/ipsec.secrets | 6 - .../hosts/moon/etc/strongswan.conf | 19 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + .../tests/tnc/tnccs-20-client-retry/posttest.dat | 6 +- .../tests/tnc/tnccs-20-client-retry/pretest.dat | 14 +- testing/tests/tnc/tnccs-20-client-retry/test.conf | 3 + .../tnccs-20-fail-init/hosts/carol/etc/ipsec.conf | 23 - .../hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 19 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnccs-20-fail-init/hosts/dave/etc/ipsec.conf | 23 - .../hosts/dave/etc/ipsec.secrets | 3 - .../hosts/dave/etc/strongswan.conf | 19 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnccs-20-fail-init/hosts/moon/etc/ipsec.conf | 34 - .../hosts/moon/etc/ipsec.secrets | 6 - .../hosts/moon/etc/strongswan.conf | 19 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-20-fail-init/posttest.dat | 6 +- testing/tests/tnc/tnccs-20-fail-init/pretest.dat | 14 +- testing/tests/tnc/tnccs-20-fail-init/test.conf | 3 + .../tnccs-20-fail-resp/hosts/carol/etc/ipsec.conf | 23 - .../hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 20 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnccs-20-fail-resp/hosts/moon/etc/ipsec.conf | 34 - .../hosts/moon/etc/ipsec.secrets | 6 - .../hosts/moon/etc/strongswan.conf | 19 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-20-fail-resp/posttest.dat | 4 +- testing/tests/tnc/tnccs-20-fail-resp/pretest.dat | 8 +- testing/tests/tnc/tnccs-20-fail-resp/test.conf | 3 + testing/tests/tnc/tnccs-20-fhh/evaltest.dat | 17 +- .../tnc/tnccs-20-fhh/hosts/carol/etc/init.d/charon | 158 + .../tnc/tnccs-20-fhh/hosts/carol/etc/ipsec.conf | 23 - .../tnc/tnccs-20-fhh/hosts/carol/etc/ipsec.secrets | 3 - .../tnccs-20-fhh/hosts/carol/etc/strongswan.conf | 20 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-fhh/hosts/dave/etc/init.d/charon | 158 + .../tnc/tnccs-20-fhh/hosts/dave/etc/ipsec.conf | 23 - .../tnc/tnccs-20-fhh/hosts/dave/etc/ipsec.secrets | 3 - .../tnccs-20-fhh/hosts/dave/etc/strongswan.conf | 19 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-fhh/hosts/moon/etc/init.d/charon | 158 + .../tnc/tnccs-20-fhh/hosts/moon/etc/ipsec.conf | 34 - .../tnc/tnccs-20-fhh/hosts/moon/etc/ipsec.secrets | 6 - .../tnccs-20-fhh/hosts/moon/etc/strongswan.conf | 15 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-20-fhh/posttest.dat | 6 +- testing/tests/tnc/tnccs-20-fhh/pretest.dat | 15 +- testing/tests/tnc/tnccs-20-fhh/test.conf | 3 + testing/tests/tnc/tnccs-20-hcd-eap/evaltest.dat | 1 - .../tnccs-20-hcd-eap/hosts/alice/etc/ipsec.conf | 9 - .../hosts/alice/etc/ipsec.d/certs/aaaCert.pem | 25 - .../hosts/alice/etc/ipsec.d/private/aaaKey.pem | 27 - .../tnccs-20-hcd-eap/hosts/alice/etc/ipsec.secrets | 3 - .../hosts/alice/etc/strongswan.conf | 14 +- .../hosts/alice/etc/swanctl/rsa/aaaKey.pem | 27 + .../hosts/alice/etc/swanctl/swanctl.conf | 0 .../hosts/alice/etc/swanctl/x509/aaaCert.pem | 25 + .../tnccs-20-hcd-eap/hosts/carol/etc/ipsec.conf | 24 - .../hosts/carol/etc/strongswan.conf | 19 +- .../hosts/carol/etc/swanctl/swanctl.conf | 27 + .../tnc/tnccs-20-hcd-eap/hosts/dave/etc/ipsec.conf | 24 - .../hosts/dave/etc/strongswan.conf | 19 +- .../hosts/dave/etc/swanctl/swanctl.conf | 27 + .../tnc/tnccs-20-hcd-eap/hosts/moon/etc/ipsec.conf | 33 - .../tnccs-20-hcd-eap/hosts/moon/etc/ipsec.secrets | 3 - .../hosts/moon/etc/strongswan.conf | 7 +- .../hosts/moon/etc/swanctl/swanctl.conf | 53 + testing/tests/tnc/tnccs-20-hcd-eap/posttest.dat | 10 +- testing/tests/tnc/tnccs-20-hcd-eap/pretest.dat | 14 +- testing/tests/tnc/tnccs-20-hcd-eap/test.conf | 3 + .../tnc/tnccs-20-mutual-eap-fail/description.txt | 5 + .../tnc/tnccs-20-mutual-eap-fail/evaltest.dat | 7 + .../hosts/moon/etc/strongswan.conf | 45 + .../hosts/moon/etc/swanctl/swanctl.conf | 28 + .../hosts/moon/etc/tnc_config | 4 + .../hosts/sun/etc/strongswan.conf | 47 + .../hosts/sun/etc/swanctl/swanctl.conf | 28 + .../hosts/sun/etc/tnc_config | 4 + .../tnc/tnccs-20-mutual-eap-fail/posttest.dat | 4 + .../tests/tnc/tnccs-20-mutual-eap-fail/pretest.dat | 6 + .../tests/tnc/tnccs-20-mutual-eap-fail/test.conf | 25 + .../tests/tnc/tnccs-20-mutual-eap/description.txt | 5 +- testing/tests/tnc/tnccs-20-mutual-eap/evaltest.dat | 12 +- .../tnccs-20-mutual-eap/hosts/moon/etc/ipsec.conf | 23 - .../hosts/moon/etc/strongswan.conf | 23 +- .../hosts/moon/etc/swanctl/swanctl.conf | 28 + .../tnccs-20-mutual-eap/hosts/sun/etc/ipsec.conf | 23 - .../hosts/sun/etc/strongswan.conf | 23 +- .../hosts/sun/etc/swanctl/swanctl.conf | 28 + testing/tests/tnc/tnccs-20-mutual-eap/posttest.dat | 4 +- testing/tests/tnc/tnccs-20-mutual-eap/pretest.dat | 8 +- testing/tests/tnc/tnccs-20-mutual-eap/test.conf | 4 + .../hosts/moon/etc/ipsec.conf | 3 - .../hosts/moon/etc/pts/options | 6 +- .../hosts/moon/etc/strongswan.conf | 6 +- .../hosts/moon/etc/swanctl/swanctl.conf | 1 + .../hosts/sun/etc/ipsec.conf | 9 - .../hosts/sun/etc/strongswan.conf | 19 +- .../hosts/sun/etc/swantcl/swanctl.conf | 0 .../tests/tnc/tnccs-20-mutual-pt-tls/posttest.dat | 2 +- .../tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat | 4 +- testing/tests/tnc/tnccs-20-mutual-pt-tls/test.conf | 4 + testing/tests/tnc/tnccs-20-os-pts/evaltest.dat | 8 +- .../tnc/tnccs-20-os-pts/hosts/carol/etc/ipsec.conf | 23 - .../tnccs-20-os-pts/hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 21 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-os-pts/hosts/dave/etc/ipsec.conf | 23 - .../tnccs-20-os-pts/hosts/dave/etc/ipsec.secrets | 3 - .../tnccs-20-os-pts/hosts/dave/etc/strongswan.conf | 21 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-os-pts/hosts/moon/etc/ipsec.conf | 34 - .../tnccs-20-os-pts/hosts/moon/etc/ipsec.secrets | 6 - .../tnccs-20-os-pts/hosts/moon/etc/strongswan.conf | 20 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-20-os-pts/posttest.dat | 6 +- testing/tests/tnc/tnccs-20-os-pts/pretest.dat | 16 +- testing/tests/tnc/tnccs-20-os-pts/test.conf | 4 + testing/tests/tnc/tnccs-20-os/evaltest.dat | 8 +- .../tnc/tnccs-20-os/hosts/carol/etc/ipsec.conf | 23 - .../tnc/tnccs-20-os/hosts/carol/etc/ipsec.secrets | 3 - .../tnccs-20-os/hosts/carol/etc/strongswan.conf | 20 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-os/hosts/dave/etc/ipsec.conf | 23 - .../tnc/tnccs-20-os/hosts/dave/etc/ipsec.secrets | 3 - .../tnc/tnccs-20-os/hosts/dave/etc/strongswan.conf | 19 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-os/hosts/moon/etc/ipsec.conf | 34 - .../tnc/tnccs-20-os/hosts/moon/etc/ipsec.secrets | 6 - .../tnc/tnccs-20-os/hosts/moon/etc/strongswan.conf | 19 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-20-os/posttest.dat | 6 +- testing/tests/tnc/tnccs-20-os/pretest.dat | 19 +- testing/tests/tnc/tnccs-20-os/test.conf | 6 +- testing/tests/tnc/tnccs-20-pdp-eap/evaltest.dat | 8 +- .../tnccs-20-pdp-eap/hosts/alice/etc/ipsec.conf | 9 - .../hosts/alice/etc/ipsec.d/certs/aaaCert.pem | 25 - .../hosts/alice/etc/ipsec.d/private/aaaKey.pem | 27 - .../tnccs-20-pdp-eap/hosts/alice/etc/ipsec.secrets | 6 - .../hosts/alice/etc/strongswan.conf | 14 +- .../hosts/alice/etc/swanctl/rsa/aaaKey.pem | 27 + .../hosts/alice/etc/swanctl/swanctl.conf | 11 + .../hosts/alice/etc/swanctl/x509/aaaCert.pem | 25 + .../tnccs-20-pdp-eap/hosts/carol/etc/ipsec.conf | 23 - .../tnccs-20-pdp-eap/hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 21 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-pdp-eap/hosts/dave/etc/ipsec.conf | 23 - .../tnccs-20-pdp-eap/hosts/dave/etc/ipsec.secrets | 3 - .../hosts/dave/etc/strongswan.conf | 21 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-pdp-eap/hosts/moon/etc/ipsec.conf | 33 - .../tnccs-20-pdp-eap/hosts/moon/etc/ipsec.secrets | 3 - .../hosts/moon/etc/strongswan.conf | 8 +- .../hosts/moon/etc/swanctl/swanctl.conf | 53 + testing/tests/tnc/tnccs-20-pdp-eap/posttest.dat | 10 +- testing/tests/tnc/tnccs-20-pdp-eap/pretest.dat | 18 +- testing/tests/tnc/tnccs-20-pdp-eap/test.conf | 3 + .../tnccs-20-pdp-pt-tls/hosts/alice/etc/ipsec.conf | 9 - .../hosts/alice/etc/ipsec.d/certs/aaaCert.pem | 25 - .../hosts/alice/etc/ipsec.d/private/aaaKey.pem | 27 - .../hosts/alice/etc/ipsec.secrets | 6 - .../hosts/alice/etc/strongswan.conf | 15 +- .../hosts/alice/etc/swanctl/rsa/aaaKey.pem | 27 + .../hosts/alice/etc/swanctl/swanctl.conf | 7 + .../hosts/alice/etc/swanctl/x509/aaaCert.pem | 25 + .../tnccs-20-pdp-pt-tls/hosts/carol/etc/ipsec.conf | 3 - .../hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/pts/options | 2 +- .../hosts/carol/etc/swanctl/swanctl.conf | 1 + .../tnccs-20-pdp-pt-tls/hosts/dave/etc/ipsec.conf | 3 - .../hosts/dave/etc/ipsec.secrets | 3 - .../tnccs-20-pdp-pt-tls/hosts/dave/etc/pts/options | 6 +- .../hosts/dave/etc/swanctl/swanctl.conf | 1 + .../tnccs-20-pdp-pt-tls/hosts/moon/etc/ipsec.conf | 3 - .../hosts/moon/etc/ipsec.secrets | 3 - .../hosts/moon/etc/swanctl/swanctl.conf | 1 + testing/tests/tnc/tnccs-20-pdp-pt-tls/posttest.dat | 4 +- testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat | 4 +- testing/tests/tnc/tnccs-20-pdp-pt-tls/test.conf | 4 + testing/tests/tnc/tnccs-20-pts-no-ecc/evaltest.dat | 8 +- .../tnccs-20-pts-no-ecc/hosts/carol/etc/ipsec.conf | 23 - .../hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 21 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnccs-20-pts-no-ecc/hosts/dave/etc/ipsec.conf | 23 - .../hosts/dave/etc/ipsec.secrets | 3 - .../hosts/dave/etc/strongswan.conf | 22 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnccs-20-pts-no-ecc/hosts/moon/etc/ipsec.conf | 34 - .../hosts/moon/etc/ipsec.secrets | 6 - .../hosts/moon/etc/strongswan.conf | 20 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-20-pts-no-ecc/posttest.dat | 6 +- testing/tests/tnc/tnccs-20-pts-no-ecc/pretest.dat | 14 +- testing/tests/tnc/tnccs-20-pts-no-ecc/test.conf | 3 + testing/tests/tnc/tnccs-20-pts/evaltest.dat | 8 +- .../hosts/carol/etc/.strongswan.conf.swp | Bin 0 -> 12288 bytes .../tnc/tnccs-20-pts/hosts/carol/etc/ipsec.conf | 23 - .../tnc/tnccs-20-pts/hosts/carol/etc/ipsec.secrets | 3 - .../tnccs-20-pts/hosts/carol/etc/strongswan.conf | 21 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-pts/hosts/dave/etc/ipsec.conf | 23 - .../tnc/tnccs-20-pts/hosts/dave/etc/ipsec.secrets | 3 - .../tnccs-20-pts/hosts/dave/etc/strongswan.conf | 23 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-20-pts/hosts/moon/etc/ipsec.conf | 34 - .../tnc/tnccs-20-pts/hosts/moon/etc/ipsec.secrets | 6 - .../tnccs-20-pts/hosts/moon/etc/strongswan.conf | 22 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-20-pts/posttest.dat | 6 +- testing/tests/tnc/tnccs-20-pts/pretest.dat | 14 +- testing/tests/tnc/tnccs-20-pts/test.conf | 3 + .../tests/tnc/tnccs-20-server-retry/evaltest.dat | 13 +- .../hosts/carol/etc/ipsec.conf | 23 - .../hosts/carol/etc/ipsec.secrets | 3 - .../hosts/carol/etc/strongswan.conf | 20 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../hosts/dave/etc/ipsec.conf | 23 - .../hosts/dave/etc/ipsec.secrets | 3 - .../hosts/dave/etc/strongswan.conf | 19 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../hosts/moon/etc/ipsec.conf | 34 - .../hosts/moon/etc/ipsec.secrets | 6 - .../hosts/moon/etc/strongswan.conf | 19 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + .../tests/tnc/tnccs-20-server-retry/posttest.dat | 6 +- .../tests/tnc/tnccs-20-server-retry/pretest.dat | 14 +- testing/tests/tnc/tnccs-20-server-retry/test.conf | 3 + testing/tests/tnc/tnccs-20-tls/evaltest.dat | 13 +- .../tnc/tnccs-20-tls/hosts/carol/etc/ipsec.conf | 23 - .../tnccs-20-tls/hosts/carol/etc/strongswan.conf | 20 +- .../hosts/carol/etc/swanctl/swanctl.conf | 27 + .../tnc/tnccs-20-tls/hosts/dave/etc/ipsec.conf | 23 - .../tnccs-20-tls/hosts/dave/etc/strongswan.conf | 20 +- .../hosts/dave/etc/swanctl/swanctl.conf | 27 + .../tnc/tnccs-20-tls/hosts/moon/etc/ipsec.conf | 34 - .../tnc/tnccs-20-tls/hosts/moon/etc/ipsec.secrets | 6 - .../tnccs-20-tls/hosts/moon/etc/strongswan.conf | 19 +- .../hosts/moon/etc/swanctl/swanctl.conf | 50 + testing/tests/tnc/tnccs-20-tls/posttest.dat | 6 +- testing/tests/tnc/tnccs-20-tls/pretest.dat | 10 +- testing/tests/tnc/tnccs-20-tls/test.conf | 3 + testing/tests/tnc/tnccs-20/evaltest.dat | 13 +- .../tests/tnc/tnccs-20/hosts/carol/etc/ipsec.conf | 23 - .../tnc/tnccs-20/hosts/carol/etc/ipsec.secrets | 3 - .../tnc/tnccs-20/hosts/carol/etc/strongswan.conf | 20 +- .../tnccs-20/hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tests/tnc/tnccs-20/hosts/dave/etc/ipsec.conf | 23 - .../tnc/tnccs-20/hosts/dave/etc/ipsec.secrets | 3 - .../tnc/tnccs-20/hosts/dave/etc/strongswan.conf | 19 +- .../tnccs-20/hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tests/tnc/tnccs-20/hosts/moon/etc/ipsec.conf | 34 - .../tnc/tnccs-20/hosts/moon/etc/ipsec.secrets | 6 - .../tnc/tnccs-20/hosts/moon/etc/strongswan.conf | 19 +- .../tnccs-20/hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-20/posttest.dat | 6 +- testing/tests/tnc/tnccs-20/pretest.dat | 14 +- testing/tests/tnc/tnccs-20/test.conf | 3 + testing/tests/tnc/tnccs-dynamic/evaltest.dat | 13 +- .../tnc/tnccs-dynamic/hosts/carol/etc/ipsec.conf | 23 - .../tnccs-dynamic/hosts/carol/etc/ipsec.secrets | 3 - .../tnccs-dynamic/hosts/carol/etc/strongswan.conf | 19 +- .../hosts/carol/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-dynamic/hosts/dave/etc/ipsec.conf | 23 - .../tnc/tnccs-dynamic/hosts/dave/etc/ipsec.secrets | 3 - .../tnccs-dynamic/hosts/dave/etc/strongswan.conf | 19 +- .../hosts/dave/etc/swanctl/swanctl.conf | 35 + .../tnc/tnccs-dynamic/hosts/moon/etc/ipsec.conf | 34 - .../tnc/tnccs-dynamic/hosts/moon/etc/ipsec.secrets | 6 - .../tnccs-dynamic/hosts/moon/etc/strongswan.conf | 20 +- .../hosts/moon/etc/swanctl/swanctl.conf | 64 + testing/tests/tnc/tnccs-dynamic/posttest.dat | 6 +- testing/tests/tnc/tnccs-dynamic/pretest.dat | 14 +- testing/tests/tnc/tnccs-dynamic/test.conf | 3 + 1561 files changed, 40340 insertions(+), 27642 deletions(-) create mode 100644 conf/plugins/p-cscf.conf create mode 100644 conf/plugins/p-cscf.opt create mode 100644 src/libcharon/bus/listeners/custom_logger.h create mode 100644 src/libcharon/kernel/kernel_interface.c create mode 100644 src/libcharon/kernel/kernel_interface.h create mode 100644 src/libcharon/kernel/kernel_ipsec.c create mode 100644 src/libcharon/kernel/kernel_ipsec.h create mode 100644 src/libcharon/kernel/kernel_listener.h create mode 100644 src/libcharon/kernel/kernel_net.c create mode 100644 src/libcharon/kernel/kernel_net.h create mode 100644 src/libcharon/plugins/kernel_netlink/Makefile.am create mode 100644 src/libcharon/plugins/kernel_netlink/Makefile.in create mode 100644 src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c create mode 100644 src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h create mode 100644 src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c create mode 100644 src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h create mode 100644 src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c create mode 100644 src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h create mode 100644 src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c create mode 100644 src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h create mode 100644 src/libcharon/plugins/kernel_netlink/suites/test_socket.c create mode 100644 src/libcharon/plugins/kernel_netlink/tests.c create mode 100644 src/libcharon/plugins/kernel_netlink/tests.h create mode 100644 src/libcharon/plugins/kernel_pfkey/Makefile.am create mode 100644 src/libcharon/plugins/kernel_pfkey/Makefile.in create mode 100644 src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c create mode 100644 src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h create mode 100644 src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c create mode 100644 src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h create mode 100644 src/libcharon/plugins/kernel_pfroute/Makefile.am create mode 100644 src/libcharon/plugins/kernel_pfroute/Makefile.in create mode 100644 src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c create mode 100644 src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h create mode 100644 src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c create mode 100644 src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h create mode 100644 src/libcharon/plugins/p_cscf/Makefile.am create mode 100644 src/libcharon/plugins/p_cscf/Makefile.in create mode 100644 src/libcharon/plugins/p_cscf/p_cscf_handler.c create mode 100644 src/libcharon/plugins/p_cscf/p_cscf_handler.h create mode 100644 src/libcharon/plugins/p_cscf/p_cscf_plugin.c create mode 100644 src/libcharon/plugins/p_cscf/p_cscf_plugin.h create mode 100644 src/libcharon/plugins/vici/perl/Makefile.am create mode 100644 src/libcharon/plugins/vici/perl/Makefile.in create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/Changes create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/MANIFEST create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/Makefile.PL create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/README.pod create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/lib/Vici/Message.pm create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/lib/Vici/Packet.pm create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/lib/Vici/Session.pm create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/lib/Vici/Transport.pm create mode 100644 src/libcharon/plugins/vici/perl/Vici-Session/t/Vici-Session.t create mode 100644 src/libcharon/plugins/vici/vici_cert_info.c create mode 100644 src/libcharon/plugins/vici/vici_cert_info.h create mode 100644 src/libcharon/processing/jobs/redirect_job.c create mode 100644 src/libcharon/processing/jobs/redirect_job.h create mode 100644 src/libcharon/sa/ikev2/tasks/ike_redirect.c create mode 100644 src/libcharon/sa/ikev2/tasks/ike_redirect.h create mode 100644 src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.c create mode 100644 src/libcharon/sa/ikev2/tasks/ike_verify_peer_cert.h create mode 100644 src/libcharon/sa/redirect_manager.c create mode 100644 src/libcharon/sa/redirect_manager.h create mode 100644 src/libcharon/sa/redirect_provider.h delete mode 100644 src/libhydra/Android.mk delete mode 100644 src/libhydra/Makefile.am delete mode 100644 src/libhydra/Makefile.in delete mode 100644 src/libhydra/hydra.c delete mode 100644 src/libhydra/hydra.h delete mode 100644 src/libhydra/kernel/kernel_interface.c delete mode 100644 src/libhydra/kernel/kernel_interface.h delete mode 100644 src/libhydra/kernel/kernel_ipsec.c delete mode 100644 src/libhydra/kernel/kernel_ipsec.h delete mode 100644 src/libhydra/kernel/kernel_listener.h delete mode 100644 src/libhydra/kernel/kernel_net.c delete mode 100644 src/libhydra/kernel/kernel_net.h delete mode 100644 src/libhydra/plugins/kernel_netlink/Makefile.am delete mode 100644 src/libhydra/plugins/kernel_netlink/Makefile.in delete mode 100644 src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c delete mode 100644 src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.h delete mode 100644 src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c delete mode 100644 src/libhydra/plugins/kernel_netlink/kernel_netlink_net.h delete mode 100644 src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.c delete mode 100644 src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.h delete mode 100644 src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c delete mode 100644 src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h delete mode 100644 src/libhydra/plugins/kernel_netlink/suites/test_socket.c delete mode 100644 src/libhydra/plugins/kernel_netlink/tests.c delete mode 100644 src/libhydra/plugins/kernel_netlink/tests.h delete mode 100644 src/libhydra/plugins/kernel_pfkey/Makefile.am delete mode 100644 src/libhydra/plugins/kernel_pfkey/Makefile.in delete mode 100644 src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c delete mode 100644 src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.h delete mode 100644 src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c delete mode 100644 src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.h delete mode 100644 src/libhydra/plugins/kernel_pfroute/Makefile.am delete mode 100644 src/libhydra/plugins/kernel_pfroute/Makefile.in delete mode 100644 src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c delete mode 100644 src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.h delete mode 100644 src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.c delete mode 100644 src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.h delete mode 100644 src/libhydra/tests/Makefile.am delete mode 100644 src/libhydra/tests/Makefile.in delete mode 100644 src/libhydra/tests/hydra_tests.c delete mode 100644 src/libhydra/tests/hydra_tests.h create mode 100644 src/libstrongswan/credentials/certificates/certificate_printer.c create mode 100644 src/libstrongswan/credentials/certificates/certificate_printer.h create mode 100644 src/libstrongswan/credentials/certificates/x509.c create mode 100644 src/libstrongswan/tests/suites/test_auth_cfg.c create mode 100644 src/swanctl/commands/list_algs.c create mode 100644 src/swanctl/commands/redirect.c delete mode 100644 testing/tests/af-alg/alg-camellia/hosts/carol/etc/ipsec.conf create mode 100755 testing/tests/af-alg/alg-camellia/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/af-alg/alg-camellia/hosts/moon/etc/ipsec.conf create mode 100755 testing/tests/af-alg/alg-camellia/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/af-alg/rw-cert/hosts/carol/etc/ipsec.conf create mode 100755 testing/tests/af-alg/rw-cert/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/af-alg/rw-cert/hosts/dave/etc/ipsec.conf create mode 100755 testing/tests/af-alg/rw-cert/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/af-alg/rw-cert/hosts/moon/etc/ipsec.conf create mode 100755 testing/tests/af-alg/rw-cert/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/description.txt create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/evaltest.dat create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/ipsec.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/hosts/carol/etc/strongswan.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/ipsec.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/hosts/moon/etc/strongswan.conf create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/posttest.dat create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/pretest.dat create mode 100644 testing/tests/ikev2/reauth-mbb-revoked/test.conf create mode 100644 testing/tests/ikev2/redirect-active/description.txt create mode 100644 testing/tests/ikev2/redirect-active/evaltest.dat create mode 100644 testing/tests/ikev2/redirect-active/hosts/alice/etc/ipsec.conf create mode 100644 testing/tests/ikev2/redirect-active/hosts/alice/etc/ipsec.d/certs/marsCert.pem create mode 100644 testing/tests/ikev2/redirect-active/hosts/alice/etc/ipsec.d/private/marsKey.pem create mode 100644 testing/tests/ikev2/redirect-active/hosts/alice/etc/ipsec.secrets create mode 100644 testing/tests/ikev2/redirect-active/hosts/alice/etc/iptables.rules create mode 100644 testing/tests/ikev2/redirect-active/hosts/alice/etc/strongswan.conf create mode 100644 testing/tests/ikev2/redirect-active/hosts/carol/etc/ipsec.conf create mode 100644 testing/tests/ikev2/redirect-active/hosts/carol/etc/strongswan.conf create mode 100644 testing/tests/ikev2/redirect-active/hosts/dave/etc/ipsec.conf create mode 100644 testing/tests/ikev2/redirect-active/hosts/dave/etc/strongswan.conf create mode 100644 testing/tests/ikev2/redirect-active/hosts/moon/etc/ipsec.conf create mode 100644 testing/tests/ikev2/redirect-active/hosts/moon/etc/ipsec.d/certs/marsCert.pem create mode 100644 testing/tests/ikev2/redirect-active/hosts/moon/etc/ipsec.d/private/marsKey.pem create mode 100644 testing/tests/ikev2/redirect-active/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/ikev2/redirect-active/hosts/moon/etc/strongswan.conf create mode 100644 testing/tests/ikev2/redirect-active/posttest.dat create mode 100644 testing/tests/ikev2/redirect-active/pretest.dat create mode 100644 testing/tests/ikev2/redirect-active/test.conf create mode 100644 testing/tests/sql/ip-pool-db-expired/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-pool-db-expired/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-pool-db-expired/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-pool-db-restart/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-pool-db-restart/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-pool-db-restart/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-pool-db/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-pool-db/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-pool-db/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-split-pools-db-restart/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-split-pools-db-restart/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-split-pools-db-restart/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-split-pools-db/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-split-pools-db/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/ip-split-pools-db/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/multi-level-ca/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/multi-level-ca/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/multi-level-ca/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/net2net-cert/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/net2net-cert/hosts/sun/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/net2net-psk/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/net2net-psk/hosts/sun/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/net2net-route-pem/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/net2net-route-pem/hosts/sun/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/net2net-start-pem/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/net2net-start-pem/hosts/sun/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-cert/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-cert/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-cert/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-eap-aka-rsa/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-eap-aka-rsa/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-ipv4/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-ipv4/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-ipv4/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-ipv6/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-ipv6/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-ipv6/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-rsa-split/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-rsa-split/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-psk-rsa-split/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-rsa-keyid/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-rsa-keyid/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-rsa-keyid/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-rsa/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-rsa/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/sql/rw-rsa/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/alice/etc/ipsec.conf delete mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/alice/etc/ipsec.secrets create mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/alice/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/sun/etc/ipsec.conf delete mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/sun/etc/ipsec.secrets create mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/sun/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/venus/etc/ipsec.conf delete mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/venus/etc/ipsec.secrets create mode 100644 testing/tests/sql/shunt-policies-nat-rw/hosts/venus/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/config-payload/description.txt create mode 100755 testing/tests/swanctl/config-payload/evaltest.dat create mode 100755 testing/tests/swanctl/config-payload/hosts/carol/etc/strongswan.conf create mode 100755 testing/tests/swanctl/config-payload/hosts/carol/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/config-payload/hosts/dave/etc/strongswan.conf create mode 100755 testing/tests/swanctl/config-payload/hosts/dave/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/config-payload/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/swanctl/config-payload/hosts/moon/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/config-payload/hosts/moon/etc/swanctl/swanctl_base.conf create mode 100755 testing/tests/swanctl/config-payload/posttest.dat create mode 100755 testing/tests/swanctl/config-payload/pretest.dat create mode 100755 testing/tests/swanctl/config-payload/test.conf create mode 100644 testing/tests/swanctl/dhcp-dynamic/description.txt create mode 100644 testing/tests/swanctl/dhcp-dynamic/evaltest.dat create mode 100755 testing/tests/swanctl/dhcp-dynamic/hosts/carol/etc/strongswan.conf create mode 100755 testing/tests/swanctl/dhcp-dynamic/hosts/carol/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/dhcp-dynamic/hosts/dave/etc/strongswan.conf create mode 100755 testing/tests/swanctl/dhcp-dynamic/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/dhcp-dynamic/hosts/moon/etc/dhcpd.conf create mode 100644 testing/tests/swanctl/dhcp-dynamic/hosts/moon/etc/iptables.rules create mode 100755 testing/tests/swanctl/dhcp-dynamic/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/swanctl/dhcp-dynamic/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/dhcp-dynamic/hosts/venus/etc/dhcp/dhcpd.conf create mode 100644 testing/tests/swanctl/dhcp-dynamic/hosts/venus/etc/dnsmasq.conf create mode 100644 testing/tests/swanctl/dhcp-dynamic/posttest.dat create mode 100644 testing/tests/swanctl/dhcp-dynamic/pretest.dat create mode 100644 testing/tests/swanctl/dhcp-dynamic/test.conf create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/description.txt create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/evaltest.dat create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/alice/etc/freeradius/eap.conf create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/alice/etc/freeradius/modules/sim_files create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/alice/etc/freeradius/proxy.conf create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/alice/etc/freeradius/sites-available/default create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/alice/etc/freeradius/triplets.dat create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/alice/etc/freeradius/users create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.d/triplets.dat create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/carol/etc/strongswan.conf create mode 100755 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.d/triplets.dat create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/dave/etc/strongswan.conf create mode 100755 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/moon/etc/iptables.rules create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/posttest.dat create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/pretest.dat create mode 100644 testing/tests/swanctl/mult-auth-rsa-eap-sim-id/test.conf create mode 100644 testing/tests/swanctl/net2net-pubkey/description.txt create mode 100644 testing/tests/swanctl/net2net-pubkey/evaltest.dat create mode 100644 testing/tests/swanctl/net2net-pubkey/hosts/moon/etc/strongswan.conf create mode 100644 testing/tests/swanctl/net2net-pubkey/hosts/moon/etc/swanctl/pubkey/moonPub.pem create mode 100644 testing/tests/swanctl/net2net-pubkey/hosts/moon/etc/swanctl/pubkey/sunPub.pem create mode 100755 testing/tests/swanctl/net2net-pubkey/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/net2net-pubkey/hosts/sun/etc/strongswan.conf create mode 100644 testing/tests/swanctl/net2net-pubkey/hosts/sun/etc/swanctl/pubkey/moonPub.pem create mode 100644 testing/tests/swanctl/net2net-pubkey/hosts/sun/etc/swanctl/pubkey/sunPub.pem create mode 100755 testing/tests/swanctl/net2net-pubkey/hosts/sun/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/net2net-pubkey/posttest.dat create mode 100644 testing/tests/swanctl/net2net-pubkey/pretest.dat create mode 100644 testing/tests/swanctl/net2net-pubkey/test.conf create mode 100644 testing/tests/swanctl/protoport-dual/description.txt create mode 100644 testing/tests/swanctl/protoport-dual/evaltest.dat create mode 100644 testing/tests/swanctl/protoport-dual/hosts/carol/etc/strongswan.conf create mode 100755 testing/tests/swanctl/protoport-dual/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/protoport-dual/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/swanctl/protoport-dual/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/protoport-dual/posttest.dat create mode 100644 testing/tests/swanctl/protoport-dual/pretest.dat create mode 100644 testing/tests/swanctl/protoport-dual/test.conf create mode 100644 testing/tests/swanctl/protoport-range/description.txt create mode 100644 testing/tests/swanctl/protoport-range/evaltest.dat create mode 100644 testing/tests/swanctl/protoport-range/hosts/carol/etc/strongswan.conf create mode 100755 testing/tests/swanctl/protoport-range/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/protoport-range/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/swanctl/protoport-range/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/protoport-range/posttest.dat create mode 100644 testing/tests/swanctl/protoport-range/pretest.dat create mode 100644 testing/tests/swanctl/protoport-range/test.conf create mode 100644 testing/tests/swanctl/rw-cert/hosts/carol/etc/swanctl/rsa/carolKey.pem create mode 100644 testing/tests/swanctl/rw-dnssec/description.txt create mode 100644 testing/tests/swanctl/rw-dnssec/evaltest.dat create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/carol/etc/iptables.rules create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/carol/etc/resolv.conf create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/carol/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/carol/etc/swanctl/dnssec.keys create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/carol/etc/swanctl/pubkey/carolPub.der create mode 100755 testing/tests/swanctl/rw-dnssec/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/dave/etc/iptables.rules create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/dave/etc/resolv.conf create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/dave/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/dave/etc/swanctl/dnssec.keys create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/dave/etc/swanctl/pubkey/davePub.der create mode 100755 testing/tests/swanctl/rw-dnssec/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/moon/etc/iptables.rules create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/moon/etc/resolv.conf create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/moon/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/moon/etc/swanctl/dnssec.keys create mode 100644 testing/tests/swanctl/rw-dnssec/hosts/moon/etc/swanctl/pubkey/moonPub.der create mode 100755 testing/tests/swanctl/rw-dnssec/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/rw-dnssec/posttest.dat create mode 100644 testing/tests/swanctl/rw-dnssec/pretest.dat create mode 100644 testing/tests/swanctl/rw-dnssec/test.conf create mode 100644 testing/tests/swanctl/rw-ntru-bliss/description.txt create mode 100644 testing/tests/swanctl/rw-ntru-bliss/evaltest.dat create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/carol/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/carol/etc/swanctl/bliss/carolKey.der create mode 100755 testing/tests/swanctl/rw-ntru-bliss/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/carol/etc/swanctl/x509/carolCert.der create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/carol/etc/swanctl/x509ca/strongswan_blissCert.der create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/dave/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/dave/etc/swanctl/bliss/daveKey.der create mode 100755 testing/tests/swanctl/rw-ntru-bliss/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/dave/etc/swanctl/x509/daveCert.der create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/dave/etc/swanctl/x509ca/strongswan_blissCert.der create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/moon/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/moon/etc/swanctl/bliss/moonKey.der create mode 100755 testing/tests/swanctl/rw-ntru-bliss/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/moon/etc/swanctl/x509/moonCert.der create mode 100644 testing/tests/swanctl/rw-ntru-bliss/hosts/moon/etc/swanctl/x509ca/strongswan_blissCert.der create mode 100644 testing/tests/swanctl/rw-ntru-bliss/posttest.dat create mode 100644 testing/tests/swanctl/rw-ntru-bliss/pretest.dat create mode 100644 testing/tests/swanctl/rw-ntru-bliss/test.conf create mode 100755 testing/tests/swanctl/rw-psk-ikev1/description.txt create mode 100755 testing/tests/swanctl/rw-psk-ikev1/evaltest.dat create mode 100755 testing/tests/swanctl/rw-psk-ikev1/hosts/carol/etc/strongswan.conf create mode 100755 testing/tests/swanctl/rw-psk-ikev1/hosts/carol/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-psk-ikev1/hosts/dave/etc/strongswan.conf create mode 100755 testing/tests/swanctl/rw-psk-ikev1/hosts/dave/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-psk-ikev1/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/swanctl/rw-psk-ikev1/hosts/moon/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-psk-ikev1/posttest.dat create mode 100755 testing/tests/swanctl/rw-psk-ikev1/pretest.dat create mode 100755 testing/tests/swanctl/rw-psk-ikev1/test.conf create mode 100755 testing/tests/swanctl/rw-pubkey-anon/description.txt create mode 100755 testing/tests/swanctl/rw-pubkey-anon/evaltest.dat create mode 100755 testing/tests/swanctl/rw-pubkey-anon/hosts/carol/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/carol/etc/swanctl/pubkey/carolPub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/carol/etc/swanctl/pubkey/moonPub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/carol/etc/swanctl/rsa/carolKey.pem create mode 100755 testing/tests/swanctl/rw-pubkey-anon/hosts/carol/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-pubkey-anon/hosts/dave/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/dave/etc/swanctl/pubkey/davePub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/dave/etc/swanctl/pubkey/moonPub.pem create mode 100755 testing/tests/swanctl/rw-pubkey-anon/hosts/dave/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-pubkey-anon/hosts/moon/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/moon/etc/swanctl/pubkey/carolPub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/moon/etc/swanctl/pubkey/davePub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/moon/etc/swanctl/pubkey/moonPub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-anon/hosts/moon/etc/swanctl/pubkey/sunPub.pem create mode 100755 testing/tests/swanctl/rw-pubkey-anon/hosts/moon/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-pubkey-anon/posttest.dat create mode 100755 testing/tests/swanctl/rw-pubkey-anon/pretest.dat create mode 100755 testing/tests/swanctl/rw-pubkey-anon/test.conf create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/description.txt create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/evaltest.dat create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/hosts/carol/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-pubkey-keyid/hosts/carol/etc/swanctl/pubkey/carolPub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-keyid/hosts/carol/etc/swanctl/pubkey/moonPub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-keyid/hosts/carol/etc/swanctl/rsa/carolKey.pem create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/hosts/carol/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/hosts/dave/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-pubkey-keyid/hosts/dave/etc/swanctl/pubkey/davePub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-keyid/hosts/dave/etc/swanctl/pubkey/moonPub.pem create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/hosts/dave/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/hosts/moon/etc/strongswan.conf create mode 100644 testing/tests/swanctl/rw-pubkey-keyid/hosts/moon/etc/swanctl/pubkey/carolPub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-keyid/hosts/moon/etc/swanctl/pubkey/davePub.pem create mode 100644 testing/tests/swanctl/rw-pubkey-keyid/hosts/moon/etc/swanctl/pubkey/moonPub.pem create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/hosts/moon/etc/swanctl/swanctl.conf create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/hosts/moon/etc/swanctl/swanctl_base.conf create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/posttest.dat create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/pretest.dat create mode 100755 testing/tests/swanctl/rw-pubkey-keyid/test.conf create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/description.txt create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/evaltest.dat create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/hosts/alice/etc/strongswan.conf create mode 100755 testing/tests/swanctl/shunt-policies-nat-rw/hosts/alice/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/hosts/sun/etc/iptables.rules create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/hosts/sun/etc/strongswan.conf create mode 100755 testing/tests/swanctl/shunt-policies-nat-rw/hosts/sun/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/hosts/venus/etc/strongswan.conf create mode 100755 testing/tests/swanctl/shunt-policies-nat-rw/hosts/venus/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/posttest.dat create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/pretest.dat create mode 100644 testing/tests/swanctl/shunt-policies-nat-rw/test.conf create mode 100644 testing/tests/swanctl/xauth-rsa/description.txt create mode 100644 testing/tests/swanctl/xauth-rsa/evaltest.dat create mode 100644 testing/tests/swanctl/xauth-rsa/hosts/carol/etc/strongswan.conf create mode 100755 testing/tests/swanctl/xauth-rsa/hosts/carol/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/xauth-rsa/hosts/dave/etc/strongswan.conf create mode 100755 testing/tests/swanctl/xauth-rsa/hosts/dave/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/xauth-rsa/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/swanctl/xauth-rsa/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/swanctl/xauth-rsa/posttest.dat create mode 100644 testing/tests/swanctl/xauth-rsa/pretest.dat create mode 100644 testing/tests/swanctl/xauth-rsa/test.conf create mode 100755 testing/tests/tnc/tnccs-11-fhh/hosts/carol/etc/init.d/charon delete mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/carol/etc/swanctl/swanctl.conf create mode 100755 testing/tests/tnc/tnccs-11-fhh/hosts/dave/etc/init.d/charon delete mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/dave/etc/swanctl/swanctl.conf create mode 100755 testing/tests/tnc/tnccs-11-fhh/hosts/moon/etc/init.d/charon delete mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-fhh/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius-block/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius-pts/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-radius/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/moon/etc/ipsec.secrets delete mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/moon/etc/iptables.rules delete mode 100644 testing/tests/tnc/tnccs-11-supplicant/hosts/moon/etc/strongswan.conf delete mode 100644 testing/tests/tnc/tnccs-11/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-11/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-11/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-11/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-block/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-block/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-block/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-block/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-block/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-block/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-block/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-block/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-block/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-client-retry/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/swanctl/swanctl.conf create mode 100755 testing/tests/tnc/tnccs-20-fhh/hosts/carol/etc/init.d/charon delete mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/carol/etc/swanctl/swanctl.conf create mode 100755 testing/tests/tnc/tnccs-20-fhh/hosts/dave/etc/init.d/charon delete mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/dave/etc/swanctl/swanctl.conf create mode 100755 testing/tests/tnc/tnccs-20-fhh/hosts/moon/etc/init.d/charon delete mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-fhh/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/alice/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/alice/etc/ipsec.d/certs/aaaCert.pem delete mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/alice/etc/ipsec.d/private/aaaKey.pem delete mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/alice/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/alice/etc/swanctl/rsa/aaaKey.pem create mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/alice/etc/swanctl/swanctl.conf create mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/alice/etc/swanctl/x509/aaaCert.pem delete mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/carol/etc/ipsec.conf create mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/dave/etc/ipsec.conf create mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-hcd-eap/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/description.txt create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/evaltest.dat create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/hosts/moon/etc/strongswan.conf create mode 100755 testing/tests/tnc/tnccs-20-mutual-eap-fail/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/hosts/moon/etc/tnc_config create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/hosts/sun/etc/strongswan.conf create mode 100755 testing/tests/tnc/tnccs-20-mutual-eap-fail/hosts/sun/etc/swanctl/swanctl.conf create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/hosts/sun/etc/tnc_config create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/posttest.dat create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/pretest.dat create mode 100644 testing/tests/tnc/tnccs-20-mutual-eap-fail/test.conf delete mode 100644 testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/ipsec.conf create mode 100755 testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/ipsec.conf create mode 100755 testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/ipsec.conf create mode 100644 testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/ipsec.conf create mode 100644 testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/swantcl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-os-pts/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-os/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-os/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-os/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-os/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-os/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-os/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-os/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-os/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-os/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/alice/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/alice/etc/ipsec.d/certs/aaaCert.pem delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/alice/etc/ipsec.d/private/aaaKey.pem delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/alice/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/alice/etc/swanctl/rsa/aaaKey.pem create mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/alice/etc/swanctl/swanctl.conf create mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/alice/etc/swanctl/x509/aaaCert.pem delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pdp-eap/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/alice/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/alice/etc/ipsec.d/certs/aaaCert.pem delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/alice/etc/ipsec.d/private/aaaKey.pem delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/alice/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/alice/etc/swanctl/rsa/aaaKey.pem create mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/alice/etc/swanctl/swanctl.conf create mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/alice/etc/swanctl/x509/aaaCert.pem delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pdp-pt-tls/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pts-no-ecc/hosts/moon/etc/swanctl/swanctl.conf create mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/carol/etc/.strongswan.conf.swp delete mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-pts/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-server-retry/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-tls/hosts/carol/etc/ipsec.conf create mode 100644 testing/tests/tnc/tnccs-20-tls/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-tls/hosts/dave/etc/ipsec.conf create mode 100644 testing/tests/tnc/tnccs-20-tls/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20-tls/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20-tls/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20-tls/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-20/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-20/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-20/hosts/moon/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/carol/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/carol/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/carol/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/dave/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/dave/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/dave/etc/swanctl/swanctl.conf delete mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/moon/etc/ipsec.conf delete mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/moon/etc/ipsec.secrets create mode 100644 testing/tests/tnc/tnccs-dynamic/hosts/moon/etc/swanctl/swanctl.conf diff --git a/Android.common.mk b/Android.common.mk index 41f508a0e..1aa5b533b 100644 --- a/Android.common.mk +++ b/Android.common.mk @@ -26,5 +26,5 @@ add_plugin_subdirs = $(if $(call plugin_enabled,$(1)), \ ) # strongSwan version, replaced by top Makefile -strongswan_VERSION := "5.3.5" +strongswan_VERSION := "5.4.0" diff --git a/Android.mk b/Android.mk index 7b8bc8f87..f17289ea0 100644 --- a/Android.mk +++ b/Android.mk @@ -97,7 +97,6 @@ strongswan_CFLAGS += \ strongswan_BUILD := \ charon \ libcharon \ - libhydra \ libstrongswan \ libtncif \ libtnccs \ diff --git a/Makefile.in b/Makefile.in index 22286fe9f..55ddc0edc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -444,6 +444,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/NEWS b/NEWS index bda70686a..8de6cac4e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,43 @@ +strongswan-5.4.0 +---------------- + +- Support for IKEv2 redirection (RFC 5685) has been added. Plugins may + implement the redirect_provider_t interface to decide if and when to redirect + connecting clients. It is also possible to redirect established IKE_SAs based + on different selectors via VICI/swanctl. Unless disabled in strongswan.conf + the charon daemon will follow redirect requests received from servers. + +- The ike: prefix enables the explicit configuration of signature scheme + constraints against IKEv2 authentication in rightauth, which allows the use + of different signature schemes for trustchain verification and authentication. + +- The initiator of an IKEv2 make-before-break reauthentication now suspends + online certificate revocation checks (OCSP, CRLs) until the new IKE_SA and all + CHILD_SAs are established. This is required if the checks are done over the + CHILD_SA established with the new IKE_SA. This is not possible until the + initiator installs this SA and that only happens after the authentication is + completed successfully. So we suspend the checks during the reauthentication + and do them afterwards, if they fail the IKE_SA is closed. This change has no + effect on the behavior during the authentication of the initial IKE_SA. + +- For the vici plugin a Vici:Session Perl CPAN module has been added to allow + Perl applications to control and/or monitor the IKE daemon using the VICI + interface, similar to the existing Python egg or Ruby gem. + +- Traffic selectors with port ranges can now be configured in the Linux kernel: + e.g. remote_ts = 10.1.0.0/16[tcp/20-23] local_ts = dynamic[tcp/32768-65535]. + The port range must map to a port mask, though since the kernel does not + support arbitrary ranges. + +- The vici plugin allows the configuration of IPv4 and IPv6 address ranges + in local and remote traffic selectors. Since both the Linux kernel and + iptables cannot handle arbitrary ranges, address ranges are mapped to the next + larger CIDR subnet by the kernel-netlink and updown plugins, respectively. + +- Implemented IKEv1 IPv4/IPv6 address subnet and range identities that can be + used as owners of shared secrets. + + strongswan-5.3.5 ---------------- diff --git a/conf/Makefile.am b/conf/Makefile.am index 72d9f258d..b7edaa8ee 100644 --- a/conf/Makefile.am +++ b/conf/Makefile.am @@ -73,6 +73,7 @@ plugins = \ plugins/ntru.opt \ plugins/openssl.opt \ plugins/osx-attr.opt \ + plugins/p-cscf.opt \ plugins/pkcs11.opt \ plugins/radattr.opt \ plugins/random.opt \ diff --git a/conf/Makefile.in b/conf/Makefile.in index e6781b150..8bfc298a9 100644 --- a/conf/Makefile.in +++ b/conf/Makefile.in @@ -367,6 +367,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -455,6 +457,7 @@ plugins = \ plugins/ntru.opt \ plugins/openssl.opt \ plugins/osx-attr.opt \ + plugins/p-cscf.opt \ plugins/pkcs11.opt \ plugins/radattr.opt \ plugins/random.opt \ diff --git a/conf/format-options.py b/conf/format-options.py index d046e24ca..307394399 100755 --- a/conf/format-options.py +++ b/conf/format-options.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (C) 2014 Tobias Brunner +# Copyright (C) 2014-2015 Tobias Brunner # Hochschule fuer Technik Rapperswil # # This program is free software; you can redistribute it and/or modify it @@ -48,6 +48,14 @@ full.section.name {[#]} If a # is added between the curly braces the section header will be commented out in the configuration file snippet, which is useful for example sections. + +Dots in section/option names may be escaped with a backslash. For instance, +with the following section description + +charon.filelog./var/log/daemon\.log {} + Section to define logging into /var/log/daemon.log + +/var/log/daemon.log will be the name of the last section. """ import sys @@ -58,9 +66,10 @@ from operator import attrgetter class ConfigOption: """Representing a configuration option or described section in strongswan.conf""" - def __init__(self, name, default = None, section = False, commented = False): - self.name = name.split('.')[-1] - self.fullname = name + def __init__(self, path, default = None, section = False, commented = False): + self.path = path + self.name = path[-1] + self.fullname = '.'.join(path) self.default = default self.section = section self.commented = commented @@ -68,7 +77,7 @@ class ConfigOption: self.options = [] def __lt__(self, other): - return self.name < other.name + return self.name < other.name def add_paragraph(self): """Adds a new paragraph to the description""" @@ -113,7 +122,8 @@ class Parser: if m: if self.__current: self.__add_option(self.__current) - self.__current = ConfigOption(m.group('name'), m.group('default'), + path = self.__split_name(m.group('name')) + self.__current = ConfigOption(path, m.group('default'), commented = not m.group('assign')) return # section definition @@ -121,7 +131,8 @@ class Parser: if m: if self.__current: self.__add_option(self.__current) - self.__current = ConfigOption(m.group('name'), section = True, + path = self.__split_name(m.group('name')) + self.__current = ConfigOption(path, section = True, commented = m.group('comment')) return # paragraph separator @@ -133,11 +144,14 @@ class Parser: if m and self.__current: self.__current.add(m.group('text')) + def __split_name(self, name): + """Split the given full name in a list of section/option names""" + return [x.replace('\.', '.') for x in re.split(r'(? is the name of a connection with an ePDG from which to request + # P-CSCF server addresses. + # = no + + } + +} + diff --git a/conf/plugins/p-cscf.opt b/conf/plugins/p-cscf.opt new file mode 100644 index 000000000..ec7f8153f --- /dev/null +++ b/conf/plugins/p-cscf.opt @@ -0,0 +1,11 @@ +charon.plugins.p-cscf.enable {} + Section to enable requesting P-CSCF server addresses for individual + connections. + +charon.plugins.p-cscf.enable. = no + is the name of a connection with an ePDG from which to request + P-CSCF server addresses. + + is the name of a connection with an ePDG from which to request + P-CSCF server addresses. Requests will be sent for addresses of the same + families for which internal IPs are requested. diff --git a/conf/strongswan.conf.5.main b/conf/strongswan.conf.5.main index 633588325..e6a502952 100644 --- a/conf/strongswan.conf.5.main +++ b/conf/strongswan.conf.5.main @@ -96,6 +96,13 @@ Strictly require at least one test vector to enable an algorithm. .BR charon.crypto_test.rng_true " [no]" Whether to test RNG with TRUE quality; requires a lot of entropy. +.TP +.BR charon.delete_rekeyed " [no]" +Delete CHILD_SAs right after they got successfully rekeyed (IKEv1 only). Reduces +the number of stale CHILD_SAs in scenarios with a lot of rekeyings. However, +this might cause problems with implementations that continue to use rekeyed SAs +until they expire. + .TP .BR charon.dh_exponent_ansi_x9_42 " [yes]" Use ANSI X9.42 DH exponent size or optimum size matched to cryptographic @@ -176,6 +183,10 @@ If enabled objects used during authentication (certificates, identities etc.) are released to free memory once an IKE_SA is established. Enabling this might conflict with plugins that later need access to e.g. the used certificates. +.TP +.BR charon.follow_redirects " [yes]" +Whether to follow IKEv2 redirects (RFC 5685). + .TP .BR charon.fragment_size " [0]" Maximum size (complete IP datagram size in bytes) of a sent IKE fragment when @@ -1190,6 +1201,17 @@ Set OpenSSL FIPS mode: disabled(0), enabled(1), Suite B enabled(2). .BR charon.plugins.osx-attr.append " [yes]" Whether DNS servers are appended to existing entries, instead of replacing them. +.TP +.B charon.plugins.p-cscf.enable +.br +Section to enable requesting P\-CSCF server addresses for individual connections. + +.TP +.BR charon.plugins.p-cscf.enable. " [no]" + is the name of a connection with an ePDG from which to request P\-CSCF +server addresses. Requests will be sent for addresses of the same families for +which internal IPs are requested. + .TP .BR charon.plugins.pkcs11.load_certs " [yes]" Whether to load certificates from tokens. @@ -1572,7 +1594,7 @@ resolution failed), 0 to disable retries. .TP .BR charon.reuse_ikesa " [yes]" -Initiate CHILD_SA within existing IKE_SAs. +Initiate CHILD_SA within existing IKE_SAs (always enabled for IKEv1). .TP .BR charon.routing_table " []" diff --git a/config.h.in b/config.h.in index b95e01843..02528e733 100644 --- a/config.h.in +++ b/config.h.in @@ -329,6 +329,9 @@ /* support for IKEv2 protocol */ #undef USE_IKEV2 +/* use thread ID for thread identification, if available */ +#undef USE_THREAD_IDS + /* use Vstr string library for printf hooks */ #undef USE_VSTR diff --git a/configure b/configure index 3d0478c88..dac40eacc 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for strongSwan 5.3.5. +# Generated by GNU Autoconf 2.69 for strongSwan 5.4.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='strongSwan' PACKAGE_TARNAME='strongswan' -PACKAGE_VERSION='5.3.5' -PACKAGE_STRING='strongSwan 5.3.5' +PACKAGE_VERSION='5.4.0' +PACKAGE_STRING='strongSwan 5.4.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -635,6 +635,8 @@ LIBOBJS strongswan_options USE_PY_TEST_FALSE USE_PY_TEST_TRUE +USE_PERL_CPAN_FALSE +USE_PERL_CPAN_TRUE USE_PYTHON_EGGS_FALSE USE_PYTHON_EGGS_TRUE USE_RUBY_GEMS_FALSE @@ -691,8 +693,6 @@ USE_LIBIPSEC_FALSE USE_LIBIPSEC_TRUE USE_LIBCHARON_FALSE USE_LIBCHARON_TRUE -USE_LIBHYDRA_FALSE -USE_LIBHYDRA_TRUE USE_LIBSTRONGSWAN_FALSE USE_LIBSTRONGSWAN_TRUE USE_CONFTEST_FALSE @@ -731,12 +731,6 @@ USE_LOCK_PROFILER_FALSE USE_LOCK_PROFILER_TRUE USE_LEAK_DETECTIVE_FALSE USE_LEAK_DETECTIVE_TRUE -USE_KERNEL_PFROUTE_FALSE -USE_KERNEL_PFROUTE_TRUE -USE_KERNEL_PFKEY_FALSE -USE_KERNEL_PFKEY_TRUE -USE_KERNEL_NETLINK_FALSE -USE_KERNEL_NETLINK_TRUE USE_ATTR_SQL_FALSE USE_ATTR_SQL_TRUE USE_ATTR_FALSE @@ -869,6 +863,12 @@ USE_KERNEL_WFP_FALSE USE_KERNEL_WFP_TRUE USE_KERNEL_LIBIPSEC_FALSE USE_KERNEL_LIBIPSEC_TRUE +USE_KERNEL_PFROUTE_FALSE +USE_KERNEL_PFROUTE_TRUE +USE_KERNEL_PFKEY_FALSE +USE_KERNEL_PFKEY_TRUE +USE_KERNEL_NETLINK_FALSE +USE_KERNEL_NETLINK_TRUE USE_HA_FALSE USE_HA_TRUE USE_LOAD_TESTER_FALSE @@ -891,6 +891,8 @@ USE_ANDROID_LOG_FALSE USE_ANDROID_LOG_TRUE USE_ANDROID_DNS_FALSE USE_ANDROID_DNS_TRUE +USE_P_CSCF_FALSE +USE_P_CSCF_TRUE USE_OSX_ATTR_FALSE USE_OSX_ATTR_TRUE USE_UCI_FALSE @@ -1025,6 +1027,8 @@ attest_plugins pool_plugins starter_plugins charon_plugins +PERL_CPAN_INSTALL_FALSE +PERL_CPAN_INSTALL_TRUE PYTHON_EGGS_INSTALL_FALSE PYTHON_EGGS_INSTALL_TRUE PY_TEST @@ -1068,6 +1072,8 @@ systemd_journal_LIBS systemd_journal_CFLAGS systemd_daemon_LIBS systemd_daemon_CFLAGS +systemd_LIBS +systemd_CFLAGS xml_LIBS xml_CFLAGS soup_LIBS @@ -1374,6 +1380,7 @@ enable_attr enable_attr_sql enable_dhcp enable_osx_attr +enable_p_cscf enable_resolve enable_unity enable_imc_test @@ -1441,9 +1448,12 @@ enable_ruby_gems enable_ruby_gems_install enable_python_eggs enable_python_eggs_install +enable_perl_cpan +enable_perl_cpan_install enable_coverage enable_leak_detective enable_lock_profiler +enable_log_thread_ids enable_monolithic enable_defaults enable_all @@ -1476,6 +1486,8 @@ soup_CFLAGS soup_LIBS xml_CFLAGS xml_LIBS +systemd_CFLAGS +systemd_LIBS systemd_daemon_CFLAGS systemd_daemon_LIBS systemd_journal_CFLAGS @@ -2032,7 +2044,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures strongSwan 5.3.5 to adapt to many kinds of systems. +\`configure' configures strongSwan 5.4.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -2102,7 +2114,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of strongSwan 5.3.5:";; + short | recursive ) echo "Configuration of strongSwan 5.4.0:";; esac cat <<\_ACEOF @@ -2230,13 +2242,15 @@ Optional Features: Requires libxml. --enable-sql enable SQL database configuration backend. --enable-uci enable OpenWRT UCI configuration plugin. - --enable-vici enable strongSwan IKE generic IPC interface plugin. + --disable-vici disable strongSwan IKE generic IPC interface plugin. --enable-android-dns enable Android specific DNS handler. --disable-attr disable strongswan.conf based configuration attribute plugin. --enable-attr-sql enable SQL based configuration attribute plugin. --enable-dhcp enable DHCP based attribute provider plugin. --enable-osx-attr enable OS X SystemConfiguration attribute handler. + --enable-p-cscf enable plugin to request P-CSCF server addresses + from an ePDG. --disable-resolve disable resolve DNS handler plugin. --enable-unity enables Cisco Unity extension plugin. --enable-imc-test enable IMC test module. @@ -2305,7 +2319,7 @@ Optional Features: scripts). --enable-svc enable charon Windows service. --enable-systemd enable systemd specific IKE daemon charon-systemd. - --enable-swanctl enable swanctl configuration and control tool. + --disable-swanctl disable swanctl configuration and control tool. --enable-tkm enable Trusted Key Manager support. --enable-bfd-backtraces use binutils libbfd to resolve backtraces for memory leaks and segfaults. @@ -2328,9 +2342,15 @@ Optional Features: --enable-python-eggs enable build of provided python eggs. --enable-python-eggs-install enable installation of provided python eggs. + --enable-perl-cpan enable build of provided perl CPAN module. + --enable-perl-cpan-install + enable installation of provided CPAN module. --enable-coverage enable lcov coverage report generation. --enable-leak-detective enable malloc hooks to find memory leaks. --enable-lock-profiler enable lock/mutex profiling code. + --enable-log-thread-ids use thread ID, if available, instead of an + incremented value starting from 1, to identify + threads. --enable-monolithic build monolithic version of libstrongswan that includes all enabled plugins. Similarly, the plugins of charon are assembled in libcharon. @@ -2453,6 +2473,10 @@ Some influential environment variables: soup_LIBS linker flags for soup, overriding pkg-config xml_CFLAGS C compiler flags for xml, overriding pkg-config xml_LIBS linker flags for xml, overriding pkg-config + systemd_CFLAGS + C compiler flags for systemd, overriding pkg-config + systemd_LIBS + linker flags for systemd, overriding pkg-config systemd_daemon_CFLAGS C compiler flags for systemd_daemon, overriding pkg-config systemd_daemon_LIBS @@ -2545,7 +2569,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -strongSwan configure 5.3.5 +strongSwan configure 5.4.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -3067,7 +3091,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by strongSwan $as_me 5.3.5, which was +It was created by strongSwan $as_me 5.4.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3930,7 +3954,7 @@ fi # Define the identity of the package. PACKAGE='strongswan' - VERSION='5.3.5' + VERSION='5.4.0' cat >>confdefs.h <<_ACEOF @@ -6286,12 +6310,12 @@ if test "${enable_vici+set}" = set; then : vici=false fi else - vici=false + vici=true vici_given=false fi - disabled_by_default=${disabled_by_default}" vici" + enabled_by_default=${enabled_by_default}" vici" # attribute provider/consumer plugins # Check whether --enable-android-dns was given. @@ -6374,6 +6398,22 @@ fi disabled_by_default=${disabled_by_default}" osx_attr" +# Check whether --enable-p-cscf was given. +if test "${enable_p_cscf+set}" = set; then : + enableval=$enable_p_cscf; p_cscf_given=true + if test x$enableval = xyes; then + p_cscf=true + else + p_cscf=false + fi +else + p_cscf=false + p_cscf_given=false + +fi + + disabled_by_default=${disabled_by_default}" p_cscf" + # Check whether --enable-resolve was given. if test "${enable_resolve+set}" = set; then : enableval=$enable_resolve; resolve_given=true @@ -7234,12 +7274,12 @@ if test "${enable_swanctl+set}" = set; then : swanctl=false fi else - swanctl=false + swanctl=true swanctl_given=false fi - disabled_by_default=${disabled_by_default}" swanctl" + enabled_by_default=${enabled_by_default}" swanctl" # Check whether --enable-tkm was given. if test "${enable_tkm+set}" = set; then : @@ -7450,6 +7490,38 @@ fi disabled_by_default=${disabled_by_default}" python_eggs_install" +# Check whether --enable-perl-cpan was given. +if test "${enable_perl_cpan+set}" = set; then : + enableval=$enable_perl_cpan; perl_cpan_given=true + if test x$enableval = xyes; then + perl_cpan=true + else + perl_cpan=false + fi +else + perl_cpan=false + perl_cpan_given=false + +fi + + disabled_by_default=${disabled_by_default}" perl_cpan" + +# Check whether --enable-perl-cpan-install was given. +if test "${enable_perl_cpan_install+set}" = set; then : + enableval=$enable_perl_cpan_install; perl_cpan_install_given=true + if test x$enableval = xyes; then + perl_cpan_install=true + else + perl_cpan_install=false + fi +else + perl_cpan_install=false + perl_cpan_install_given=false + +fi + + disabled_by_default=${disabled_by_default}" perl_cpan_install" + # compile options # Check whether --enable-coverage was given. if test "${enable_coverage+set}" = set; then : @@ -7499,6 +7571,22 @@ fi disabled_by_default=${disabled_by_default}" lock_profiler" +# Check whether --enable-log-thread-ids was given. +if test "${enable_log_thread_ids+set}" = set; then : + enableval=$enable_log_thread_ids; log_thread_ids_given=true + if test x$enableval = xyes; then + log_thread_ids=true + else + log_thread_ids=false + fi +else + log_thread_ids=false + log_thread_ids_given=false + +fi + + disabled_by_default=${disabled_by_default}" log_thread_ids" + # Check whether --enable-monolithic was given. if test "${enable_monolithic+set}" = set; then : enableval=$enable_monolithic; monolithic_given=true @@ -17328,6 +17416,10 @@ if test x$python_eggs_install = xtrue; then python_eggs=true fi +if test x$perl_cpan_install = xtrue; then + perl_cpan=true +fi + # =========================================== # check required libraries and header files # =========================================== @@ -19497,6 +19589,65 @@ $as_echo "$systemdsystemunitdir" >&6; } fi +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for systemd" >&5 +$as_echo_n "checking for systemd... " >&6; } + +if test -n "$systemd_CFLAGS"; then + pkg_cv_systemd_CFLAGS="$systemd_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd >= 209\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd >= 209") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_systemd_CFLAGS=`$PKG_CONFIG --cflags "libsystemd >= 209" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$systemd_LIBS"; then + pkg_cv_systemd_LIBS="$systemd_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd >= 209\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd >= 209") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_systemd_LIBS=`$PKG_CONFIG --libs "libsystemd >= 209" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + systemd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd >= 209" 2>&1` + else + systemd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd >= 209" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$systemd_PKG_ERRORS" >&5 + + pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for systemd_daemon" >&5 $as_echo_n "checking for systemd_daemon... " >&6; } @@ -19590,6 +19741,195 @@ fi +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for systemd_journal" >&5 +$as_echo_n "checking for systemd_journal... " >&6; } + +if test -n "$systemd_journal_CFLAGS"; then + pkg_cv_systemd_journal_CFLAGS="$systemd_journal_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-journal\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-journal") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_systemd_journal_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-journal" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$systemd_journal_LIBS"; then + pkg_cv_systemd_journal_LIBS="$systemd_journal_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-journal\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-journal") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_systemd_journal_LIBS=`$PKG_CONFIG --libs "libsystemd-journal" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + systemd_journal_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-journal" 2>&1` + else + systemd_journal_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-journal" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$systemd_journal_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libsystemd-journal) were not met: + +$systemd_journal_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables systemd_journal_CFLAGS +and systemd_journal_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables systemd_journal_CFLAGS +and systemd_journal_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + systemd_journal_CFLAGS=$pkg_cv_systemd_journal_CFLAGS + systemd_journal_LIBS=$pkg_cv_systemd_journal_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for systemd_daemon" >&5 +$as_echo_n "checking for systemd_daemon... " >&6; } + +if test -n "$systemd_daemon_CFLAGS"; then + pkg_cv_systemd_daemon_CFLAGS="$systemd_daemon_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_systemd_daemon_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$systemd_daemon_LIBS"; then + pkg_cv_systemd_daemon_LIBS="$systemd_daemon_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_systemd_daemon_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + systemd_daemon_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + else + systemd_daemon_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$systemd_daemon_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libsystemd-daemon) were not met: + +$systemd_daemon_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables systemd_daemon_CFLAGS +and systemd_daemon_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables systemd_daemon_CFLAGS +and systemd_daemon_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + systemd_daemon_CFLAGS=$pkg_cv_systemd_daemon_CFLAGS + systemd_daemon_LIBS=$pkg_cv_systemd_daemon_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + + pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for systemd_journal" >&5 @@ -19683,6 +20023,15 @@ $as_echo "yes" >&6; } fi + +else + systemd_CFLAGS=$pkg_cv_systemd_CFLAGS + systemd_LIBS=$pkg_cv_systemd_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + +fi fi if test x$tss = xtrousers; then @@ -20556,7 +20905,7 @@ if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-l$openssl_lib $LIBS" +LIBS="-l$openssl_lib $DLLIB $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -21861,6 +22210,15 @@ else fi + if test "x$perl_cpan_install" = xtrue; then + PERL_CPAN_INSTALL_TRUE= + PERL_CPAN_INSTALL_FALSE='#' +else + PERL_CPAN_INSTALL_TRUE='#' + PERL_CPAN_INSTALL_FALSE= +fi + + # =============================================== # collect plugin list for strongSwan components # =============================================== @@ -21886,9 +22244,8 @@ cmd_plugins= aikgen_plugins= # location specific lists for checksumming, -# for src/libcharon, src/libhydra, src/libstrongswan and src/libtnccs +# for src/libcharon, src/libstrongswan and src/libtnccs c_plugins= -h_plugins= s_plugins= t_plugins= @@ -21984,21 +22341,6 @@ if test x$rc2 = xtrue; then fi -if test x$sha1 = xtrue; then - s_plugins=${s_plugins}" sha1" - charon_plugins=${charon_plugins}" sha1" - scepclient_plugins=${scepclient_plugins}" sha1" - pki_plugins=${pki_plugins}" sha1" - scripts_plugins=${scripts_plugins}" sha1" - manager_plugins=${manager_plugins}" sha1" - medsrv_plugins=${medsrv_plugins}" sha1" - attest_plugins=${attest_plugins}" sha1" - nm_plugins=${nm_plugins}" sha1" - cmd_plugins=${cmd_plugins}" sha1" - aikgen_plugins=${aikgen_plugins}" sha1" - - fi - if test x$sha2 = xtrue; then s_plugins=${s_plugins}" sha2" charon_plugins=${charon_plugins}" sha2" @@ -22027,6 +22369,21 @@ if test x$sha3 = xtrue; then fi +if test x$sha1 = xtrue; then + s_plugins=${s_plugins}" sha1" + charon_plugins=${charon_plugins}" sha1" + scepclient_plugins=${scepclient_plugins}" sha1" + pki_plugins=${pki_plugins}" sha1" + scripts_plugins=${scripts_plugins}" sha1" + manager_plugins=${manager_plugins}" sha1" + medsrv_plugins=${medsrv_plugins}" sha1" + attest_plugins=${attest_plugins}" sha1" + nm_plugins=${nm_plugins}" sha1" + cmd_plugins=${cmd_plugins}" sha1" + aikgen_plugins=${aikgen_plugins}" sha1" + + fi + if test x$md4 = xtrue; then s_plugins=${s_plugins}" md4" charon_plugins=${charon_plugins}" md4" @@ -22498,7 +22855,7 @@ if test x$kernel_iph = xtrue; then fi if test x$kernel_pfkey = xtrue; then - h_plugins=${h_plugins}" kernel-pfkey" + c_plugins=${c_plugins}" kernel-pfkey" charon_plugins=${charon_plugins}" kernel-pfkey" starter_plugins=${starter_plugins}" kernel-pfkey" nm_plugins=${nm_plugins}" kernel-pfkey" @@ -22507,7 +22864,7 @@ if test x$kernel_pfkey = xtrue; then fi if test x$kernel_pfroute = xtrue; then - h_plugins=${h_plugins}" kernel-pfroute" + c_plugins=${c_plugins}" kernel-pfroute" charon_plugins=${charon_plugins}" kernel-pfroute" starter_plugins=${starter_plugins}" kernel-pfroute" nm_plugins=${nm_plugins}" kernel-pfroute" @@ -22516,7 +22873,7 @@ if test x$kernel_pfroute = xtrue; then fi if test x$kernel_netlink = xtrue; then - h_plugins=${h_plugins}" kernel-netlink" + c_plugins=${c_plugins}" kernel-netlink" charon_plugins=${charon_plugins}" kernel-netlink" starter_plugins=${starter_plugins}" kernel-netlink" nm_plugins=${nm_plugins}" kernel-netlink" @@ -22820,6 +23177,13 @@ if test x$osx_attr = xtrue; then fi +if test x$p_cscf = xtrue; then + c_plugins=${c_plugins}" p-cscf" + charon_plugins=${charon_plugins}" p-cscf" + cmd_plugins=${cmd_plugins}" p-cscf" + + fi + if test x$android_dns = xtrue; then c_plugins=${c_plugins}" android-dns" charon_plugins=${charon_plugins}" android-dns" @@ -23422,6 +23786,14 @@ else USE_OSX_ATTR_FALSE= fi + if test x$p_cscf = xtrue; then + USE_P_CSCF_TRUE= + USE_P_CSCF_FALSE='#' +else + USE_P_CSCF_TRUE='#' + USE_P_CSCF_FALSE= +fi + if test x$android_dns = xtrue; then USE_ANDROID_DNS_TRUE= USE_ANDROID_DNS_FALSE='#' @@ -23510,6 +23882,30 @@ else USE_HA_FALSE= fi + if test x$kernel_netlink = xtrue; then + USE_KERNEL_NETLINK_TRUE= + USE_KERNEL_NETLINK_FALSE='#' +else + USE_KERNEL_NETLINK_TRUE='#' + USE_KERNEL_NETLINK_FALSE= +fi + + if test x$kernel_pfkey = xtrue; then + USE_KERNEL_PFKEY_TRUE= + USE_KERNEL_PFKEY_FALSE='#' +else + USE_KERNEL_PFKEY_TRUE='#' + USE_KERNEL_PFKEY_FALSE= +fi + + if test x$kernel_pfroute = xtrue; then + USE_KERNEL_PFROUTE_TRUE= + USE_KERNEL_PFROUTE_FALSE='#' +else + USE_KERNEL_PFROUTE_TRUE='#' + USE_KERNEL_PFROUTE_FALSE= +fi + if test x$kernel_libipsec = xtrue; then USE_KERNEL_LIBIPSEC_TRUE= USE_KERNEL_LIBIPSEC_FALSE='#' @@ -24039,33 +24435,6 @@ else fi -# hydra plugins -# --------------- - if test x$kernel_netlink = xtrue; then - USE_KERNEL_NETLINK_TRUE= - USE_KERNEL_NETLINK_FALSE='#' -else - USE_KERNEL_NETLINK_TRUE='#' - USE_KERNEL_NETLINK_FALSE= -fi - - if test x$kernel_pfkey = xtrue; then - USE_KERNEL_PFKEY_TRUE= - USE_KERNEL_PFKEY_FALSE='#' -else - USE_KERNEL_PFKEY_TRUE='#' - USE_KERNEL_PFKEY_FALSE= -fi - - if test x$kernel_pfroute = xtrue; then - USE_KERNEL_PFROUTE_TRUE= - USE_KERNEL_PFROUTE_FALSE='#' -else - USE_KERNEL_PFROUTE_TRUE='#' - USE_KERNEL_PFROUTE_FALSE= -fi - - # other options # --------------- if test x$leak_detective = xtrue; then @@ -24220,14 +24589,6 @@ else USE_LIBSTRONGSWAN_FALSE= fi - if test x$charon = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$svc = xtrue -o x$systemd = xtrue; then - USE_LIBHYDRA_TRUE= - USE_LIBHYDRA_FALSE='#' -else - USE_LIBHYDRA_TRUE='#' - USE_LIBHYDRA_FALSE= -fi - if test x$charon = xtrue -o x$conftest = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$svc = xtrue -o x$systemd = xtrue; then USE_LIBCHARON_TRUE= USE_LIBCHARON_FALSE='#' @@ -24452,6 +24813,14 @@ else USE_PYTHON_EGGS_FALSE= fi + if test x$perl_cpan = xtrue; then + USE_PERL_CPAN_TRUE= + USE_PERL_CPAN_FALSE='#' +else + USE_PERL_CPAN_TRUE='#' + USE_PERL_CPAN_FALSE= +fi + if test "x$PY_TEST" != x; then USE_PY_TEST_TRUE= USE_PY_TEST_FALSE='#' @@ -24474,6 +24843,11 @@ if test x$capabilities = xlibcap -o x$capabilities = xnative; then $as_echo "#define CAPABILITIES /**/" >>confdefs.h +fi +if test x$log_thread_ids = xtrue; then + +$as_echo "#define USE_THREAD_IDS /**/" >>confdefs.h + fi if test x$monolithic = xtrue; then @@ -24543,7 +24917,7 @@ fi # build Makefiles # ================= -ac_config_files="$ac_config_files Makefile conf/Makefile man/Makefile init/Makefile init/systemd/Makefile init/systemd-swanctl/Makefile src/Makefile src/include/Makefile src/libstrongswan/Makefile src/libstrongswan/plugins/aes/Makefile src/libstrongswan/plugins/cmac/Makefile src/libstrongswan/plugins/des/Makefile src/libstrongswan/plugins/blowfish/Makefile src/libstrongswan/plugins/rc2/Makefile src/libstrongswan/plugins/md4/Makefile src/libstrongswan/plugins/md5/Makefile src/libstrongswan/plugins/sha1/Makefile src/libstrongswan/plugins/sha2/Makefile src/libstrongswan/plugins/sha3/Makefile src/libstrongswan/plugins/fips_prf/Makefile src/libstrongswan/plugins/gmp/Makefile src/libstrongswan/plugins/rdrand/Makefile src/libstrongswan/plugins/aesni/Makefile src/libstrongswan/plugins/random/Makefile src/libstrongswan/plugins/nonce/Makefile src/libstrongswan/plugins/hmac/Makefile src/libstrongswan/plugins/xcbc/Makefile src/libstrongswan/plugins/x509/Makefile src/libstrongswan/plugins/revocation/Makefile src/libstrongswan/plugins/constraints/Makefile src/libstrongswan/plugins/acert/Makefile src/libstrongswan/plugins/pubkey/Makefile src/libstrongswan/plugins/pkcs1/Makefile src/libstrongswan/plugins/pkcs7/Makefile src/libstrongswan/plugins/pkcs8/Makefile src/libstrongswan/plugins/pkcs12/Makefile src/libstrongswan/plugins/pgp/Makefile src/libstrongswan/plugins/dnskey/Makefile src/libstrongswan/plugins/sshkey/Makefile src/libstrongswan/plugins/pem/Makefile src/libstrongswan/plugins/curl/Makefile src/libstrongswan/plugins/files/Makefile src/libstrongswan/plugins/winhttp/Makefile src/libstrongswan/plugins/unbound/Makefile src/libstrongswan/plugins/soup/Makefile src/libstrongswan/plugins/ldap/Makefile src/libstrongswan/plugins/mysql/Makefile src/libstrongswan/plugins/sqlite/Makefile src/libstrongswan/plugins/padlock/Makefile src/libstrongswan/plugins/openssl/Makefile src/libstrongswan/plugins/gcrypt/Makefile src/libstrongswan/plugins/agent/Makefile src/libstrongswan/plugins/keychain/Makefile src/libstrongswan/plugins/pkcs11/Makefile src/libstrongswan/plugins/chapoly/Makefile src/libstrongswan/plugins/ctr/Makefile src/libstrongswan/plugins/ccm/Makefile src/libstrongswan/plugins/gcm/Makefile src/libstrongswan/plugins/af_alg/Makefile src/libstrongswan/plugins/ntru/Makefile src/libstrongswan/plugins/bliss/Makefile src/libstrongswan/plugins/bliss/tests/Makefile src/libstrongswan/plugins/test_vectors/Makefile src/libstrongswan/tests/Makefile src/libhydra/Makefile src/libhydra/plugins/kernel_netlink/Makefile src/libhydra/plugins/kernel_pfkey/Makefile src/libhydra/plugins/kernel_pfroute/Makefile src/libhydra/tests/Makefile src/libipsec/Makefile src/libipsec/tests/Makefile src/libsimaka/Makefile src/libtls/Makefile src/libtls/tests/Makefile src/libradius/Makefile src/libtncif/Makefile src/libtnccs/Makefile src/libtnccs/plugins/tnc_tnccs/Makefile src/libtnccs/plugins/tnc_imc/Makefile src/libtnccs/plugins/tnc_imv/Makefile src/libtnccs/plugins/tnccs_11/Makefile src/libtnccs/plugins/tnccs_20/Makefile src/libtnccs/plugins/tnccs_dynamic/Makefile src/libpttls/Makefile src/libimcv/Makefile src/libimcv/plugins/imc_test/Makefile src/libimcv/plugins/imv_test/Makefile src/libimcv/plugins/imc_scanner/Makefile src/libimcv/plugins/imv_scanner/Makefile src/libimcv/plugins/imc_os/Makefile src/libimcv/plugins/imv_os/Makefile src/libimcv/plugins/imc_attestation/Makefile src/libimcv/plugins/imv_attestation/Makefile src/libimcv/plugins/imc_swid/Makefile src/libimcv/plugins/imv_swid/Makefile src/libimcv/plugins/imc_hcd/Makefile src/libimcv/plugins/imv_hcd/Makefile src/charon/Makefile src/charon-nm/Makefile src/charon-tkm/Makefile src/charon-cmd/Makefile src/charon-svc/Makefile src/charon-systemd/Makefile src/libcharon/Makefile src/libcharon/plugins/eap_aka/Makefile src/libcharon/plugins/eap_aka_3gpp2/Makefile src/libcharon/plugins/eap_dynamic/Makefile src/libcharon/plugins/eap_identity/Makefile src/libcharon/plugins/eap_md5/Makefile src/libcharon/plugins/eap_gtc/Makefile src/libcharon/plugins/eap_sim/Makefile src/libcharon/plugins/eap_sim_file/Makefile src/libcharon/plugins/eap_sim_pcsc/Makefile src/libcharon/plugins/eap_simaka_sql/Makefile src/libcharon/plugins/eap_simaka_pseudonym/Makefile src/libcharon/plugins/eap_simaka_reauth/Makefile src/libcharon/plugins/eap_mschapv2/Makefile src/libcharon/plugins/eap_tls/Makefile src/libcharon/plugins/eap_ttls/Makefile src/libcharon/plugins/eap_peap/Makefile src/libcharon/plugins/eap_tnc/Makefile src/libcharon/plugins/eap_radius/Makefile src/libcharon/plugins/xauth_generic/Makefile src/libcharon/plugins/xauth_eap/Makefile src/libcharon/plugins/xauth_pam/Makefile src/libcharon/plugins/xauth_noauth/Makefile src/libcharon/plugins/tnc_ifmap/Makefile src/libcharon/plugins/tnc_pdp/Makefile src/libcharon/plugins/socket_default/Makefile src/libcharon/plugins/socket_dynamic/Makefile src/libcharon/plugins/socket_win/Makefile src/libcharon/plugins/connmark/Makefile src/libcharon/plugins/forecast/Makefile src/libcharon/plugins/farp/Makefile src/libcharon/plugins/smp/Makefile src/libcharon/plugins/sql/Makefile src/libcharon/plugins/dnscert/Makefile src/libcharon/plugins/ipseckey/Makefile src/libcharon/plugins/medsrv/Makefile src/libcharon/plugins/medcli/Makefile src/libcharon/plugins/addrblock/Makefile src/libcharon/plugins/unity/Makefile src/libcharon/plugins/uci/Makefile src/libcharon/plugins/ha/Makefile src/libcharon/plugins/kernel_libipsec/Makefile src/libcharon/plugins/kernel_wfp/Makefile src/libcharon/plugins/kernel_iph/Makefile src/libcharon/plugins/whitelist/Makefile src/libcharon/plugins/ext_auth/Makefile src/libcharon/plugins/lookip/Makefile src/libcharon/plugins/error_notify/Makefile src/libcharon/plugins/certexpire/Makefile src/libcharon/plugins/systime_fix/Makefile src/libcharon/plugins/led/Makefile src/libcharon/plugins/duplicheck/Makefile src/libcharon/plugins/coupling/Makefile src/libcharon/plugins/radattr/Makefile src/libcharon/plugins/osx_attr/Makefile src/libcharon/plugins/android_dns/Makefile src/libcharon/plugins/android_log/Makefile src/libcharon/plugins/maemo/Makefile src/libcharon/plugins/stroke/Makefile src/libcharon/plugins/vici/Makefile src/libcharon/plugins/vici/ruby/Makefile src/libcharon/plugins/vici/python/Makefile src/libcharon/plugins/updown/Makefile src/libcharon/plugins/dhcp/Makefile src/libcharon/plugins/load_tester/Makefile src/libcharon/plugins/resolve/Makefile src/libcharon/plugins/attr/Makefile src/libcharon/plugins/attr_sql/Makefile src/libcharon/tests/Makefile src/stroke/Makefile src/ipsec/Makefile src/starter/Makefile src/starter/tests/Makefile src/_updown/Makefile src/_copyright/Makefile src/scepclient/Makefile src/aikgen/Makefile src/pki/Makefile src/pki/man/Makefile src/pool/Makefile src/dumm/Makefile src/dumm/ext/extconf.rb src/libfast/Makefile src/manager/Makefile src/medsrv/Makefile src/checksum/Makefile src/conftest/Makefile src/pt-tls-client/Makefile src/swanctl/Makefile scripts/Makefile testing/Makefile" +ac_config_files="$ac_config_files Makefile conf/Makefile man/Makefile init/Makefile init/systemd/Makefile init/systemd-swanctl/Makefile src/Makefile src/include/Makefile src/libstrongswan/Makefile src/libstrongswan/plugins/aes/Makefile src/libstrongswan/plugins/cmac/Makefile src/libstrongswan/plugins/des/Makefile src/libstrongswan/plugins/blowfish/Makefile src/libstrongswan/plugins/rc2/Makefile src/libstrongswan/plugins/md4/Makefile src/libstrongswan/plugins/md5/Makefile src/libstrongswan/plugins/sha1/Makefile src/libstrongswan/plugins/sha2/Makefile src/libstrongswan/plugins/sha3/Makefile src/libstrongswan/plugins/fips_prf/Makefile src/libstrongswan/plugins/gmp/Makefile src/libstrongswan/plugins/rdrand/Makefile src/libstrongswan/plugins/aesni/Makefile src/libstrongswan/plugins/random/Makefile src/libstrongswan/plugins/nonce/Makefile src/libstrongswan/plugins/hmac/Makefile src/libstrongswan/plugins/xcbc/Makefile src/libstrongswan/plugins/x509/Makefile src/libstrongswan/plugins/revocation/Makefile src/libstrongswan/plugins/constraints/Makefile src/libstrongswan/plugins/acert/Makefile src/libstrongswan/plugins/pubkey/Makefile src/libstrongswan/plugins/pkcs1/Makefile src/libstrongswan/plugins/pkcs7/Makefile src/libstrongswan/plugins/pkcs8/Makefile src/libstrongswan/plugins/pkcs12/Makefile src/libstrongswan/plugins/pgp/Makefile src/libstrongswan/plugins/dnskey/Makefile src/libstrongswan/plugins/sshkey/Makefile src/libstrongswan/plugins/pem/Makefile src/libstrongswan/plugins/curl/Makefile src/libstrongswan/plugins/files/Makefile src/libstrongswan/plugins/winhttp/Makefile src/libstrongswan/plugins/unbound/Makefile src/libstrongswan/plugins/soup/Makefile src/libstrongswan/plugins/ldap/Makefile src/libstrongswan/plugins/mysql/Makefile src/libstrongswan/plugins/sqlite/Makefile src/libstrongswan/plugins/padlock/Makefile src/libstrongswan/plugins/openssl/Makefile src/libstrongswan/plugins/gcrypt/Makefile src/libstrongswan/plugins/agent/Makefile src/libstrongswan/plugins/keychain/Makefile src/libstrongswan/plugins/pkcs11/Makefile src/libstrongswan/plugins/chapoly/Makefile src/libstrongswan/plugins/ctr/Makefile src/libstrongswan/plugins/ccm/Makefile src/libstrongswan/plugins/gcm/Makefile src/libstrongswan/plugins/af_alg/Makefile src/libstrongswan/plugins/ntru/Makefile src/libstrongswan/plugins/bliss/Makefile src/libstrongswan/plugins/bliss/tests/Makefile src/libstrongswan/plugins/test_vectors/Makefile src/libstrongswan/tests/Makefile src/libipsec/Makefile src/libipsec/tests/Makefile src/libsimaka/Makefile src/libtls/Makefile src/libtls/tests/Makefile src/libradius/Makefile src/libtncif/Makefile src/libtnccs/Makefile src/libtnccs/plugins/tnc_tnccs/Makefile src/libtnccs/plugins/tnc_imc/Makefile src/libtnccs/plugins/tnc_imv/Makefile src/libtnccs/plugins/tnccs_11/Makefile src/libtnccs/plugins/tnccs_20/Makefile src/libtnccs/plugins/tnccs_dynamic/Makefile src/libpttls/Makefile src/libimcv/Makefile src/libimcv/plugins/imc_test/Makefile src/libimcv/plugins/imv_test/Makefile src/libimcv/plugins/imc_scanner/Makefile src/libimcv/plugins/imv_scanner/Makefile src/libimcv/plugins/imc_os/Makefile src/libimcv/plugins/imv_os/Makefile src/libimcv/plugins/imc_attestation/Makefile src/libimcv/plugins/imv_attestation/Makefile src/libimcv/plugins/imc_swid/Makefile src/libimcv/plugins/imv_swid/Makefile src/libimcv/plugins/imc_hcd/Makefile src/libimcv/plugins/imv_hcd/Makefile src/charon/Makefile src/charon-nm/Makefile src/charon-tkm/Makefile src/charon-cmd/Makefile src/charon-svc/Makefile src/charon-systemd/Makefile src/libcharon/Makefile src/libcharon/plugins/eap_aka/Makefile src/libcharon/plugins/eap_aka_3gpp2/Makefile src/libcharon/plugins/eap_dynamic/Makefile src/libcharon/plugins/eap_identity/Makefile src/libcharon/plugins/eap_md5/Makefile src/libcharon/plugins/eap_gtc/Makefile src/libcharon/plugins/eap_sim/Makefile src/libcharon/plugins/eap_sim_file/Makefile src/libcharon/plugins/eap_sim_pcsc/Makefile src/libcharon/plugins/eap_simaka_sql/Makefile src/libcharon/plugins/eap_simaka_pseudonym/Makefile src/libcharon/plugins/eap_simaka_reauth/Makefile src/libcharon/plugins/eap_mschapv2/Makefile src/libcharon/plugins/eap_tls/Makefile src/libcharon/plugins/eap_ttls/Makefile src/libcharon/plugins/eap_peap/Makefile src/libcharon/plugins/eap_tnc/Makefile src/libcharon/plugins/eap_radius/Makefile src/libcharon/plugins/xauth_generic/Makefile src/libcharon/plugins/xauth_eap/Makefile src/libcharon/plugins/xauth_pam/Makefile src/libcharon/plugins/xauth_noauth/Makefile src/libcharon/plugins/tnc_ifmap/Makefile src/libcharon/plugins/tnc_pdp/Makefile src/libcharon/plugins/socket_default/Makefile src/libcharon/plugins/socket_dynamic/Makefile src/libcharon/plugins/socket_win/Makefile src/libcharon/plugins/connmark/Makefile src/libcharon/plugins/forecast/Makefile src/libcharon/plugins/farp/Makefile src/libcharon/plugins/smp/Makefile src/libcharon/plugins/sql/Makefile src/libcharon/plugins/dnscert/Makefile src/libcharon/plugins/ipseckey/Makefile src/libcharon/plugins/medsrv/Makefile src/libcharon/plugins/medcli/Makefile src/libcharon/plugins/addrblock/Makefile src/libcharon/plugins/unity/Makefile src/libcharon/plugins/uci/Makefile src/libcharon/plugins/ha/Makefile src/libcharon/plugins/kernel_netlink/Makefile src/libcharon/plugins/kernel_pfkey/Makefile src/libcharon/plugins/kernel_pfroute/Makefile src/libcharon/plugins/kernel_libipsec/Makefile src/libcharon/plugins/kernel_wfp/Makefile src/libcharon/plugins/kernel_iph/Makefile src/libcharon/plugins/whitelist/Makefile src/libcharon/plugins/ext_auth/Makefile src/libcharon/plugins/lookip/Makefile src/libcharon/plugins/error_notify/Makefile src/libcharon/plugins/certexpire/Makefile src/libcharon/plugins/systime_fix/Makefile src/libcharon/plugins/led/Makefile src/libcharon/plugins/duplicheck/Makefile src/libcharon/plugins/coupling/Makefile src/libcharon/plugins/radattr/Makefile src/libcharon/plugins/osx_attr/Makefile src/libcharon/plugins/p_cscf/Makefile src/libcharon/plugins/android_dns/Makefile src/libcharon/plugins/android_log/Makefile src/libcharon/plugins/maemo/Makefile src/libcharon/plugins/stroke/Makefile src/libcharon/plugins/vici/Makefile src/libcharon/plugins/vici/ruby/Makefile src/libcharon/plugins/vici/perl/Makefile src/libcharon/plugins/vici/python/Makefile src/libcharon/plugins/updown/Makefile src/libcharon/plugins/dhcp/Makefile src/libcharon/plugins/load_tester/Makefile src/libcharon/plugins/resolve/Makefile src/libcharon/plugins/attr/Makefile src/libcharon/plugins/attr_sql/Makefile src/libcharon/tests/Makefile src/stroke/Makefile src/ipsec/Makefile src/starter/Makefile src/starter/tests/Makefile src/_updown/Makefile src/_copyright/Makefile src/scepclient/Makefile src/aikgen/Makefile src/pki/Makefile src/pki/man/Makefile src/pool/Makefile src/dumm/Makefile src/dumm/ext/extconf.rb src/libfast/Makefile src/manager/Makefile src/medsrv/Makefile src/checksum/Makefile src/conftest/Makefile src/pt-tls-client/Makefile src/swanctl/Makefile scripts/Makefile testing/Makefile" # ================= @@ -24711,6 +25085,10 @@ if test -z "${PYTHON_EGGS_INSTALL_TRUE}" && test -z "${PYTHON_EGGS_INSTALL_FALSE as_fn_error $? "conditional \"PYTHON_EGGS_INSTALL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${PERL_CPAN_INSTALL_TRUE}" && test -z "${PERL_CPAN_INSTALL_FALSE}"; then + as_fn_error $? "conditional \"PERL_CPAN_INSTALL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_TEST_VECTORS_TRUE}" && test -z "${USE_TEST_VECTORS_FALSE}"; then as_fn_error $? "conditional \"USE_TEST_VECTORS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -24947,6 +25325,10 @@ if test -z "${USE_OSX_ATTR_TRUE}" && test -z "${USE_OSX_ATTR_FALSE}"; then as_fn_error $? "conditional \"USE_OSX_ATTR\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_P_CSCF_TRUE}" && test -z "${USE_P_CSCF_FALSE}"; then + as_fn_error $? "conditional \"USE_P_CSCF\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_ANDROID_DNS_TRUE}" && test -z "${USE_ANDROID_DNS_FALSE}"; then as_fn_error $? "conditional \"USE_ANDROID_DNS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -24991,6 +25373,18 @@ if test -z "${USE_HA_TRUE}" && test -z "${USE_HA_FALSE}"; then as_fn_error $? "conditional \"USE_HA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_KERNEL_NETLINK_TRUE}" && test -z "${USE_KERNEL_NETLINK_FALSE}"; then + as_fn_error $? "conditional \"USE_KERNEL_NETLINK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_KERNEL_PFKEY_TRUE}" && test -z "${USE_KERNEL_PFKEY_FALSE}"; then + as_fn_error $? "conditional \"USE_KERNEL_PFKEY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_KERNEL_PFROUTE_TRUE}" && test -z "${USE_KERNEL_PFROUTE_FALSE}"; then + as_fn_error $? "conditional \"USE_KERNEL_PFROUTE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_KERNEL_LIBIPSEC_TRUE}" && test -z "${USE_KERNEL_LIBIPSEC_FALSE}"; then as_fn_error $? "conditional \"USE_KERNEL_LIBIPSEC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -25255,18 +25649,6 @@ if test -z "${USE_ATTR_SQL_TRUE}" && test -z "${USE_ATTR_SQL_FALSE}"; then as_fn_error $? "conditional \"USE_ATTR_SQL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${USE_KERNEL_NETLINK_TRUE}" && test -z "${USE_KERNEL_NETLINK_FALSE}"; then - as_fn_error $? "conditional \"USE_KERNEL_NETLINK\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_KERNEL_PFKEY_TRUE}" && test -z "${USE_KERNEL_PFKEY_FALSE}"; then - as_fn_error $? "conditional \"USE_KERNEL_PFKEY\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_KERNEL_PFROUTE_TRUE}" && test -z "${USE_KERNEL_PFROUTE_FALSE}"; then - as_fn_error $? "conditional \"USE_KERNEL_PFROUTE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${USE_LEAK_DETECTIVE_TRUE}" && test -z "${USE_LEAK_DETECTIVE_FALSE}"; then as_fn_error $? "conditional \"USE_LEAK_DETECTIVE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -25343,10 +25725,6 @@ if test -z "${USE_LIBSTRONGSWAN_TRUE}" && test -z "${USE_LIBSTRONGSWAN_FALSE}"; as_fn_error $? "conditional \"USE_LIBSTRONGSWAN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${USE_LIBHYDRA_TRUE}" && test -z "${USE_LIBHYDRA_FALSE}"; then - as_fn_error $? "conditional \"USE_LIBHYDRA\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${USE_LIBCHARON_TRUE}" && test -z "${USE_LIBCHARON_FALSE}"; then as_fn_error $? "conditional \"USE_LIBCHARON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -25459,6 +25837,10 @@ if test -z "${USE_PYTHON_EGGS_TRUE}" && test -z "${USE_PYTHON_EGGS_FALSE}"; then as_fn_error $? "conditional \"USE_PYTHON_EGGS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_PERL_CPAN_TRUE}" && test -z "${USE_PERL_CPAN_FALSE}"; then + as_fn_error $? "conditional \"USE_PERL_CPAN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_PY_TEST_TRUE}" && test -z "${USE_PY_TEST_FALSE}"; then as_fn_error $? "conditional \"USE_PY_TEST\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -25860,7 +26242,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by strongSwan $as_me 5.3.5, which was +This file was extended by strongSwan $as_me 5.4.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25926,7 +26308,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -strongSwan config.status 5.3.5 +strongSwan config.status 5.4.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -26399,11 +26781,6 @@ do "src/libstrongswan/plugins/bliss/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/bliss/tests/Makefile" ;; "src/libstrongswan/plugins/test_vectors/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/test_vectors/Makefile" ;; "src/libstrongswan/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/tests/Makefile" ;; - "src/libhydra/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/Makefile" ;; - "src/libhydra/plugins/kernel_netlink/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/kernel_netlink/Makefile" ;; - "src/libhydra/plugins/kernel_pfkey/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/kernel_pfkey/Makefile" ;; - "src/libhydra/plugins/kernel_pfroute/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/kernel_pfroute/Makefile" ;; - "src/libhydra/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/tests/Makefile" ;; "src/libipsec/Makefile") CONFIG_FILES="$CONFIG_FILES src/libipsec/Makefile" ;; "src/libipsec/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/libipsec/tests/Makefile" ;; "src/libsimaka/Makefile") CONFIG_FILES="$CONFIG_FILES src/libsimaka/Makefile" ;; @@ -26479,6 +26856,9 @@ do "src/libcharon/plugins/unity/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/unity/Makefile" ;; "src/libcharon/plugins/uci/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/uci/Makefile" ;; "src/libcharon/plugins/ha/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/ha/Makefile" ;; + "src/libcharon/plugins/kernel_netlink/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/kernel_netlink/Makefile" ;; + "src/libcharon/plugins/kernel_pfkey/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/kernel_pfkey/Makefile" ;; + "src/libcharon/plugins/kernel_pfroute/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/kernel_pfroute/Makefile" ;; "src/libcharon/plugins/kernel_libipsec/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/kernel_libipsec/Makefile" ;; "src/libcharon/plugins/kernel_wfp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/kernel_wfp/Makefile" ;; "src/libcharon/plugins/kernel_iph/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/kernel_iph/Makefile" ;; @@ -26493,12 +26873,14 @@ do "src/libcharon/plugins/coupling/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/coupling/Makefile" ;; "src/libcharon/plugins/radattr/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/radattr/Makefile" ;; "src/libcharon/plugins/osx_attr/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/osx_attr/Makefile" ;; + "src/libcharon/plugins/p_cscf/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/p_cscf/Makefile" ;; "src/libcharon/plugins/android_dns/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/android_dns/Makefile" ;; "src/libcharon/plugins/android_log/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/android_log/Makefile" ;; "src/libcharon/plugins/maemo/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/maemo/Makefile" ;; "src/libcharon/plugins/stroke/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/stroke/Makefile" ;; "src/libcharon/plugins/vici/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/vici/Makefile" ;; "src/libcharon/plugins/vici/ruby/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/vici/ruby/Makefile" ;; + "src/libcharon/plugins/vici/perl/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/vici/perl/Makefile" ;; "src/libcharon/plugins/vici/python/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/vici/python/Makefile" ;; "src/libcharon/plugins/updown/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/updown/Makefile" ;; "src/libcharon/plugins/dhcp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/dhcp/Makefile" ;; @@ -27923,8 +28305,6 @@ $as_echo "-----------------------------------------------------" >&6; } $as_echo "libstrongswan:$s_plugins" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: libcharon: $c_plugins" >&5 $as_echo "libcharon: $c_plugins" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: libhydra: $h_plugins" >&5 -$as_echo "libhydra: $h_plugins" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: libtnccs: $t_plugins" >&5 $as_echo "libtnccs: $t_plugins" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 diff --git a/configure.ac b/configure.ac index ea6bddb7d..9486907a2 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ # initialize & set some vars # ============================ -AC_INIT([strongSwan],[5.3.5]) +AC_INIT([strongSwan],[5.4.0]) AM_INIT_AUTOMAKE(m4_esyscmd([ echo tar-ustar echo subdir-objects @@ -221,13 +221,14 @@ ARG_DISBL_SET([stroke], [disable charons stroke configuration backend.]) ARG_ENABL_SET([smp], [enable SMP configuration and control interface. Requires libxml.]) ARG_ENABL_SET([sql], [enable SQL database configuration backend.]) ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.]) -ARG_ENABL_SET([vici], [enable strongSwan IKE generic IPC interface plugin.]) +ARG_DISBL_SET([vici], [disable strongSwan IKE generic IPC interface plugin.]) # attribute provider/consumer plugins ARG_ENABL_SET([android-dns], [enable Android specific DNS handler.]) ARG_DISBL_SET([attr], [disable strongswan.conf based configuration attribute plugin.]) ARG_ENABL_SET([attr-sql], [enable SQL based configuration attribute plugin.]) ARG_ENABL_SET([dhcp], [enable DHCP based attribute provider plugin.]) ARG_ENABL_SET([osx-attr], [enable OS X SystemConfiguration attribute handler.]) +ARG_ENABL_SET([p-cscf], [enable plugin to request P-CSCF server addresses from an ePDG.]) ARG_DISBL_SET([resolve], [disable resolve DNS handler plugin.]) ARG_ENABL_SET([unity], [enables Cisco Unity extension plugin.]) # TNC modules/plugins @@ -284,7 +285,7 @@ ARG_DISBL_SET([scepclient], [disable SCEP client tool.]) ARG_DISBL_SET([scripts], [disable additional utilities (found in directory scripts).]) ARG_ENABL_SET([svc], [enable charon Windows service.]) ARG_ENABL_SET([systemd], [enable systemd specific IKE daemon charon-systemd.]) -ARG_ENABL_SET([swanctl], [enable swanctl configuration and control tool.]) +ARG_DISBL_SET([swanctl], [disable swanctl configuration and control tool.]) ARG_ENABL_SET([tkm], [enable Trusted Key Manager support.]) # optional features ARG_ENABL_SET([bfd-backtraces], [use binutils libbfd to resolve backtraces for memory leaks and segfaults.]) @@ -299,10 +300,13 @@ ARG_ENABL_SET([ruby-gems], [enable build of provided ruby gems.]) ARG_ENABL_SET([ruby-gems-install],[enable installation of provided ruby gems.]) ARG_ENABL_SET([python-eggs], [enable build of provided python eggs.]) ARG_ENABL_SET([python-eggs-install],[enable installation of provided python eggs.]) +ARG_ENABL_SET([perl-cpan], [enable build of provided perl CPAN module.]) +ARG_ENABL_SET([perl-cpan-install],[enable installation of provided CPAN module.]) # compile options ARG_ENABL_SET([coverage], [enable lcov coverage report generation.]) ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.]) ARG_ENABL_SET([lock-profiler], [enable lock/mutex profiling code.]) +ARG_ENABL_SET([log-thread-ids], [use thread ID, if available, instead of an incremented value starting from 1, to identify threads.]) ARG_ENABL_SET([monolithic], [build monolithic version of libstrongswan that includes all enabled plugins. Similarly, the plugins of charon are assembled in libcharon.]) # =================================== @@ -447,6 +451,10 @@ if test x$python_eggs_install = xtrue; then python_eggs=true fi +if test x$perl_cpan_install = xtrue; then + perl_cpan=true +fi + # =========================================== # check required libraries and header files # =========================================== @@ -935,13 +943,16 @@ if test x$systemd = xtrue; then AC_MSG_ERROR([not found (try --with-systemdsystemunitdir)]) fi - PKG_CHECK_MODULES(systemd_daemon, [libsystemd-daemon]) - AC_SUBST(systemd_daemon_CFLAGS) - AC_SUBST(systemd_daemon_LIBS) - - PKG_CHECK_MODULES(systemd_journal, [libsystemd-journal]) - AC_SUBST(systemd_journal_CFLAGS) - AC_SUBST(systemd_journal_LIBS) + PKG_CHECK_MODULES(systemd, [libsystemd >= 209], + [AC_SUBST(systemd_CFLAGS) + AC_SUBST(systemd_LIBS)], + [PKG_CHECK_MODULES(systemd_daemon, [libsystemd-daemon]) + AC_SUBST(systemd_daemon_CFLAGS) + AC_SUBST(systemd_daemon_LIBS) + PKG_CHECK_MODULES(systemd_journal, [libsystemd-journal]) + AC_SUBST(systemd_journal_CFLAGS) + AC_SUBST(systemd_journal_LIBS)] + ) fi if test x$tss = xtrousers; then @@ -1063,7 +1074,8 @@ if test x$sqlite = xtrue; then fi if test x$openssl = xtrue; then - AC_CHECK_LIB([$openssl_lib],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([OpenSSL lib$openssl_lib not found])],[]) + AC_CHECK_LIB([$openssl_lib],[main],[LIBS="$LIBS"], + [AC_MSG_ERROR([OpenSSL lib$openssl_lib not found])],[$DLLIB]) AC_CHECK_HEADER([openssl/evp.h],,[AC_MSG_ERROR([OpenSSL header openssl/evp.h not found!])]) fi @@ -1247,6 +1259,8 @@ if test x$python_eggs = xtrue; then fi AM_CONDITIONAL(PYTHON_EGGS_INSTALL, [test "x$python_eggs_install" = xtrue]) +AM_CONDITIONAL(PERL_CPAN_INSTALL, [test "x$perl_cpan_install" = xtrue]) + # =============================================== # collect plugin list for strongSwan components # =============================================== @@ -1268,9 +1282,8 @@ cmd_plugins= aikgen_plugins= # location specific lists for checksumming, -# for src/libcharon, src/libhydra, src/libstrongswan and src/libtnccs +# for src/libcharon, src/libstrongswan and src/libtnccs c_plugins= -h_plugins= s_plugins= t_plugins= @@ -1283,9 +1296,9 @@ ADD_PLUGIN([aes], [s charon scepclient pki scripts nm cmd]) ADD_PLUGIN([des], [s charon scepclient pki scripts nm cmd]) ADD_PLUGIN([blowfish], [s charon scepclient pki scripts nm cmd]) ADD_PLUGIN([rc2], [s charon scepclient pki scripts nm cmd]) -ADD_PLUGIN([sha1], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen]) ADD_PLUGIN([sha2], [s charon scepclient pki scripts medsrv attest nm cmd aikgen]) ADD_PLUGIN([sha3], [s charon scepclient pki scripts medsrv attest nm cmd aikgen]) +ADD_PLUGIN([sha1], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen]) ADD_PLUGIN([md4], [s charon scepclient pki nm cmd]) ADD_PLUGIN([md5], [s charon scepclient pki scripts attest nm cmd aikgen]) ADD_PLUGIN([rdrand], [s charon scepclient pki scripts medsrv attest nm cmd aikgen]) @@ -1335,9 +1348,9 @@ ADD_PLUGIN([load-tester], [c charon]) ADD_PLUGIN([kernel-libipsec], [c charon cmd]) ADD_PLUGIN([kernel-wfp], [c charon]) ADD_PLUGIN([kernel-iph], [c charon]) -ADD_PLUGIN([kernel-pfkey], [h charon starter nm cmd]) -ADD_PLUGIN([kernel-pfroute], [h charon starter nm cmd]) -ADD_PLUGIN([kernel-netlink], [h charon starter nm cmd]) +ADD_PLUGIN([kernel-pfkey], [c charon starter nm cmd]) +ADD_PLUGIN([kernel-pfroute], [c charon starter nm cmd]) +ADD_PLUGIN([kernel-netlink], [c charon starter nm cmd]) ADD_PLUGIN([resolve], [c charon cmd]) ADD_PLUGIN([socket-default], [c charon nm cmd]) ADD_PLUGIN([socket-dynamic], [c charon cmd]) @@ -1384,6 +1397,7 @@ ADD_PLUGIN([medsrv], [c charon]) ADD_PLUGIN([medcli], [c charon]) ADD_PLUGIN([dhcp], [c charon]) ADD_PLUGIN([osx-attr], [c charon cmd]) +ADD_PLUGIN([p-cscf], [c charon cmd]) ADD_PLUGIN([android-dns], [c charon]) ADD_PLUGIN([android-log], [c charon]) ADD_PLUGIN([ha], [c charon]) @@ -1488,6 +1502,7 @@ AM_CONDITIONAL(USE_MEDSRV, test x$medsrv = xtrue) AM_CONDITIONAL(USE_MEDCLI, test x$medcli = xtrue) AM_CONDITIONAL(USE_UCI, test x$uci = xtrue) AM_CONDITIONAL(USE_OSX_ATTR, test x$osx_attr = xtrue) +AM_CONDITIONAL(USE_P_CSCF, test x$p_cscf = xtrue) AM_CONDITIONAL(USE_ANDROID_DNS, test x$android_dns = xtrue) AM_CONDITIONAL(USE_ANDROID_LOG, test x$android_log = xtrue) AM_CONDITIONAL(USE_MAEMO, test x$maemo = xtrue) @@ -1499,6 +1514,9 @@ AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue) AM_CONDITIONAL(USE_DHCP, test x$dhcp = xtrue) AM_CONDITIONAL(USE_LOAD_TESTER, test x$load_tester = xtrue) AM_CONDITIONAL(USE_HA, test x$ha = xtrue) +AM_CONDITIONAL(USE_KERNEL_NETLINK, test x$kernel_netlink = xtrue) +AM_CONDITIONAL(USE_KERNEL_PFKEY, test x$kernel_pfkey = xtrue) +AM_CONDITIONAL(USE_KERNEL_PFROUTE, test x$kernel_pfroute = xtrue) AM_CONDITIONAL(USE_KERNEL_LIBIPSEC, test x$kernel_libipsec = xtrue) AM_CONDITIONAL(USE_KERNEL_WFP, test x$kernel_wfp = xtrue) AM_CONDITIONAL(USE_KERNEL_IPH, test x$kernel_iph = xtrue) @@ -1566,12 +1584,6 @@ AM_CONDITIONAL(USE_RESOLVE, test x$resolve = xtrue) AM_CONDITIONAL(USE_ATTR, test x$attr = xtrue) AM_CONDITIONAL(USE_ATTR_SQL, test x$attr_sql = xtrue) -# hydra plugins -# --------------- -AM_CONDITIONAL(USE_KERNEL_NETLINK, test x$kernel_netlink = xtrue) -AM_CONDITIONAL(USE_KERNEL_PFKEY, test x$kernel_pfkey = xtrue) -AM_CONDITIONAL(USE_KERNEL_PFROUTE, test x$kernel_pfroute = xtrue) - # other options # --------------- AM_CONDITIONAL(USE_LEAK_DETECTIVE, test x$leak_detective = xtrue) @@ -1593,7 +1605,6 @@ AM_CONDITIONAL(USE_SCEPCLIENT, test x$scepclient = xtrue) AM_CONDITIONAL(USE_SCRIPTS, test x$scripts = xtrue) AM_CONDITIONAL(USE_CONFTEST, test x$conftest = xtrue) AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$pki = xtrue -o x$scepclient = xtrue -o x$conftest = xtrue -o x$fast = xtrue -o x$imcv = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$tls = xtrue -o x$tnc_tnccs = xtrue -o x$aikgen = xtrue -o x$svc = xtrue -o x$systemd = xtrue) -AM_CONDITIONAL(USE_LIBHYDRA, test x$charon = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$svc = xtrue -o x$systemd = xtrue) AM_CONDITIONAL(USE_LIBCHARON, test x$charon = xtrue -o x$conftest = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$svc = xtrue -o x$systemd = xtrue) AM_CONDITIONAL(USE_LIBIPSEC, test x$libipsec = xtrue) AM_CONDITIONAL(USE_LIBTNCIF, test x$tnc_tnccs = xtrue -o x$imcv = xtrue) @@ -1622,6 +1633,7 @@ AM_CONDITIONAL(USE_SYSTEMD, test x$systemd = xtrue) AM_CONDITIONAL(USE_LEGACY_SYSTEMD, test -n "$systemdsystemunitdir" -a "x$systemdsystemunitdir" != xno) AM_CONDITIONAL(USE_RUBY_GEMS, test x$ruby_gems = xtrue) AM_CONDITIONAL(USE_PYTHON_EGGS, test x$python_eggs = xtrue) +AM_CONDITIONAL(USE_PERL_CPAN, test x$perl_cpan = xtrue) AM_CONDITIONAL(USE_PY_TEST, test "x$PY_TEST" != x) # ======================== @@ -1634,6 +1646,9 @@ fi if test x$capabilities = xlibcap -o x$capabilities = xnative; then AC_DEFINE([CAPABILITIES], [], [capability dropping support]) fi +if test x$log_thread_ids = xtrue; then + AC_DEFINE([USE_THREAD_IDS], [], [use thread ID for thread identification, if available]) +fi if test x$monolithic = xtrue; then AC_DEFINE([MONOLITHIC], [], [monolithic build embedding plugins]) fi @@ -1735,11 +1750,6 @@ AC_CONFIG_FILES([ src/libstrongswan/plugins/bliss/tests/Makefile src/libstrongswan/plugins/test_vectors/Makefile src/libstrongswan/tests/Makefile - src/libhydra/Makefile - src/libhydra/plugins/kernel_netlink/Makefile - src/libhydra/plugins/kernel_pfkey/Makefile - src/libhydra/plugins/kernel_pfroute/Makefile - src/libhydra/tests/Makefile src/libipsec/Makefile src/libipsec/tests/Makefile src/libsimaka/Makefile @@ -1815,6 +1825,9 @@ AC_CONFIG_FILES([ src/libcharon/plugins/unity/Makefile src/libcharon/plugins/uci/Makefile src/libcharon/plugins/ha/Makefile + src/libcharon/plugins/kernel_netlink/Makefile + src/libcharon/plugins/kernel_pfkey/Makefile + src/libcharon/plugins/kernel_pfroute/Makefile src/libcharon/plugins/kernel_libipsec/Makefile src/libcharon/plugins/kernel_wfp/Makefile src/libcharon/plugins/kernel_iph/Makefile @@ -1829,12 +1842,14 @@ AC_CONFIG_FILES([ src/libcharon/plugins/coupling/Makefile src/libcharon/plugins/radattr/Makefile src/libcharon/plugins/osx_attr/Makefile + src/libcharon/plugins/p_cscf/Makefile src/libcharon/plugins/android_dns/Makefile src/libcharon/plugins/android_log/Makefile src/libcharon/plugins/maemo/Makefile src/libcharon/plugins/stroke/Makefile src/libcharon/plugins/vici/Makefile src/libcharon/plugins/vici/ruby/Makefile + src/libcharon/plugins/vici/perl/Makefile src/libcharon/plugins/vici/python/Makefile src/libcharon/plugins/updown/Makefile src/libcharon/plugins/dhcp/Makefile @@ -1908,6 +1923,5 @@ AC_MSG_RESULT([-----------------------------------------------------]) AC_MSG_RESULT([libstrongswan:$s_plugins]) AC_MSG_RESULT([libcharon: $c_plugins]) -AC_MSG_RESULT([libhydra: $h_plugins]) AC_MSG_RESULT([libtnccs: $t_plugins]) AC_MSG_RESULT([]) diff --git a/init/Makefile.in b/init/Makefile.in index 883d42403..72ee05912 100644 --- a/init/Makefile.in +++ b/init/Makefile.in @@ -391,6 +391,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/init/systemd-swanctl/Makefile.in b/init/systemd-swanctl/Makefile.in index 28cedbda8..0c5f5ce18 100644 --- a/init/systemd-swanctl/Makefile.in +++ b/init/systemd-swanctl/Makefile.in @@ -359,6 +359,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/init/systemd-swanctl/strongswan-swanctl.service.in b/init/systemd-swanctl/strongswan-swanctl.service.in index 818d352d5..944101faf 100644 --- a/init/systemd-swanctl/strongswan-swanctl.service.in +++ b/init/systemd-swanctl/strongswan-swanctl.service.in @@ -7,3 +7,6 @@ Type=notify ExecStart=@SBINDIR@/charon-systemd ExecStartPost=@SBINDIR@/swanctl --load-all --noprompt ExecReload=@SBINDIR@/swanctl --reload + +[Install] +WantedBy=multi-user.target diff --git a/init/systemd/Makefile.in b/init/systemd/Makefile.in index 808023eb2..ab7d64766 100644 --- a/init/systemd/Makefile.in +++ b/init/systemd/Makefile.in @@ -359,6 +359,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/man/Makefile.in b/man/Makefile.in index 501361003..5f621c201 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -365,6 +365,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/man/ipsec.conf.5.in b/man/ipsec.conf.5.in index 61804c8b3..54440c0c7 100644 --- a/man/ipsec.conf.5.in +++ b/man/ipsec.conf.5.in @@ -402,7 +402,7 @@ or keyword may be used, AH+ESP bundles are not supported. Defaults to -.BR aes128-sha1,3des-sha1 . +.BR aes128-sha256 . The daemon adds its extensive default proposal to this default or the configured value. To restrict it to the configured proposal an exclamation mark @@ -453,7 +453,7 @@ if required. .BR ike " = " comma-separated list of IKE/ISAKMP SA encryption/authentication algorithms to be used, e.g. -.BR aes128-sha1-modp2048 . +.BR aes128-sha256-modp3072 . The notation is .BR encryption-integrity[-prf]-dhgroup . If no PRF is given, the algorithms defined for integrity are used for the PRF. @@ -466,10 +466,10 @@ or .BR prfaesxcbc ). .br In IKEv2, multiple algorithms and proposals may be included, such as -.BR aes128-aes256-sha1-modp1536-modp2048,3des-sha1-md5-modp1024 . +.BR aes128-aes256-sha1-modp3072-modp2048,3des-sha1-md5-modp1024 . Defaults to -.BR aes128-sha1-modp2048,3des-sha1-modp1536 . +.BR aes128-sha256-modp3072 . The daemon adds its extensive default proposal to this default or the configured value. To restrict it to the configured proposal an exclamation mark @@ -587,18 +587,23 @@ or a key strength definition (for example or .BR rsa-2048-ecdsa-256-sha256-sha384-sha512 ). Unless disabled in -.BR strongswan.conf (5) -such key types and hash algorithms are also applied as constraints against IKEv2 +.BR strongswan.conf (5), +or explicit IKEv2 signature constraints are configured (see below), such key +types and hash algorithms are also applied as constraints against IKEv2 signature authentication schemes used by the remote side. If both peers support RFC 7427 ("Signature Authentication in IKEv2") specific hash algorithms to be used during IKEv2 authentication may be configured. -The syntax is the same as above. For example, with -.B pubkey-sha384-sha256 +The syntax is the same as above, but with ike: prefix. For example, with +.B ike:pubkey-sha384-sha256 a public key signature scheme with either SHA-384 or SHA-256 would get used for authentication, in that order and depending on the hash algorithms supported by the peer. If no specific hash algorithms are configured, the default is to prefer an algorithm that matches or exceeds the strength of the signature key. +If no constraints with ike: prefix are configured any signature scheme +constraint (without ike: prefix) will also apply to IKEv2 authentication, unless +this is disabled in +.BR strongswan.conf (5). For .BR eap , diff --git a/scripts/Makefile.in b/scripts/Makefile.in index bdb8e5ffc..15e90064c 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -474,6 +474,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/src/Makefile.am b/src/Makefile.am index 9608a3a13..a9df10cc6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,10 +4,6 @@ if USE_LIBSTRONGSWAN SUBDIRS += libstrongswan endif -if USE_LIBHYDRA - SUBDIRS += libhydra -endif - if USE_LIBIPSEC SUBDIRS += libipsec endif diff --git a/src/Makefile.in b/src/Makefile.in index 7596e7e55..1d012fb22 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -78,39 +78,38 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USE_LIBSTRONGSWAN_TRUE@am__append_1 = libstrongswan -@USE_LIBHYDRA_TRUE@am__append_2 = libhydra -@USE_LIBIPSEC_TRUE@am__append_3 = libipsec -@USE_SIMAKA_TRUE@am__append_4 = libsimaka -@USE_TLS_TRUE@am__append_5 = libtls -@USE_RADIUS_TRUE@am__append_6 = libradius -@USE_LIBTNCIF_TRUE@am__append_7 = libtncif -@USE_LIBTNCCS_TRUE@am__append_8 = libtnccs -@USE_LIBPTTLS_TRUE@am__append_9 = libpttls -@USE_IMCV_TRUE@am__append_10 = libimcv -@USE_LIBCHARON_TRUE@am__append_11 = libcharon -@USE_FILE_CONFIG_TRUE@am__append_12 = starter -@USE_IPSEC_SCRIPT_TRUE@am__append_13 = ipsec _copyright -@USE_CHARON_TRUE@am__append_14 = charon -@USE_SYSTEMD_TRUE@am__append_15 = charon-systemd -@USE_NM_TRUE@am__append_16 = charon-nm -@USE_STROKE_TRUE@am__append_17 = stroke -@USE_UPDOWN_TRUE@am__append_18 = _updown -@USE_SCEPCLIENT_TRUE@am__append_19 = scepclient -@USE_PKI_TRUE@am__append_20 = pki -@USE_SWANCTL_TRUE@am__append_21 = swanctl -@USE_CONFTEST_TRUE@am__append_22 = conftest -@USE_DUMM_TRUE@am__append_23 = dumm -@USE_FAST_TRUE@am__append_24 = libfast -@USE_MANAGER_TRUE@am__append_25 = manager -@USE_MEDSRV_TRUE@am__append_26 = medsrv -@USE_ATTR_SQL_TRUE@am__append_27 = pool -@USE_ATTR_SQL_FALSE@@USE_SQL_TRUE@am__append_28 = pool -@USE_TKM_TRUE@am__append_29 = charon-tkm -@USE_CMD_TRUE@am__append_30 = charon-cmd -@USE_SVC_TRUE@am__append_31 = charon-svc -@USE_LIBPTTLS_TRUE@am__append_32 = pt-tls-client -@USE_INTEGRITY_TEST_TRUE@am__append_33 = checksum -@USE_AIKGEN_TRUE@am__append_34 = aikgen +@USE_LIBIPSEC_TRUE@am__append_2 = libipsec +@USE_SIMAKA_TRUE@am__append_3 = libsimaka +@USE_TLS_TRUE@am__append_4 = libtls +@USE_RADIUS_TRUE@am__append_5 = libradius +@USE_LIBTNCIF_TRUE@am__append_6 = libtncif +@USE_LIBTNCCS_TRUE@am__append_7 = libtnccs +@USE_LIBPTTLS_TRUE@am__append_8 = libpttls +@USE_IMCV_TRUE@am__append_9 = libimcv +@USE_LIBCHARON_TRUE@am__append_10 = libcharon +@USE_FILE_CONFIG_TRUE@am__append_11 = starter +@USE_IPSEC_SCRIPT_TRUE@am__append_12 = ipsec _copyright +@USE_CHARON_TRUE@am__append_13 = charon +@USE_SYSTEMD_TRUE@am__append_14 = charon-systemd +@USE_NM_TRUE@am__append_15 = charon-nm +@USE_STROKE_TRUE@am__append_16 = stroke +@USE_UPDOWN_TRUE@am__append_17 = _updown +@USE_SCEPCLIENT_TRUE@am__append_18 = scepclient +@USE_PKI_TRUE@am__append_19 = pki +@USE_SWANCTL_TRUE@am__append_20 = swanctl +@USE_CONFTEST_TRUE@am__append_21 = conftest +@USE_DUMM_TRUE@am__append_22 = dumm +@USE_FAST_TRUE@am__append_23 = libfast +@USE_MANAGER_TRUE@am__append_24 = manager +@USE_MEDSRV_TRUE@am__append_25 = medsrv +@USE_ATTR_SQL_TRUE@am__append_26 = pool +@USE_ATTR_SQL_FALSE@@USE_SQL_TRUE@am__append_27 = pool +@USE_TKM_TRUE@am__append_28 = charon-tkm +@USE_CMD_TRUE@am__append_29 = charon-cmd +@USE_SVC_TRUE@am__append_30 = charon-svc +@USE_LIBPTTLS_TRUE@am__append_31 = pt-tls-client +@USE_INTEGRITY_TEST_TRUE@am__append_32 = checksum +@USE_AIKGEN_TRUE@am__append_33 = aikgen subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -184,12 +183,12 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = . include libstrongswan libhydra libipsec libsimaka \ - libtls libradius libtncif libtnccs libpttls libimcv libcharon \ - starter ipsec _copyright charon charon-systemd charon-nm \ - stroke _updown scepclient pki swanctl conftest dumm libfast \ - manager medsrv pool charon-tkm charon-cmd charon-svc \ - pt-tls-client checksum aikgen +DIST_SUBDIRS = . include libstrongswan libipsec libsimaka libtls \ + libradius libtncif libtnccs libpttls libimcv libcharon starter \ + ipsec _copyright charon charon-systemd charon-nm stroke \ + _updown scepclient pki swanctl conftest dumm libfast manager \ + medsrv pool charon-tkm charon-cmd charon-svc pt-tls-client \ + checksum aikgen DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -428,6 +427,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -451,8 +452,7 @@ SUBDIRS = . include $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_22) $(am__append_23) $(am__append_24) \ $(am__append_25) $(am__append_26) $(am__append_27) \ $(am__append_28) $(am__append_29) $(am__append_30) \ - $(am__append_31) $(am__append_32) $(am__append_33) \ - $(am__append_34) + $(am__append_31) $(am__append_32) $(am__append_33) all: all-recursive .SUFFIXES: diff --git a/src/_copyright/Makefile.in b/src/_copyright/Makefile.in index 2a4838c9a..432bde59b 100644 --- a/src/_copyright/Makefile.in +++ b/src/_copyright/Makefile.in @@ -382,6 +382,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in index fe31dff64..08fce3e2c 100644 --- a/src/_updown/Makefile.in +++ b/src/_updown/Makefile.in @@ -359,6 +359,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/src/aikgen/Makefile.in b/src/aikgen/Makefile.in index 33ed13397..8fb9126e5 100644 --- a/src/aikgen/Makefile.in +++ b/src/aikgen/Makefile.in @@ -385,6 +385,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/src/charon-cmd/Makefile.am b/src/charon-cmd/Makefile.am index 73df45072..1f4033aad 100644 --- a/src/charon-cmd/Makefile.am +++ b/src/charon-cmd/Makefile.am @@ -12,7 +12,6 @@ charon-cmd.o : $(top_builddir)/config.status AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" \ @@ -20,6 +19,5 @@ AM_CPPFLAGS = \ charon_cmd_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(DLLIB) diff --git a/src/charon-cmd/Makefile.in b/src/charon-cmd/Makefile.in index 64dea34c7..f48410270 100644 --- a/src/charon-cmd/Makefile.in +++ b/src/charon-cmd/Makefile.in @@ -109,7 +109,6 @@ charon_cmd_OBJECTS = $(am_charon_cmd_OBJECTS) am__DEPENDENCIES_1 = charon_cmd_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) @@ -419,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -442,7 +443,6 @@ charon_cmd_SOURCES = \ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" \ @@ -450,7 +450,6 @@ AM_CPPFLAGS = \ charon_cmd_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(DLLIB) diff --git a/src/charon-cmd/charon-cmd.c b/src/charon-cmd/charon-cmd.c index d3b31cc0d..f350198c6 100644 --- a/src/charon-cmd/charon-cmd.c +++ b/src/charon-cmd/charon-cmd.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -330,11 +329,6 @@ int main(int argc, char *argv[]) exit(SS_RC_DAEMON_INTEGRITY); } } - atexit(libhydra_deinit); - if (!libhydra_init()) - { - exit(SS_RC_INITIALIZATION_FAILED); - } atexit(libcharon_deinit); if (!libcharon_init()) { diff --git a/src/charon-nm/Makefile.am b/src/charon-nm/Makefile.am index d3630ffd5..b6f0c8b54 100644 --- a/src/charon-nm/Makefile.am +++ b/src/charon-nm/Makefile.am @@ -9,7 +9,6 @@ charon_nm_SOURCES = \ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" \ @@ -21,6 +20,5 @@ AM_CFLAGS = \ charon_nm_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(DLLIB) ${nm_LIBS} diff --git a/src/charon-nm/Makefile.in b/src/charon-nm/Makefile.in index 82f6fbcb2..490a08023 100644 --- a/src/charon-nm/Makefile.in +++ b/src/charon-nm/Makefile.in @@ -109,7 +109,6 @@ charon_nm_OBJECTS = $(am_charon_nm_OBJECTS) am__DEPENDENCIES_1 = charon_nm_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @@ -390,6 +389,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -412,7 +413,6 @@ charon_nm_SOURCES = \ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" \ @@ -424,7 +424,6 @@ AM_CFLAGS = \ charon_nm_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(DLLIB) ${nm_LIBS} diff --git a/src/charon-nm/charon-nm.c b/src/charon-nm/charon-nm.c index fb090e5d3..cbbed7ac1 100644 --- a/src/charon-nm/charon-nm.c +++ b/src/charon-nm/charon-nm.c @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -177,14 +176,6 @@ int main(int argc, char *argv[]) exit(SS_RC_DAEMON_INTEGRITY); } - if (!libhydra_init()) - { - dbg_syslog(DBG_DMN, 1, "initialization failed - aborting charon-nm"); - libhydra_deinit(); - library_deinit(); - exit(SS_RC_INITIALIZATION_FAILED); - } - if (!libcharon_init()) { dbg_syslog(DBG_DMN, 1, "initialization failed - aborting charon-nm"); @@ -212,7 +203,6 @@ int main(int argc, char *argv[]) { DBG1(DBG_DMN, "integrity tests enabled:"); DBG1(DBG_DMN, "lib 'libstrongswan': passed file and segment integrity tests"); - DBG1(DBG_DMN, "lib 'libhydra': passed file and segment integrity tests"); DBG1(DBG_DMN, "lib 'libcharon': passed file and segment integrity tests"); DBG1(DBG_DMN, "daemon 'charon-nm': passed file integrity test"); } @@ -260,7 +250,6 @@ int main(int argc, char *argv[]) deinit: libcharon_deinit(); - libhydra_deinit(); library_deinit(); return status; } diff --git a/src/charon-svc/Makefile.am b/src/charon-svc/Makefile.am index ecccf02f5..c91ad08f8 100644 --- a/src/charon-svc/Makefile.am +++ b/src/charon-svc/Makefile.am @@ -6,11 +6,9 @@ charon-svc.o : $(top_builddir)/config.status AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DPLUGINS=\""${charon_plugins}\"" charon_svc_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la diff --git a/src/charon-svc/Makefile.in b/src/charon-svc/Makefile.in index 1c0a4058d..4f9143d9b 100644 --- a/src/charon-svc/Makefile.in +++ b/src/charon-svc/Makefile.in @@ -105,7 +105,6 @@ am_charon_svc_OBJECTS = charon-svc.$(OBJEXT) charon_svc_OBJECTS = $(am_charon_svc_OBJECTS) charon_svc_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -384,6 +383,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -400,13 +401,11 @@ xml_LIBS = @xml_LIBS@ charon_svc_SOURCES = charon-svc.c AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DPLUGINS=\""${charon_plugins}\"" charon_svc_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la all: all-am diff --git a/src/charon-svc/charon-svc.c b/src/charon-svc/charon-svc.c index 03cbdb871..823b366c0 100644 --- a/src/charon-svc/charon-svc.c +++ b/src/charon-svc/charon-svc.c @@ -14,7 +14,6 @@ */ #include -#include #include #include @@ -189,6 +188,15 @@ static int service_wait() return 0; } +/** + * Add namespace alias + */ +static void __attribute__ ((constructor))register_namespace() +{ + /* inherit settings from charon */ + library_add_namespace("charon"); +} + /** * Initialize and run charon using a wait function */ @@ -210,28 +218,22 @@ static void init_and_run(DWORD dwArgc, LPTSTR *lpszArgv, int (*wait)()) if (library_init(NULL, SERVICE_NAME)) { update_status(SERVICE_START_PENDING); - if (libhydra_init()) + if (libcharon_init()) { + charon->load_loggers(charon, levels, TRUE); + print_version(); update_status(SERVICE_START_PENDING); - if (libcharon_init()) + if (charon->initialize(charon, PLUGINS)) { - charon->load_loggers(charon, levels, TRUE); - print_version(); update_status(SERVICE_START_PENDING); - if (charon->initialize(charon, PLUGINS)) - { - update_status(SERVICE_START_PENDING); - lib->plugins->status(lib->plugins, LEVEL_CTRL); + lib->plugins->status(lib->plugins, LEVEL_CTRL); - charon->start(charon); + charon->start(charon); - status.dwWin32ExitCode = wait(); - } - update_status(SERVICE_STOP_PENDING); - libcharon_deinit(); + status.dwWin32ExitCode = wait(); } update_status(SERVICE_STOP_PENDING); - libhydra_deinit(); + libcharon_deinit(); } update_status(SERVICE_STOP_PENDING); library_deinit(); diff --git a/src/charon-systemd/Makefile.am b/src/charon-systemd/Makefile.am index 1b9ac150f..9942a3682 100644 --- a/src/charon-systemd/Makefile.am +++ b/src/charon-systemd/Makefile.am @@ -7,13 +7,11 @@ charon-systemd.o : $(top_builddir)/config.status charon_systemd_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ - $(systemd_daemon_CFLAGS) $(systemd_journal_CFLAGS) \ + $(systemd_CFLAGS) $(systemd_daemon_CFLAGS) $(systemd_journal_CFLAGS) \ -DPLUGINS=\""${charon_plugins}\"" charon_systemd_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ - $(systemd_daemon_LIBS) $(systemd_journal_LIBS) -lm $(PTHREADLIB) $(DLLIB) + $(systemd_LIBS) $(systemd_daemon_LIBS) $(systemd_journal_LIBS) -lm $(PTHREADLIB) $(DLLIB) diff --git a/src/charon-systemd/Makefile.in b/src/charon-systemd/Makefile.in index d6e1c471c..b4f624d45 100644 --- a/src/charon-systemd/Makefile.in +++ b/src/charon-systemd/Makefile.in @@ -106,10 +106,10 @@ charon_systemd_OBJECTS = $(am_charon_systemd_OBJECTS) am__DEPENDENCIES_1 = charon_systemd_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -387,6 +387,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -405,16 +407,14 @@ charon-systemd.c charon_systemd_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ - $(systemd_daemon_CFLAGS) $(systemd_journal_CFLAGS) \ + $(systemd_CFLAGS) $(systemd_daemon_CFLAGS) $(systemd_journal_CFLAGS) \ -DPLUGINS=\""${charon_plugins}\"" charon_systemd_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ - $(systemd_daemon_LIBS) $(systemd_journal_LIBS) -lm $(PTHREADLIB) $(DLLIB) + $(systemd_LIBS) $(systemd_daemon_LIBS) $(systemd_journal_LIBS) -lm $(PTHREADLIB) $(DLLIB) all: all-am diff --git a/src/charon-systemd/charon-systemd.c b/src/charon-systemd/charon-systemd.c index 4286cde82..5c7bbd779 100644 --- a/src/charon-systemd/charon-systemd.c +++ b/src/charon-systemd/charon-systemd.c @@ -31,7 +31,6 @@ #include #include -#include #include #include @@ -325,6 +324,15 @@ static plugin_feature_t features[] = { PLUGIN_PROVIDE(CUSTOM, "systemd-journal"), }; +/** + * Add namespace alias + */ +static void __attribute__ ((constructor))register_namespace() +{ + /* inherit settings from charon */ + library_add_namespace("charon"); +} + /** * Main function, starts the daemon. */ @@ -355,12 +363,6 @@ int main(int argc, char *argv[]) sd_notifyf(0, "STATUS=integrity check of charon-systemd failed"); return SS_RC_INITIALIZATION_FAILED; } - atexit(libhydra_deinit); - if (!libhydra_init()) - { - sd_notifyf(0, "STATUS=libhydra initialization failed"); - return SS_RC_INITIALIZATION_FAILED; - } atexit(libcharon_deinit); if (!libcharon_init()) { diff --git a/src/charon-tkm/Makefile.am b/src/charon-tkm/Makefile.am index d2b81a3ea..ad54eafc0 100644 --- a/src/charon-tkm/Makefile.am +++ b/src/charon-tkm/Makefile.am @@ -4,15 +4,13 @@ OBJ = $(abs_top_builddir)/src AM_CPPFLAGS = \ -include $(abs_top_builddir)/config.h \ -I$(SRC)/libstrongswan \ - -I$(SRC)/libhydra \ -I$(SRC)/libcharon LIBLD = \ -L$(OBJ)/libstrongswan/.libs \ - -L$(OBJ)/libhydra/.libs \ -L$(OBJ)/libcharon/.libs -LIBPT = $(OBJ)/libstrongswan/.libs:$(OBJ)/libhydra/.libs:$(OBJ)/libcharon/.libs -LIBFL = -lstrongswan -lhydra -lcharon +LIBPT = $(OBJ)/libstrongswan/.libs:$(OBJ)/libcharon/.libs +LIBFL = -lstrongswan -lcharon DEFS += -DPLUGINS=\""$(PLUGINS)\"" -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/charon-tkm/Makefile.in b/src/charon-tkm/Makefile.in index bff198ab8..81afd4de5 100644 --- a/src/charon-tkm/Makefile.in +++ b/src/charon-tkm/Makefile.in @@ -329,6 +329,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -347,16 +349,14 @@ OBJ = $(abs_top_builddir)/src AM_CPPFLAGS = \ -include $(abs_top_builddir)/config.h \ -I$(SRC)/libstrongswan \ - -I$(SRC)/libhydra \ -I$(SRC)/libcharon LIBLD = \ -L$(OBJ)/libstrongswan/.libs \ - -L$(OBJ)/libhydra/.libs \ -L$(OBJ)/libcharon/.libs -LIBPT = $(OBJ)/libstrongswan/.libs:$(OBJ)/libhydra/.libs:$(OBJ)/libcharon/.libs -LIBFL = -lstrongswan -lhydra -lcharon +LIBPT = $(OBJ)/libstrongswan/.libs:$(OBJ)/libcharon/.libs +LIBFL = -lstrongswan -lcharon BUILD_OPTS = \ -XOBJ_DIR=$(abs_builddir)/obj \ -cargs $(AM_CPPFLAGS) $(DEFS) \ diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c index 3923c8ae6..13352e55a 100644 --- a/src/charon-tkm/src/charon-tkm.c +++ b/src/charon-tkm/src/charon-tkm.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -256,14 +255,6 @@ int main(int argc, char *argv[]) exit(status); } - if (!libhydra_init()) - { - dbg_syslog(DBG_DMN, 1, "initialization failed - aborting %s", dmn_name); - libhydra_deinit(); - library_deinit(); - exit(status); - } - if (!libcharon_init()) { dbg_syslog(DBG_DMN, 1, "initialization failed - aborting %s", dmn_name); @@ -391,7 +382,6 @@ int main(int argc, char *argv[]) deinit: destroy_dh_mapping(); libcharon_deinit(); - libhydra_deinit(); library_deinit(); tkm_deinit(); return status; diff --git a/src/charon-tkm/src/ees/ees_callbacks.c b/src/charon-tkm/src/ees/ees_callbacks.c index 74c0d3618..f4107d90a 100644 --- a/src/charon-tkm/src/ees/ees_callbacks.c +++ b/src/charon-tkm/src/ees/ees_callbacks.c @@ -14,7 +14,7 @@ * for more details. */ -#include +#include #include #include #include @@ -25,8 +25,7 @@ void charon_esa_acquire(result_type *res, const sp_id_type sp_id) { DBG1(DBG_KNL, "ees: acquire received for reqid %u", sp_id); - hydra->kernel_interface->acquire(hydra->kernel_interface, sp_id, NULL, - NULL); + charon->kernel->acquire(charon->kernel, sp_id, NULL, NULL); *res = TKM_OK; } @@ -47,6 +46,5 @@ void charon_esa_expire(result_type *res, const sp_id_type sp_id, DBG1(DBG_KNL, "ees: expire received for reqid %u, spi %x, dst %H", sp_id, ntohl(spi_rem), dst); - hydra->kernel_interface->expire(hydra->kernel_interface, protocol, - spi_rem, dst, hard != 0); + charon->kernel->expire(charon->kernel, protocol, spi_rem, dst, hard != 0); } diff --git a/src/charon-tkm/tests/keymat_tests.c b/src/charon-tkm/tests/keymat_tests.c index d087bee3f..8bba1f9d9 100644 --- a/src/charon-tkm/tests/keymat_tests.c +++ b/src/charon-tkm/tests/keymat_tests.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/src/charon-tkm/tests/tests.c b/src/charon-tkm/tests/tests.c index ac152b690..e3cd2d903 100644 --- a/src/charon-tkm/tests/tests.c +++ b/src/charon-tkm/tests/tests.c @@ -18,7 +18,6 @@ #include #include -#include #include #include "tkm.h" @@ -50,7 +49,6 @@ static bool test_runner_init(bool init) if (init) { - libhydra_init(); libcharon_init(); lib->settings->set_int(lib->settings, "test-runner.filelog.stdout.default", 0); @@ -74,8 +72,6 @@ static bool test_runner_init(bool init) plugin_loader_add_plugindirs(BUILDDIR "/src/libstrongswan/plugins", PLUGINS); - plugin_loader_add_plugindirs(BUILDDIR "/src/libhydra/plugins", - PLUGINS); plugin_loader_add_plugindirs(BUILDDIR "/src/libcharon/plugins", PLUGINS); if (charon->initialize(charon, PLUGINS)) @@ -95,7 +91,6 @@ static bool test_runner_init(bool init) destroy_dh_mapping(); libcharon_deinit(); - libhydra_deinit(); return result; } diff --git a/src/charon/Android.mk b/src/charon/Android.mk index 852d73c10..92a027094 100644 --- a/src/charon/Android.mk +++ b/src/charon/Android.mk @@ -8,7 +8,6 @@ charon.c # build charon ----------------------------------------------------------------- LOCAL_C_INCLUDES += \ - $(strongswan_PATH)/src/libhydra \ $(strongswan_PATH)/src/libcharon \ $(strongswan_PATH)/src/libstrongswan @@ -23,7 +22,7 @@ LOCAL_ARM_MODE := arm LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES += libstrongswan libhydra libcharon +LOCAL_SHARED_LIBRARIES += libstrongswan libcharon include $(BUILD_EXECUTABLE) diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index 6c5b88eb8..c6a6f40f9 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -7,7 +7,6 @@ charon.o : $(top_builddir)/config.status AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" \ @@ -15,7 +14,6 @@ AM_CPPFLAGS = \ charon_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(DLLIB) diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in index e1cc5c202..b4abeff25 100644 --- a/src/charon/Makefile.in +++ b/src/charon/Makefile.in @@ -106,7 +106,6 @@ charon_OBJECTS = $(am_charon_OBJECTS) am__DEPENDENCIES_1 = charon_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) @@ -386,6 +385,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -404,7 +405,6 @@ charon.c AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" \ @@ -412,7 +412,6 @@ AM_CPPFLAGS = \ charon_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(DLLIB) diff --git a/src/charon/charon.c b/src/charon/charon.c index 4c2a9a477..116ce7e93 100644 --- a/src/charon/charon.c +++ b/src/charon/charon.c @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -309,14 +308,6 @@ int main(int argc, char *argv[]) exit(SS_RC_DAEMON_INTEGRITY); } - if (!libhydra_init()) - { - dbg_stderr(DBG_DMN, 1, "initialization failed - aborting charon"); - libhydra_deinit(); - library_deinit(); - exit(SS_RC_INITIALIZATION_FAILED); - } - if (!libcharon_init()) { dbg_stderr(DBG_DMN, 1, "initialization failed - aborting charon"); @@ -403,7 +394,6 @@ int main(int argc, char *argv[]) { DBG1(DBG_DMN, "integrity tests enabled:"); DBG1(DBG_DMN, "lib 'libstrongswan': passed file and segment integrity tests"); - DBG1(DBG_DMN, "lib 'libhydra': passed file and segment integrity tests"); DBG1(DBG_DMN, "lib 'libcharon': passed file and segment integrity tests"); DBG1(DBG_DMN, "daemon 'charon': passed file integrity test"); } @@ -457,7 +447,6 @@ int main(int argc, char *argv[]) deinit: libcharon_deinit(); - libhydra_deinit(); library_deinit(); return status; } diff --git a/src/checksum/Makefile.am b/src/checksum/Makefile.am index b358699d0..9cc5fb6b2 100644 --- a/src/checksum/Makefile.am +++ b/src/checksum/Makefile.am @@ -8,7 +8,6 @@ EXTRA_PROGRAMS = checksum_builder checksum_builder_SOURCES = checksum_builder.c checksum_builder_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ $(DLLIB) checksum_builder_LDFLAGS = -rpath '$(DESTDIR)$(ipseclibdir)' @@ -17,7 +16,6 @@ CLEANFILES = checksum.c $(EXTRA_PROGRAMS) AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DPLUGINDIR=\"${DESTDIR}${plugindir}\" @@ -35,14 +33,6 @@ if !MONOLITHIC AM_CPPFLAGS += -DS_PLUGINS=\""${s_plugins}\"" endif -if USE_LIBHYDRA - deps += $(top_builddir)/src/libhydra/libhydra.la - libs += $(DESTDIR)$(ipseclibdir)/libhydra.so -if !MONOLITHIC - AM_CPPFLAGS += -DH_PLUGINS=\""${h_plugins}\"" -endif -endif - if USE_LIBIPSEC deps += $(top_builddir)/src/libipsec/libipsec.la libs += $(DESTDIR)$(ipseclibdir)/libipsec.so diff --git a/src/checksum/Makefile.in b/src/checksum/Makefile.in index 4e4134625..2584beb76 100644 --- a/src/checksum/Makefile.in +++ b/src/checksum/Makefile.in @@ -80,34 +80,31 @@ build_triplet = @build@ host_triplet = @host@ EXTRA_PROGRAMS = checksum_builder$(EXEEXT) @MONOLITHIC_FALSE@am__append_1 = -DS_PLUGINS=\""${s_plugins}\"" -@USE_LIBHYDRA_TRUE@am__append_2 = $(top_builddir)/src/libhydra/libhydra.la -@USE_LIBHYDRA_TRUE@am__append_3 = $(DESTDIR)$(ipseclibdir)/libhydra.so -@MONOLITHIC_FALSE@@USE_LIBHYDRA_TRUE@am__append_4 = -DH_PLUGINS=\""${h_plugins}\"" -@USE_LIBIPSEC_TRUE@am__append_5 = $(top_builddir)/src/libipsec/libipsec.la -@USE_LIBIPSEC_TRUE@am__append_6 = $(DESTDIR)$(ipseclibdir)/libipsec.so -@USE_TLS_TRUE@am__append_7 = $(top_builddir)/src/libtls/libtls.la -@USE_TLS_TRUE@am__append_8 = $(DESTDIR)$(ipseclibdir)/libtls.so -@USE_RADIUS_TRUE@am__append_9 = $(top_builddir)/src/libradius/libradius.la -@USE_RADIUS_TRUE@am__append_10 = $(DESTDIR)$(ipseclibdir)/libradius.so -@USE_LIBPTTLS_TRUE@am__append_11 = $(top_builddir)/src/libpttls/libpttls.la -@USE_LIBPTTLS_TRUE@am__append_12 = $(DESTDIR)$(ipseclibdir)/libpttls.so -@USE_LIBTNCCS_TRUE@am__append_13 = $(top_builddir)/src/libtnccs/libtnccs.la -@USE_LIBTNCCS_TRUE@am__append_14 = $(DESTDIR)$(ipseclibdir)/libtnccs.so -@MONOLITHIC_FALSE@@USE_LIBTNCCS_TRUE@am__append_15 = -DT_PLUGINS=\""${t_plugins}\"" -@USE_SIMAKA_TRUE@am__append_16 = $(top_builddir)/src/libsimaka/libsimaka.la -@USE_SIMAKA_TRUE@am__append_17 = $(DESTDIR)$(ipseclibdir)/libsimaka.so -@USE_IMCV_TRUE@am__append_18 = $(top_builddir)/src/libimcv/libimcv.la -@USE_IMCV_TRUE@am__append_19 = $(DESTDIR)$(ipseclibdir)/libimcv.so -@USE_CHARON_TRUE@am__append_20 = $(top_builddir)/src/libcharon/libcharon.la -@USE_CHARON_TRUE@am__append_21 = $(DESTDIR)$(ipseclibdir)/libcharon.so -@USE_CHARON_TRUE@am__append_22 = $(DESTDIR)$(ipsecdir)/charon -@MONOLITHIC_FALSE@@USE_CHARON_TRUE@am__append_23 = -DC_PLUGINS=\""${c_plugins}\"" -@USE_CMD_TRUE@am__append_24 = $(DESTDIR)$(sbindir)/charon-cmd -@USE_SCEPCLIENT_TRUE@am__append_25 = $(DESTDIR)$(ipsecdir)/scepclient -@USE_PKI_TRUE@am__append_26 = $(DESTDIR)$(bindir)/pki -@USE_SWANCTL_TRUE@am__append_27 = $(DESTDIR)$(sbindir)/swanctl -@USE_ATTR_SQL_TRUE@am__append_28 = $(DESTDIR)$(ipsecdir)/pool -@USE_IMV_ATTESTATION_TRUE@am__append_29 = $(DESTDIR)$(ipsecdir)/attest +@USE_LIBIPSEC_TRUE@am__append_2 = $(top_builddir)/src/libipsec/libipsec.la +@USE_LIBIPSEC_TRUE@am__append_3 = $(DESTDIR)$(ipseclibdir)/libipsec.so +@USE_TLS_TRUE@am__append_4 = $(top_builddir)/src/libtls/libtls.la +@USE_TLS_TRUE@am__append_5 = $(DESTDIR)$(ipseclibdir)/libtls.so +@USE_RADIUS_TRUE@am__append_6 = $(top_builddir)/src/libradius/libradius.la +@USE_RADIUS_TRUE@am__append_7 = $(DESTDIR)$(ipseclibdir)/libradius.so +@USE_LIBPTTLS_TRUE@am__append_8 = $(top_builddir)/src/libpttls/libpttls.la +@USE_LIBPTTLS_TRUE@am__append_9 = $(DESTDIR)$(ipseclibdir)/libpttls.so +@USE_LIBTNCCS_TRUE@am__append_10 = $(top_builddir)/src/libtnccs/libtnccs.la +@USE_LIBTNCCS_TRUE@am__append_11 = $(DESTDIR)$(ipseclibdir)/libtnccs.so +@MONOLITHIC_FALSE@@USE_LIBTNCCS_TRUE@am__append_12 = -DT_PLUGINS=\""${t_plugins}\"" +@USE_SIMAKA_TRUE@am__append_13 = $(top_builddir)/src/libsimaka/libsimaka.la +@USE_SIMAKA_TRUE@am__append_14 = $(DESTDIR)$(ipseclibdir)/libsimaka.so +@USE_IMCV_TRUE@am__append_15 = $(top_builddir)/src/libimcv/libimcv.la +@USE_IMCV_TRUE@am__append_16 = $(DESTDIR)$(ipseclibdir)/libimcv.so +@USE_CHARON_TRUE@am__append_17 = $(top_builddir)/src/libcharon/libcharon.la +@USE_CHARON_TRUE@am__append_18 = $(DESTDIR)$(ipseclibdir)/libcharon.so +@USE_CHARON_TRUE@am__append_19 = $(DESTDIR)$(ipsecdir)/charon +@MONOLITHIC_FALSE@@USE_CHARON_TRUE@am__append_20 = -DC_PLUGINS=\""${c_plugins}\"" +@USE_CMD_TRUE@am__append_21 = $(DESTDIR)$(sbindir)/charon-cmd +@USE_SCEPCLIENT_TRUE@am__append_22 = $(DESTDIR)$(ipsecdir)/scepclient +@USE_PKI_TRUE@am__append_23 = $(DESTDIR)$(bindir)/pki +@USE_SWANCTL_TRUE@am__append_24 = $(DESTDIR)$(sbindir)/swanctl +@USE_ATTR_SQL_TRUE@am__append_25 = $(DESTDIR)$(ipsecdir)/pool +@USE_IMV_ATTESTATION_TRUE@am__append_26 = $(DESTDIR)$(ipsecdir)/attest subdir = src/checksum DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -173,7 +170,6 @@ checksum_builder_OBJECTS = $(am_checksum_builder_OBJECTS) am__DEPENDENCIES_1 = checksum_builder_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ $(am__DEPENDENCIES_1) checksum_builder_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @@ -453,6 +449,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -475,16 +473,15 @@ libchecksum_la_LDFLAGS = -module -avoid-version -rpath '$(ipseclibdir)' checksum_builder_SOURCES = checksum_builder.c checksum_builder_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ $(DLLIB) checksum_builder_LDFLAGS = -rpath '$(DESTDIR)$(ipseclibdir)' CLEANFILES = checksum.c $(EXTRA_PROGRAMS) AM_CPPFLAGS = -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libcharon \ -DPLUGINDIR=\"${DESTDIR}${plugindir}\" $(am__append_1) \ - $(am__append_4) $(am__append_15) $(am__append_23) + $(am__append_12) $(am__append_20) AM_CFLAGS = \ $(PLUGIN_CFLAGS) @@ -493,16 +490,16 @@ AM_CFLAGS = \ # to the installed libraries. for executables we use the built files directly # as these are not relinked during installation. deps = $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(am__append_2) $(am__append_5) $(am__append_7) \ - $(am__append_9) $(am__append_11) $(am__append_13) \ - $(am__append_16) $(am__append_18) $(am__append_20) + $(am__append_2) $(am__append_4) $(am__append_6) \ + $(am__append_8) $(am__append_10) $(am__append_13) \ + $(am__append_15) $(am__append_17) libs = $(DESTDIR)$(ipseclibdir)/libstrongswan.so $(am__append_3) \ - $(am__append_6) $(am__append_8) $(am__append_10) \ - $(am__append_12) $(am__append_14) $(am__append_17) \ - $(am__append_19) $(am__append_21) -exes = $(am__append_22) $(am__append_24) $(am__append_25) \ - $(am__append_26) $(am__append_27) $(am__append_28) \ - $(am__append_29) + $(am__append_5) $(am__append_7) $(am__append_9) \ + $(am__append_11) $(am__append_14) $(am__append_16) \ + $(am__append_18) +exes = $(am__append_19) $(am__append_21) $(am__append_22) \ + $(am__append_23) $(am__append_24) $(am__append_25) \ + $(am__append_26) all: all-am .SUFFIXES: diff --git a/src/checksum/checksum_builder.c b/src/checksum/checksum_builder.c index cc8185ecd..65399f5bc 100644 --- a/src/checksum/checksum_builder.c +++ b/src/checksum/checksum_builder.c @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -128,9 +127,8 @@ int main(int argc, char* argv[]) { int i; - /* forces link against libhydra/libcharon, imports symbols needed to + /* forces link against libcharon, imports symbols needed to * dlopen plugins */ - hydra = NULL; charon = NULL; /* avoid confusing leak reports in build process */ @@ -159,9 +157,6 @@ int main(int argc, char* argv[]) #ifdef S_PLUGINS build_plugin_checksums(S_PLUGINS); #endif -#ifdef H_PLUGINS - build_plugin_checksums(H_PLUGINS); -#endif #ifdef T_PLUGINS build_plugin_checksums(T_PLUGINS); #endif diff --git a/src/conftest/Makefile.am b/src/conftest/Makefile.am index eeb26f225..2d4e439da 100644 --- a/src/conftest/Makefile.am +++ b/src/conftest/Makefile.am @@ -2,7 +2,6 @@ ipsec_PROGRAMS = conftest AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DPLUGINS=\""${charon_plugins}\"" @@ -20,7 +19,6 @@ conftest_SOURCES = conftest.c conftest.h config.c config.h actions.c actions.h \ conftest_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(DLLIB) diff --git a/src/conftest/Makefile.in b/src/conftest/Makefile.in index 78438d8f5..f5647f9d9 100644 --- a/src/conftest/Makefile.in +++ b/src/conftest/Makefile.in @@ -120,7 +120,6 @@ conftest_OBJECTS = $(am_conftest_OBJECTS) am__DEPENDENCIES_1 = conftest_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) @@ -400,6 +399,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -415,7 +416,6 @@ 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 \ -DPLUGINS=\""${charon_plugins}\"" @@ -432,7 +432,6 @@ conftest_SOURCES = conftest.c conftest.h config.c config.h actions.c actions.h \ conftest_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(DLLIB) diff --git a/src/conftest/conftest.c b/src/conftest/conftest.c index edfe0ca35..d10f3c7b7 100644 --- a/src/conftest/conftest.c +++ b/src/conftest/conftest.c @@ -356,7 +356,6 @@ static void cleanup() free(conftest->suite_dir); free(conftest); libcharon_deinit(); - libhydra_deinit(); library_deinit(); } @@ -442,16 +441,9 @@ int main(int argc, char *argv[]) library_deinit(); return SS_RC_LIBSTRONGSWAN_INTEGRITY; } - if (!libhydra_init()) - { - libhydra_deinit(); - library_deinit(); - return SS_RC_INITIALIZATION_FAILED; - } if (!libcharon_init()) { libcharon_deinit(); - libhydra_deinit(); library_deinit(); return SS_RC_INITIALIZATION_FAILED; } diff --git a/src/conftest/conftest.h b/src/conftest/conftest.h index 6bbdabd07..2d0320429 100644 --- a/src/conftest/conftest.h +++ b/src/conftest/conftest.h @@ -21,7 +21,6 @@ #define CONFTEST_H_ #include -#include #include #include diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in index 2ecf61194..6525fbcb4 100644 --- a/src/dumm/Makefile.in +++ b/src/dumm/Makefile.in @@ -421,6 +421,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/src/include/Makefile.in b/src/include/Makefile.in index 5740544ca..9f4becb40 100644 --- a/src/include/Makefile.in +++ b/src/include/Makefile.in @@ -329,6 +329,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in index d4dafcb0c..72022ed56 100644 --- a/src/ipsec/Makefile.in +++ b/src/ipsec/Makefile.in @@ -363,6 +363,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ diff --git a/src/ipsec/_ipsec.8 b/src/ipsec/_ipsec.8 index fa46e79f1..686c1ce80 100644 --- a/src/ipsec/_ipsec.8 +++ b/src/ipsec/_ipsec.8 @@ -1,4 +1,4 @@ -.TH IPSEC 8 "2013-10-29" "5.4.0dr1" "strongSwan" +.TH IPSEC 8 "2013-10-29" "5.4.0rc1" "strongSwan" . .SH NAME . diff --git a/src/ipsec/_ipsec.in b/src/ipsec/_ipsec.in index 89c7ef753..a002614fe 100644 --- a/src/ipsec/_ipsec.in +++ b/src/ipsec/_ipsec.in @@ -259,10 +259,15 @@ stop) loop=110 while [ $loop -gt 0 ] ; do kill -0 $spid 2>/dev/null || break - sleep 0.1 + sleep 0.1 2>/dev/null + if [ $? -ne 0 ] + then + sleep 1 + loop=$(($loop - 9)) + fi loop=$(($loop - 1)) done - if [ $loop -eq 0 ] + if [ $loop -le 0 ] then kill -KILL $spid 2>/dev/null rm -f $IPSEC_STARTER_PID diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk index 10085794b..55e6bc58b 100644 --- a/src/libcharon/Android.mk +++ b/src/libcharon/Android.mk @@ -47,7 +47,10 @@ encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \ encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \ encoding/payloads/hash_payload.c encoding/payloads/hash_payload.h \ encoding/payloads/fragment_payload.c encoding/payloads/fragment_payload.h \ -kernel/kernel_handler.c kernel/kernel_handler.h \ +kernel/kernel_interface.c kernel/kernel_interface.h \ +kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ +kernel/kernel_net.c kernel/kernel_net.h \ +kernel/kernel_listener.h kernel/kernel_handler.c kernel/kernel_handler.h \ network/receiver.c network/receiver.h network/sender.c network/sender.h \ network/socket.c network/socket.h \ network/socket_manager.c network/socket_manager.h \ @@ -56,6 +59,7 @@ processing/jobs/delete_child_sa_job.c processing/jobs/delete_child_sa_job.h \ processing/jobs/delete_ike_sa_job.c processing/jobs/delete_ike_sa_job.h \ processing/jobs/migrate_job.c processing/jobs/migrate_job.h \ processing/jobs/process_message_job.c processing/jobs/process_message_job.h \ +processing/jobs/redirect_job.c processing/jobs/redirect_job.h \ processing/jobs/rekey_child_sa_job.c processing/jobs/rekey_child_sa_job.h \ processing/jobs/rekey_ike_sa_job.c processing/jobs/rekey_ike_sa_job.h \ processing/jobs/retransmit_job.c processing/jobs/retransmit_job.h \ @@ -81,6 +85,7 @@ sa/child_sa_manager.c sa/child_sa_manager.h \ sa/task_manager.h sa/task_manager.c \ sa/shunt_manager.c sa/shunt_manager.h \ sa/trap_manager.c sa/trap_manager.h \ +sa/redirect_provider.h sa/redirect_manager.c sa/redirect_manager.h \ sa/task.c sa/task.h libcharon_la_SOURCES += \ @@ -104,8 +109,10 @@ sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \ sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \ sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \ sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \ +sa/ikev2/tasks/ike_redirect.c sa/ikev2/tasks/ike_redirect.h \ sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \ -sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h +sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h \ +sa/ikev2/tasks/ike_verify_peer_cert.c sa/ikev2/tasks/ike_verify_peer_cert.h libcharon_la_SOURCES += \ sa/ikev1/keymat_v1.c sa/ikev1/keymat_v1.h \ @@ -149,6 +156,8 @@ endif LOCAL_SRC_FILES += $(call add_plugin, attr) +LOCAL_SRC_FILES += $(call add_plugin, p-cscf) + LOCAL_SRC_FILES += $(call add_plugin, eap-aka) LOCAL_SRC_FILES += $(call add_plugin, eap-aka-3gpp2) @@ -216,6 +225,10 @@ endif LOCAL_SRC_FILES += $(call add_plugin, load-tester) +LOCAL_SRC_FILES += $(call add_plugin, kernel-pfkey) + +LOCAL_SRC_FILES += $(call add_plugin, kernel-netlink) + LOCAL_SRC_FILES += $(call add_plugin, socket-default) LOCAL_SRC_FILES += $(call add_plugin, socket-dynamic) @@ -228,7 +241,6 @@ endif # build libcharon -------------------------------------------------------------- LOCAL_C_INCLUDES += \ - $(strongswan_PATH)/src/libhydra \ $(strongswan_PATH)/src/libstrongswan LOCAL_CFLAGS := $(strongswan_CFLAGS) @@ -241,6 +253,6 @@ LOCAL_ARM_MODE := arm LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES += libstrongswan libhydra +LOCAL_SHARED_LIBRARIES += libstrongswan include $(BUILD_SHARED_LIBRARY) diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index cd81a5eee..9f0707813 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -8,6 +8,7 @@ attributes/mem_pool.c attributes/mem_pool.h \ bus/bus.c bus/bus.h \ bus/listeners/listener.h \ bus/listeners/logger.h \ +bus/listeners/custom_logger.h \ bus/listeners/file_logger.c bus/listeners/file_logger.h \ config/backend_manager.c config/backend_manager.h config/backend.h \ config/child_cfg.c config/child_cfg.h \ @@ -45,7 +46,10 @@ encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \ encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \ encoding/payloads/hash_payload.c encoding/payloads/hash_payload.h \ encoding/payloads/fragment_payload.c encoding/payloads/fragment_payload.h \ -kernel/kernel_handler.c kernel/kernel_handler.h \ +kernel/kernel_interface.c kernel/kernel_interface.h \ +kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ +kernel/kernel_net.c kernel/kernel_net.h \ +kernel/kernel_listener.h kernel/kernel_handler.c kernel/kernel_handler.h \ network/receiver.c network/receiver.h network/sender.c network/sender.h \ network/socket.c network/socket.h \ network/socket_manager.c network/socket_manager.h \ @@ -54,6 +58,7 @@ processing/jobs/delete_child_sa_job.c processing/jobs/delete_child_sa_job.h \ processing/jobs/delete_ike_sa_job.c processing/jobs/delete_ike_sa_job.h \ processing/jobs/migrate_job.c processing/jobs/migrate_job.h \ processing/jobs/process_message_job.c processing/jobs/process_message_job.h \ +processing/jobs/redirect_job.c processing/jobs/redirect_job.h \ processing/jobs/rekey_child_sa_job.c processing/jobs/rekey_child_sa_job.h \ processing/jobs/rekey_ike_sa_job.c processing/jobs/rekey_ike_sa_job.h \ processing/jobs/retransmit_job.c processing/jobs/retransmit_job.h \ @@ -79,6 +84,7 @@ sa/child_sa_manager.c sa/child_sa_manager.h \ sa/task_manager.h sa/task_manager.c \ sa/shunt_manager.c sa/shunt_manager.h \ sa/trap_manager.c sa/trap_manager.h \ +sa/redirect_provider.h sa/redirect_manager.c sa/redirect_manager.h \ sa/task.c sa/task.h if USE_IKEV2 @@ -103,8 +109,10 @@ sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \ sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \ sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \ sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \ +sa/ikev2/tasks/ike_redirect.c sa/ikev2/tasks/ike_redirect.h \ sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \ -sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h +sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h \ +sa/ikev2/tasks/ike_verify_peer_cert.c sa/ikev2/tasks/ike_verify_peer_cert.h endif if USE_IKEV1 @@ -142,7 +150,6 @@ daemon.lo : $(top_builddir)/config.status AM_CPPFLAGS = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" @@ -152,7 +159,6 @@ AM_LDFLAGS = \ libcharon_la_LIBADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la \ -lm $(PTHREADLIB) $(DLLIB) $(SOCKLIB) if USE_WINDOWS @@ -483,6 +489,13 @@ if MONOLITHIC endif endif +if USE_P_CSCF + SUBDIRS += plugins/p_cscf +if MONOLITHIC + libcharon_la_LIBADD += plugins/p_cscf/libstrongswan-p-cscf.la +endif +endif + if USE_ANDROID_DNS SUBDIRS += plugins/android_dns if MONOLITHIC @@ -511,6 +524,27 @@ if MONOLITHIC endif endif +if USE_KERNEL_PFKEY + SUBDIRS += plugins/kernel_pfkey +if MONOLITHIC + libcharon_la_LIBADD += plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la +endif +endif + +if USE_KERNEL_PFROUTE + SUBDIRS += plugins/kernel_pfroute +if MONOLITHIC + libcharon_la_LIBADD += plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la +endif +endif + +if USE_KERNEL_NETLINK + SUBDIRS += plugins/kernel_netlink +if MONOLITHIC + libcharon_la_LIBADD += plugins/kernel_netlink/libstrongswan-kernel-netlink.la +endif +endif + if USE_KERNEL_LIBIPSEC SUBDIRS += plugins/kernel_libipsec if MONOLITHIC diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in index 3d425e0b4..2ccae216e 100644 --- a/src/libcharon/Makefile.in +++ b/src/libcharon/Makefile.in @@ -99,8 +99,10 @@ host_triplet = @host@ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \ +@USE_IKEV2_TRUE@sa/ikev2/tasks/ike_redirect.c sa/ikev2/tasks/ike_redirect.h \ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \ -@USE_IKEV2_TRUE@sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h +@USE_IKEV2_TRUE@sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h \ +@USE_IKEV2_TRUE@sa/ikev2/tasks/ike_verify_peer_cert.c sa/ikev2/tasks/ike_verify_peer_cert.h @USE_IKEV1_TRUE@am__append_2 = \ @USE_IKEV1_TRUE@sa/ikev1/keymat_v1.c sa/ikev1/keymat_v1.h \ @@ -221,58 +223,66 @@ host_triplet = @host@ @MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_85 = plugins/dhcp/libstrongswan-dhcp.la @USE_OSX_ATTR_TRUE@am__append_86 = plugins/osx_attr @MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE@am__append_87 = plugins/osx_attr/libstrongswan-osx-attr.la -@USE_ANDROID_DNS_TRUE@am__append_88 = plugins/android_dns -@MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE@am__append_89 = plugins/android_dns/libstrongswan-android-dns.la -@USE_ANDROID_LOG_TRUE@am__append_90 = plugins/android_log -@MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE@am__append_91 = plugins/android_log/libstrongswan-android-log.la -@USE_MAEMO_TRUE@am__append_92 = plugins/maemo -@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_93 = plugins/maemo/libstrongswan-maemo.la -@USE_HA_TRUE@am__append_94 = plugins/ha -@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_95 = plugins/ha/libstrongswan-ha.la -@USE_KERNEL_LIBIPSEC_TRUE@am__append_96 = plugins/kernel_libipsec -@MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE@am__append_97 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la -@USE_KERNEL_WFP_TRUE@am__append_98 = plugins/kernel_wfp -@MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE@am__append_99 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la -@USE_KERNEL_IPH_TRUE@am__append_100 = plugins/kernel_iph -@MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE@am__append_101 = plugins/kernel_iph/libstrongswan-kernel-iph.la -@USE_WHITELIST_TRUE@am__append_102 = plugins/whitelist -@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_103 = plugins/whitelist/libstrongswan-whitelist.la -@USE_LOOKIP_TRUE@am__append_104 = plugins/lookip -@MONOLITHIC_TRUE@@USE_LOOKIP_TRUE@am__append_105 = plugins/lookip/libstrongswan-lookip.la -@USE_ERROR_NOTIFY_TRUE@am__append_106 = plugins/error_notify -@MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE@am__append_107 = plugins/error_notify/libstrongswan-error-notify.la -@USE_CERTEXPIRE_TRUE@am__append_108 = plugins/certexpire -@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_109 = plugins/certexpire/libstrongswan-certexpire.la -@USE_SYSTIME_FIX_TRUE@am__append_110 = plugins/systime_fix -@MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE@am__append_111 = plugins/systime_fix/libstrongswan-systime-fix.la -@USE_LED_TRUE@am__append_112 = plugins/led -@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_113 = plugins/led/libstrongswan-led.la -@USE_DUPLICHECK_TRUE@am__append_114 = plugins/duplicheck -@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_115 = plugins/duplicheck/libstrongswan-duplicheck.la -@USE_COUPLING_TRUE@am__append_116 = plugins/coupling -@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_117 = plugins/coupling/libstrongswan-coupling.la -@USE_RADATTR_TRUE@am__append_118 = plugins/radattr -@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_119 = plugins/radattr/libstrongswan-radattr.la -@USE_UCI_TRUE@am__append_120 = plugins/uci -@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_121 = plugins/uci/libstrongswan-uci.la -@USE_ADDRBLOCK_TRUE@am__append_122 = plugins/addrblock -@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_123 = plugins/addrblock/libstrongswan-addrblock.la -@USE_UNITY_TRUE@am__append_124 = plugins/unity -@MONOLITHIC_TRUE@@USE_UNITY_TRUE@am__append_125 = plugins/unity/libstrongswan-unity.la -@USE_XAUTH_GENERIC_TRUE@am__append_126 = plugins/xauth_generic -@MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE@am__append_127 = plugins/xauth_generic/libstrongswan-xauth-generic.la -@USE_XAUTH_EAP_TRUE@am__append_128 = plugins/xauth_eap -@MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE@am__append_129 = plugins/xauth_eap/libstrongswan-xauth-eap.la -@USE_XAUTH_PAM_TRUE@am__append_130 = plugins/xauth_pam -@MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE@am__append_131 = plugins/xauth_pam/libstrongswan-xauth-pam.la -@USE_XAUTH_NOAUTH_TRUE@am__append_132 = plugins/xauth_noauth -@MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE@am__append_133 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la -@USE_RESOLVE_TRUE@am__append_134 = plugins/resolve -@MONOLITHIC_TRUE@@USE_RESOLVE_TRUE@am__append_135 = plugins/resolve/libstrongswan-resolve.la -@USE_ATTR_TRUE@am__append_136 = plugins/attr -@MONOLITHIC_TRUE@@USE_ATTR_TRUE@am__append_137 = plugins/attr/libstrongswan-attr.la -@USE_ATTR_SQL_TRUE@am__append_138 = plugins/attr_sql -@MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE@am__append_139 = plugins/attr_sql/libstrongswan-attr-sql.la +@USE_P_CSCF_TRUE@am__append_88 = plugins/p_cscf +@MONOLITHIC_TRUE@@USE_P_CSCF_TRUE@am__append_89 = plugins/p_cscf/libstrongswan-p-cscf.la +@USE_ANDROID_DNS_TRUE@am__append_90 = plugins/android_dns +@MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE@am__append_91 = plugins/android_dns/libstrongswan-android-dns.la +@USE_ANDROID_LOG_TRUE@am__append_92 = plugins/android_log +@MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE@am__append_93 = plugins/android_log/libstrongswan-android-log.la +@USE_MAEMO_TRUE@am__append_94 = plugins/maemo +@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_95 = plugins/maemo/libstrongswan-maemo.la +@USE_HA_TRUE@am__append_96 = plugins/ha +@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_97 = plugins/ha/libstrongswan-ha.la +@USE_KERNEL_PFKEY_TRUE@am__append_98 = plugins/kernel_pfkey +@MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE@am__append_99 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la +@USE_KERNEL_PFROUTE_TRUE@am__append_100 = plugins/kernel_pfroute +@MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE@am__append_101 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la +@USE_KERNEL_NETLINK_TRUE@am__append_102 = plugins/kernel_netlink +@MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE@am__append_103 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la +@USE_KERNEL_LIBIPSEC_TRUE@am__append_104 = plugins/kernel_libipsec +@MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE@am__append_105 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la +@USE_KERNEL_WFP_TRUE@am__append_106 = plugins/kernel_wfp +@MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE@am__append_107 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la +@USE_KERNEL_IPH_TRUE@am__append_108 = plugins/kernel_iph +@MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE@am__append_109 = plugins/kernel_iph/libstrongswan-kernel-iph.la +@USE_WHITELIST_TRUE@am__append_110 = plugins/whitelist +@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_111 = plugins/whitelist/libstrongswan-whitelist.la +@USE_LOOKIP_TRUE@am__append_112 = plugins/lookip +@MONOLITHIC_TRUE@@USE_LOOKIP_TRUE@am__append_113 = plugins/lookip/libstrongswan-lookip.la +@USE_ERROR_NOTIFY_TRUE@am__append_114 = plugins/error_notify +@MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE@am__append_115 = plugins/error_notify/libstrongswan-error-notify.la +@USE_CERTEXPIRE_TRUE@am__append_116 = plugins/certexpire +@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_117 = plugins/certexpire/libstrongswan-certexpire.la +@USE_SYSTIME_FIX_TRUE@am__append_118 = plugins/systime_fix +@MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE@am__append_119 = plugins/systime_fix/libstrongswan-systime-fix.la +@USE_LED_TRUE@am__append_120 = plugins/led +@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_121 = plugins/led/libstrongswan-led.la +@USE_DUPLICHECK_TRUE@am__append_122 = plugins/duplicheck +@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_123 = plugins/duplicheck/libstrongswan-duplicheck.la +@USE_COUPLING_TRUE@am__append_124 = plugins/coupling +@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_125 = plugins/coupling/libstrongswan-coupling.la +@USE_RADATTR_TRUE@am__append_126 = plugins/radattr +@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_127 = plugins/radattr/libstrongswan-radattr.la +@USE_UCI_TRUE@am__append_128 = plugins/uci +@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_129 = plugins/uci/libstrongswan-uci.la +@USE_ADDRBLOCK_TRUE@am__append_130 = plugins/addrblock +@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_131 = plugins/addrblock/libstrongswan-addrblock.la +@USE_UNITY_TRUE@am__append_132 = plugins/unity +@MONOLITHIC_TRUE@@USE_UNITY_TRUE@am__append_133 = plugins/unity/libstrongswan-unity.la +@USE_XAUTH_GENERIC_TRUE@am__append_134 = plugins/xauth_generic +@MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE@am__append_135 = plugins/xauth_generic/libstrongswan-xauth-generic.la +@USE_XAUTH_EAP_TRUE@am__append_136 = plugins/xauth_eap +@MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE@am__append_137 = plugins/xauth_eap/libstrongswan-xauth-eap.la +@USE_XAUTH_PAM_TRUE@am__append_138 = plugins/xauth_pam +@MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE@am__append_139 = plugins/xauth_pam/libstrongswan-xauth-pam.la +@USE_XAUTH_NOAUTH_TRUE@am__append_140 = plugins/xauth_noauth +@MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE@am__append_141 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la +@USE_RESOLVE_TRUE@am__append_142 = plugins/resolve +@MONOLITHIC_TRUE@@USE_RESOLVE_TRUE@am__append_143 = plugins/resolve/libstrongswan-resolve.la +@USE_ATTR_TRUE@am__append_144 = plugins/attr +@MONOLITHIC_TRUE@@USE_ATTR_TRUE@am__append_145 = plugins/attr/libstrongswan-attr.la +@USE_ATTR_SQL_TRUE@am__append_146 = plugins/attr_sql +@MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE@am__append_147 = plugins/attr_sql/libstrongswan-attr-sql.la subdir = src/libcharon DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -325,47 +335,47 @@ LTLIBRARIES = $(ipseclib_LTLIBRARIES) am__DEPENDENCIES_1 = libcharon_la_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__append_7) $(am__append_9) \ - $(am__append_11) $(am__append_13) $(am__append_15) \ - $(am__append_17) $(am__append_19) $(am__append_21) \ - $(am__append_23) $(am__append_25) $(am__append_27) \ - $(am__append_29) $(am__append_31) $(am__append_33) \ - $(am__append_35) $(am__append_37) $(am__append_39) \ - $(am__append_41) $(am__append_43) $(am__append_45) \ - $(am__append_47) $(am__append_49) $(am__append_51) \ - $(am__append_53) $(am__append_54) $(am__append_56) \ - $(am__append_58) $(am__append_60) $(am__append_62) \ - $(am__append_64) $(am__append_66) $(am__append_68) \ - $(am__append_70) $(am__append_72) $(am__append_73) \ - $(am__append_74) $(am__append_76) $(am__append_78) \ - $(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) \ - $(am__append_97) $(am__append_99) $(am__append_101) \ - $(am__append_103) $(am__append_105) $(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_131) \ - $(am__append_133) $(am__append_135) $(am__append_137) \ - $(am__append_139) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) $(am__append_7) \ + $(am__append_9) $(am__append_11) $(am__append_13) \ + $(am__append_15) $(am__append_17) $(am__append_19) \ + $(am__append_21) $(am__append_23) $(am__append_25) \ + $(am__append_27) $(am__append_29) $(am__append_31) \ + $(am__append_33) $(am__append_35) $(am__append_37) \ + $(am__append_39) $(am__append_41) $(am__append_43) \ + $(am__append_45) $(am__append_47) $(am__append_49) \ + $(am__append_51) $(am__append_53) $(am__append_54) \ + $(am__append_56) $(am__append_58) $(am__append_60) \ + $(am__append_62) $(am__append_64) $(am__append_66) \ + $(am__append_68) $(am__append_70) $(am__append_72) \ + $(am__append_73) $(am__append_74) $(am__append_76) \ + $(am__append_78) $(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) $(am__append_97) $(am__append_99) \ + $(am__append_101) $(am__append_103) $(am__append_105) \ + $(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_131) $(am__append_133) $(am__append_135) \ + $(am__append_137) $(am__append_139) $(am__append_141) \ + $(am__append_143) $(am__append_145) $(am__append_147) am__libcharon_la_SOURCES_DIST = attributes/attributes.c \ attributes/attributes.h attributes/attribute_provider.h \ attributes/attribute_handler.h attributes/attribute_manager.c \ attributes/attribute_manager.h attributes/mem_pool.c \ attributes/mem_pool.h bus/bus.c bus/bus.h \ bus/listeners/listener.h bus/listeners/logger.h \ - bus/listeners/file_logger.c bus/listeners/file_logger.h \ - config/backend_manager.c config/backend_manager.h \ - config/backend.h config/child_cfg.c config/child_cfg.h \ - config/ike_cfg.c config/ike_cfg.h config/peer_cfg.c \ - config/peer_cfg.h config/proposal.c config/proposal.h \ - control/controller.c control/controller.h daemon.c daemon.h \ - encoding/generator.c encoding/generator.h encoding/message.c \ - encoding/message.h encoding/parser.c encoding/parser.h \ - encoding/payloads/auth_payload.c \ + bus/listeners/custom_logger.h bus/listeners/file_logger.c \ + bus/listeners/file_logger.h config/backend_manager.c \ + config/backend_manager.h config/backend.h config/child_cfg.c \ + config/child_cfg.h config/ike_cfg.c config/ike_cfg.h \ + config/peer_cfg.c config/peer_cfg.h config/proposal.c \ + config/proposal.h control/controller.c control/controller.h \ + daemon.c daemon.h encoding/generator.c encoding/generator.h \ + encoding/message.c encoding/message.h encoding/parser.c \ + encoding/parser.h encoding/payloads/auth_payload.c \ encoding/payloads/auth_payload.h \ encoding/payloads/cert_payload.c \ encoding/payloads/cert_payload.h \ @@ -407,7 +417,10 @@ am__libcharon_la_SOURCES_DIST = attributes/attributes.c \ encoding/payloads/hash_payload.c \ encoding/payloads/hash_payload.h \ encoding/payloads/fragment_payload.c \ - encoding/payloads/fragment_payload.h kernel/kernel_handler.c \ + encoding/payloads/fragment_payload.h kernel/kernel_interface.c \ + kernel/kernel_interface.h kernel/kernel_ipsec.c \ + kernel/kernel_ipsec.h kernel/kernel_net.c kernel/kernel_net.h \ + kernel/kernel_listener.h kernel/kernel_handler.c \ kernel/kernel_handler.h network/receiver.c network/receiver.h \ network/sender.c network/sender.h network/socket.c \ network/socket.h network/socket_manager.c \ @@ -420,6 +433,7 @@ am__libcharon_la_SOURCES_DIST = attributes/attributes.c \ processing/jobs/migrate_job.c processing/jobs/migrate_job.h \ processing/jobs/process_message_job.c \ processing/jobs/process_message_job.h \ + processing/jobs/redirect_job.c processing/jobs/redirect_job.h \ processing/jobs/rekey_child_sa_job.c \ processing/jobs/rekey_child_sa_job.h \ processing/jobs/rekey_ike_sa_job.c \ @@ -449,7 +463,8 @@ am__libcharon_la_SOURCES_DIST = attributes/attributes.c \ sa/ike_sa_manager.h sa/child_sa_manager.c \ sa/child_sa_manager.h sa/task_manager.h sa/task_manager.c \ sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \ - sa/trap_manager.h sa/task.c sa/task.h sa/ikev2/keymat_v2.c \ + sa/trap_manager.h sa/redirect_provider.h sa/redirect_manager.c \ + sa/redirect_manager.h sa/task.c sa/task.h sa/ikev2/keymat_v2.c \ sa/ikev2/keymat_v2.h sa/ikev2/task_manager_v2.c \ sa/ikev2/task_manager_v2.h \ sa/ikev2/authenticators/eap_authenticator.c \ @@ -474,9 +489,12 @@ am__libcharon_la_SOURCES_DIST = attributes/attributes.c \ sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \ sa/ikev2/tasks/ike_reauth_complete.c \ sa/ikev2/tasks/ike_reauth_complete.h \ + sa/ikev2/tasks/ike_redirect.c sa/ikev2/tasks/ike_redirect.h \ sa/ikev2/tasks/ike_auth_lifetime.c \ sa/ikev2/tasks/ike_auth_lifetime.h sa/ikev2/tasks/ike_vendor.c \ - sa/ikev2/tasks/ike_vendor.h sa/ikev1/keymat_v1.c \ + sa/ikev2/tasks/ike_vendor.h \ + sa/ikev2/tasks/ike_verify_peer_cert.c \ + sa/ikev2/tasks/ike_verify_peer_cert.h sa/ikev1/keymat_v1.c \ sa/ikev1/keymat_v1.h sa/ikev1/task_manager_v1.c \ sa/ikev1/task_manager_v1.h \ sa/ikev1/authenticators/psk_v1_authenticator.c \ @@ -535,8 +553,10 @@ am__dirstamp = $(am__leading_dot)dirstamp @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_rekey.lo \ @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_reauth.lo \ @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_reauth_complete.lo \ +@USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_redirect.lo \ @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_auth_lifetime.lo \ -@USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_vendor.lo +@USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_vendor.lo \ +@USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_verify_peer_cert.lo @USE_IKEV1_TRUE@am__objects_2 = sa/ikev1/keymat_v1.lo \ @USE_IKEV1_TRUE@ sa/ikev1/task_manager_v1.lo \ @USE_IKEV1_TRUE@ sa/ikev1/authenticators/psk_v1_authenticator.lo \ @@ -595,13 +615,16 @@ am_libcharon_la_OBJECTS = attributes/attributes.lo \ encoding/payloads/unknown_payload.lo \ encoding/payloads/vendor_id_payload.lo \ encoding/payloads/hash_payload.lo \ - encoding/payloads/fragment_payload.lo kernel/kernel_handler.lo \ + encoding/payloads/fragment_payload.lo \ + kernel/kernel_interface.lo kernel/kernel_ipsec.lo \ + kernel/kernel_net.lo kernel/kernel_handler.lo \ network/receiver.lo network/sender.lo network/socket.lo \ network/socket_manager.lo processing/jobs/acquire_job.lo \ processing/jobs/delete_child_sa_job.lo \ processing/jobs/delete_ike_sa_job.lo \ processing/jobs/migrate_job.lo \ processing/jobs/process_message_job.lo \ + processing/jobs/redirect_job.lo \ processing/jobs/rekey_child_sa_job.lo \ processing/jobs/rekey_ike_sa_job.lo \ processing/jobs/retransmit_job.lo \ @@ -616,8 +639,9 @@ am_libcharon_la_OBJECTS = attributes/attributes.lo \ sa/xauth/xauth_manager.lo sa/authenticator.lo sa/child_sa.lo \ sa/ike_sa.lo sa/ike_sa_id.lo sa/keymat.lo sa/ike_sa_manager.lo \ sa/child_sa_manager.lo sa/task_manager.lo sa/shunt_manager.lo \ - sa/trap_manager.lo sa/task.lo $(am__objects_1) \ - $(am__objects_2) $(am__objects_3) $(am__objects_4) + sa/trap_manager.lo sa/redirect_manager.lo sa/task.lo \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) \ + $(am__objects_4) libcharon_la_OBJECTS = $(am_libcharon_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -712,12 +736,14 @@ DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \ 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/p_cscf plugins/android_dns plugins/android_log \ + plugins/maemo plugins/ha plugins/kernel_pfkey \ + plugins/kernel_pfroute plugins/kernel_netlink \ + 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/xauth_generic plugins/xauth_eap plugins/xauth_pam \ plugins/xauth_noauth plugins/resolve plugins/attr \ plugins/attr_sql tests @@ -959,6 +985,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -978,15 +1006,15 @@ libcharon_la_SOURCES = attributes/attributes.c attributes/attributes.h \ attributes/attribute_manager.c attributes/attribute_manager.h \ attributes/mem_pool.c attributes/mem_pool.h bus/bus.c \ bus/bus.h bus/listeners/listener.h bus/listeners/logger.h \ - bus/listeners/file_logger.c bus/listeners/file_logger.h \ - config/backend_manager.c config/backend_manager.h \ - config/backend.h config/child_cfg.c config/child_cfg.h \ - config/ike_cfg.c config/ike_cfg.h config/peer_cfg.c \ - config/peer_cfg.h config/proposal.c config/proposal.h \ - control/controller.c control/controller.h daemon.c daemon.h \ - encoding/generator.c encoding/generator.h encoding/message.c \ - encoding/message.h encoding/parser.c encoding/parser.h \ - encoding/payloads/auth_payload.c \ + bus/listeners/custom_logger.h bus/listeners/file_logger.c \ + bus/listeners/file_logger.h config/backend_manager.c \ + config/backend_manager.h config/backend.h config/child_cfg.c \ + config/child_cfg.h config/ike_cfg.c config/ike_cfg.h \ + config/peer_cfg.c config/peer_cfg.h config/proposal.c \ + config/proposal.h control/controller.c control/controller.h \ + daemon.c daemon.h encoding/generator.c encoding/generator.h \ + encoding/message.c encoding/message.h encoding/parser.c \ + encoding/parser.h encoding/payloads/auth_payload.c \ encoding/payloads/auth_payload.h \ encoding/payloads/cert_payload.c \ encoding/payloads/cert_payload.h \ @@ -1028,7 +1056,10 @@ libcharon_la_SOURCES = attributes/attributes.c attributes/attributes.h \ encoding/payloads/hash_payload.c \ encoding/payloads/hash_payload.h \ encoding/payloads/fragment_payload.c \ - encoding/payloads/fragment_payload.h kernel/kernel_handler.c \ + encoding/payloads/fragment_payload.h kernel/kernel_interface.c \ + kernel/kernel_interface.h kernel/kernel_ipsec.c \ + kernel/kernel_ipsec.h kernel/kernel_net.c kernel/kernel_net.h \ + kernel/kernel_listener.h kernel/kernel_handler.c \ kernel/kernel_handler.h network/receiver.c network/receiver.h \ network/sender.c network/sender.h network/socket.c \ network/socket.h network/socket_manager.c \ @@ -1041,6 +1072,7 @@ libcharon_la_SOURCES = attributes/attributes.c attributes/attributes.h \ processing/jobs/migrate_job.c processing/jobs/migrate_job.h \ processing/jobs/process_message_job.c \ processing/jobs/process_message_job.h \ + processing/jobs/redirect_job.c processing/jobs/redirect_job.h \ processing/jobs/rekey_child_sa_job.c \ processing/jobs/rekey_child_sa_job.h \ processing/jobs/rekey_ike_sa_job.c \ @@ -1070,12 +1102,12 @@ libcharon_la_SOURCES = attributes/attributes.c attributes/attributes.h \ sa/ike_sa_manager.h sa/child_sa_manager.c \ sa/child_sa_manager.h sa/task_manager.h sa/task_manager.c \ sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \ - sa/trap_manager.h sa/task.c sa/task.h $(am__append_1) \ + sa/trap_manager.h sa/redirect_provider.h sa/redirect_manager.c \ + sa/redirect_manager.h sa/task.c sa/task.h $(am__append_1) \ $(am__append_2) $(am__append_3) $(am__append_5) AM_CPPFLAGS = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_PIDDIR=\"${piddir}\" @@ -1084,32 +1116,33 @@ AM_LDFLAGS = \ -no-undefined libcharon_la_LIBADD = \ - $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la -lm $(PTHREADLIB) \ - $(DLLIB) $(SOCKLIB) $(am__append_4) $(am__append_7) \ - $(am__append_9) $(am__append_11) $(am__append_13) \ - $(am__append_15) $(am__append_17) $(am__append_19) \ - $(am__append_21) $(am__append_23) $(am__append_25) \ - $(am__append_27) $(am__append_29) $(am__append_31) \ - $(am__append_33) $(am__append_35) $(am__append_37) \ - $(am__append_39) $(am__append_41) $(am__append_43) \ - $(am__append_45) $(am__append_47) $(am__append_49) \ - $(am__append_51) $(am__append_53) $(am__append_54) \ - $(am__append_56) $(am__append_58) $(am__append_60) \ - $(am__append_62) $(am__append_64) $(am__append_66) \ - $(am__append_68) $(am__append_70) $(am__append_72) \ - $(am__append_73) $(am__append_74) $(am__append_76) \ - $(am__append_78) $(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) $(am__append_97) $(am__append_99) \ - $(am__append_101) $(am__append_103) $(am__append_105) \ - $(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_131) $(am__append_133) $(am__append_135) \ - $(am__append_137) $(am__append_139) + $(top_builddir)/src/libstrongswan/libstrongswan.la -lm \ + $(PTHREADLIB) $(DLLIB) $(SOCKLIB) $(am__append_4) \ + $(am__append_7) $(am__append_9) $(am__append_11) \ + $(am__append_13) $(am__append_15) $(am__append_17) \ + $(am__append_19) $(am__append_21) $(am__append_23) \ + $(am__append_25) $(am__append_27) $(am__append_29) \ + $(am__append_31) $(am__append_33) $(am__append_35) \ + $(am__append_37) $(am__append_39) $(am__append_41) \ + $(am__append_43) $(am__append_45) $(am__append_47) \ + $(am__append_49) $(am__append_51) $(am__append_53) \ + $(am__append_54) $(am__append_56) $(am__append_58) \ + $(am__append_60) $(am__append_62) $(am__append_64) \ + $(am__append_66) $(am__append_68) $(am__append_70) \ + $(am__append_72) $(am__append_73) $(am__append_74) \ + $(am__append_76) $(am__append_78) $(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) $(am__append_97) \ + $(am__append_99) $(am__append_101) $(am__append_103) \ + $(am__append_105) $(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_131) $(am__append_133) \ + $(am__append_135) $(am__append_137) $(am__append_139) \ + $(am__append_141) $(am__append_143) $(am__append_145) \ + $(am__append_147) EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@SUBDIRS = . $(am__append_6) $(am__append_8) \ @MONOLITHIC_FALSE@ $(am__append_10) $(am__append_12) \ @@ -1143,7 +1176,9 @@ EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@ $(am__append_126) $(am__append_128) \ @MONOLITHIC_FALSE@ $(am__append_130) $(am__append_132) \ @MONOLITHIC_FALSE@ $(am__append_134) $(am__append_136) \ -@MONOLITHIC_FALSE@ $(am__append_138) tests +@MONOLITHIC_FALSE@ $(am__append_138) $(am__append_140) \ +@MONOLITHIC_FALSE@ $(am__append_142) $(am__append_144) \ +@MONOLITHIC_FALSE@ $(am__append_146) tests # build optional plugins ######################## @@ -1179,7 +1214,9 @@ EXTRA_DIST = Android.mk @MONOLITHIC_TRUE@ $(am__append_126) $(am__append_128) \ @MONOLITHIC_TRUE@ $(am__append_130) $(am__append_132) \ @MONOLITHIC_TRUE@ $(am__append_134) $(am__append_136) \ -@MONOLITHIC_TRUE@ $(am__append_138) . tests +@MONOLITHIC_TRUE@ $(am__append_138) $(am__append_140) \ +@MONOLITHIC_TRUE@ $(am__append_142) $(am__append_144) \ +@MONOLITHIC_TRUE@ $(am__append_146) . tests all: all-recursive .SUFFIXES: @@ -1386,6 +1423,12 @@ kernel/$(am__dirstamp): kernel/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) kernel/$(DEPDIR) @: > kernel/$(DEPDIR)/$(am__dirstamp) +kernel/kernel_interface.lo: kernel/$(am__dirstamp) \ + kernel/$(DEPDIR)/$(am__dirstamp) +kernel/kernel_ipsec.lo: kernel/$(am__dirstamp) \ + kernel/$(DEPDIR)/$(am__dirstamp) +kernel/kernel_net.lo: kernel/$(am__dirstamp) \ + kernel/$(DEPDIR)/$(am__dirstamp) kernel/kernel_handler.lo: kernel/$(am__dirstamp) \ kernel/$(DEPDIR)/$(am__dirstamp) network/$(am__dirstamp): @@ -1420,6 +1463,8 @@ processing/jobs/migrate_job.lo: processing/jobs/$(am__dirstamp) \ processing/jobs/process_message_job.lo: \ processing/jobs/$(am__dirstamp) \ processing/jobs/$(DEPDIR)/$(am__dirstamp) +processing/jobs/redirect_job.lo: processing/jobs/$(am__dirstamp) \ + processing/jobs/$(DEPDIR)/$(am__dirstamp) processing/jobs/rekey_child_sa_job.lo: \ processing/jobs/$(am__dirstamp) \ processing/jobs/$(DEPDIR)/$(am__dirstamp) @@ -1483,6 +1528,8 @@ sa/child_sa_manager.lo: sa/$(am__dirstamp) \ sa/task_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) sa/shunt_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) sa/trap_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) +sa/redirect_manager.lo: sa/$(am__dirstamp) \ + sa/$(DEPDIR)/$(am__dirstamp) sa/task.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) sa/ikev2/$(am__dirstamp): @$(MKDIR_P) sa/ikev2 @@ -1545,10 +1592,15 @@ sa/ikev2/tasks/ike_reauth.lo: sa/ikev2/tasks/$(am__dirstamp) \ sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) sa/ikev2/tasks/ike_reauth_complete.lo: sa/ikev2/tasks/$(am__dirstamp) \ sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) +sa/ikev2/tasks/ike_redirect.lo: sa/ikev2/tasks/$(am__dirstamp) \ + sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) sa/ikev2/tasks/ike_auth_lifetime.lo: sa/ikev2/tasks/$(am__dirstamp) \ sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) sa/ikev2/tasks/ike_vendor.lo: sa/ikev2/tasks/$(am__dirstamp) \ sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) +sa/ikev2/tasks/ike_verify_peer_cert.lo: \ + sa/ikev2/tasks/$(am__dirstamp) \ + sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) sa/ikev1/$(am__dirstamp): @$(MKDIR_P) sa/ikev1 @: > sa/ikev1/$(am__dirstamp) @@ -1720,6 +1772,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/unknown_payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@encoding/payloads/$(DEPDIR)/vendor_id_payload.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_handler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_interface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_ipsec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_net.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@network/$(DEPDIR)/receiver.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@network/$(DEPDIR)/sender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@network/$(DEPDIR)/socket.Plo@am__quote@ @@ -1735,6 +1790,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/mediation_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/migrate_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/process_message_job.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/redirect_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/rekey_child_sa_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/rekey_ike_sa_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/retransmit_job.Plo@am__quote@ @@ -1751,6 +1807,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/ike_sa_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/ike_sa_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/keymat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/redirect_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/shunt_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/task.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/task_manager.Plo@am__quote@ @@ -1799,8 +1856,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_natd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_reauth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_reauth_complete.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_redirect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_rekey.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_vendor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_verify_peer_cert.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/xauth/$(DEPDIR)/xauth_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/xauth/$(DEPDIR)/xauth_method.Plo@am__quote@ diff --git a/src/libcharon/attributes/attributes.c b/src/libcharon/attributes/attributes.c index 9fabcf4e4..0f28d55fa 100644 --- a/src/libcharon/attributes/attributes.c +++ b/src/libcharon/attributes/attributes.c @@ -17,7 +17,7 @@ #include "attributes.h" -ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, HOME_AGENT_ADDRESS, +ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, P_CSCF_IP6_ADDRESS, "INTERNAL_IP4_ADDRESS", "INTERNAL_IP4_NETMASK", "INTERNAL_IP4_DNS", @@ -36,8 +36,10 @@ ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, HOME_AGENT_ "MIP6_HOME_PREFIX", "INTERNAL_IP6_LINK", "INTERNAL_IP6_PREFIX", - "HOME_AGENT_ADDRESS"); -ENUM_NEXT(configuration_attribute_type_names, XAUTH_TYPE, XAUTH_ANSWER, HOME_AGENT_ADDRESS, + "HOME_AGENT_ADDRESS", + "P_CSCF_IP4_ADDRESS", + "P_CSCF_IP6_ADDRESS"); +ENUM_NEXT(configuration_attribute_type_names, XAUTH_TYPE, XAUTH_ANSWER, P_CSCF_IP6_ADDRESS, "XAUTH_TYPE", "XAUTH_USER_NAME", "XAUTH_USER_PASSWORD", @@ -65,7 +67,7 @@ ENUM_NEXT(configuration_attribute_type_names, UNITY_BANNER, UNITY_DDNS_HOSTNAME, "UNITY_DDNS_HOSTNAME"); ENUM_END(configuration_attribute_type_names, UNITY_DDNS_HOSTNAME); -ENUM_BEGIN(configuration_attribute_type_short_names, INTERNAL_IP4_ADDRESS, HOME_AGENT_ADDRESS, +ENUM_BEGIN(configuration_attribute_type_short_names, INTERNAL_IP4_ADDRESS, P_CSCF_IP6_ADDRESS, "ADDR", "MASK", "DNS", @@ -84,8 +86,10 @@ ENUM_BEGIN(configuration_attribute_type_short_names, INTERNAL_IP4_ADDRESS, HOME_ "MIP6HPFX", "LINK6", "PFX6", - "HOA"); -ENUM_NEXT(configuration_attribute_type_short_names, XAUTH_TYPE, XAUTH_ANSWER, HOME_AGENT_ADDRESS, + "HOA", + "PCSCF4", + "PCSCF6"); +ENUM_NEXT(configuration_attribute_type_short_names, XAUTH_TYPE, XAUTH_ANSWER, P_CSCF_IP6_ADDRESS, "X_TYPE", "X_USER", "X_PWD", diff --git a/src/libcharon/attributes/attributes.h b/src/libcharon/attributes/attributes.h index 5d1e9f9ba..dd1db4fc3 100644 --- a/src/libcharon/attributes/attributes.h +++ b/src/libcharon/attributes/attributes.h @@ -49,6 +49,9 @@ enum configuration_attribute_type_t { INTERNAL_IP6_LINK = 17, INTERNAL_IP6_PREFIX = 18, HOME_AGENT_ADDRESS = 19, + /* RFC 7651 */ + P_CSCF_IP4_ADDRESS = 20, + P_CSCF_IP6_ADDRESS = 21, /* XAUTH attributes */ XAUTH_TYPE = 16520, XAUTH_USER_NAME = 16521, diff --git a/src/libcharon/attributes/mem_pool.c b/src/libcharon/attributes/mem_pool.c index 279668249..833c3e950 100644 --- a/src/libcharon/attributes/mem_pool.c +++ b/src/libcharon/attributes/mem_pool.c @@ -17,7 +17,6 @@ #include "mem_pool.h" #include -#include #include #include #include diff --git a/src/libcharon/bus/listeners/custom_logger.h b/src/libcharon/bus/listeners/custom_logger.h new file mode 100644 index 000000000..a256ad1ec --- /dev/null +++ b/src/libcharon/bus/listeners/custom_logger.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2016 secunet Security Networks AG + * Copyright (C) 2016 Thomas Egerer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @defgroup custom_logger custom_logger + * @{ @ingroup listeners + */ + +#ifndef CUSTOM_LOGGER_H_ +#define CUSTOM_LOGGER_H_ + +#include + +typedef struct custom_logger_t custom_logger_t; + +/** + * Custom logger which implements listener_t. + */ +struct custom_logger_t { + + /** + * Implements the logger_t interface. + */ + logger_t logger; + + /** + * Set the loglevel for a debug group. + * + * @param group debug group to set + * @param level max level to log (0..4) + */ + void (*set_level) (custom_logger_t *this, debug_t group, level_t level); + + /** + * Destroy the custom_logger_t object. + */ + void (*destroy) (custom_logger_t *this); +}; + +/** + * Prototype for custom logger construction function pointer. + */ +typedef custom_logger_t *(*custom_logger_constructor_t)(const char *name); + +#endif /** CUSTOM_LOGGER_H_ @}*/ diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c index ed7c0d406..3d3c7419b 100644 --- a/src/libcharon/config/child_cfg.c +++ b/src/libcharon/config/child_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -531,6 +531,57 @@ METHOD(child_cfg_t, install_policy, bool, return this->install_policy; } +#define LT_PART_EQUALS(a, b) ({ a.life == b.life && a.rekey == b.rekey && a.jitter == b.jitter; }) +#define LIFETIME_EQUALS(a, b) ({ LT_PART_EQUALS(a.time, b.time) && LT_PART_EQUALS(a.bytes, b.bytes) && LT_PART_EQUALS(a.packets, b.packets); }) + +METHOD(child_cfg_t, equals, bool, + private_child_cfg_t *this, child_cfg_t *other_pub) +{ + private_child_cfg_t *other = (private_child_cfg_t*)other_pub; + + if (this == other) + { + return TRUE; + } + if (this->public.equals != other->public.equals) + { + return FALSE; + } + if (!this->proposals->equals_offset(this->proposals, other->proposals, + offsetof(proposal_t, equals))) + { + return FALSE; + } + if (!this->my_ts->equals_offset(this->my_ts, other->my_ts, + offsetof(traffic_selector_t, equals))) + { + return FALSE; + } + if (!this->other_ts->equals_offset(this->other_ts, other->other_ts, + offsetof(traffic_selector_t, equals))) + { + return FALSE; + } + return this->hostaccess == other->hostaccess && + this->mode == other->mode && + this->start_action == other->start_action && + this->dpd_action == other->dpd_action && + this->close_action == other->close_action && + LIFETIME_EQUALS(this->lifetime, other->lifetime) && + this->use_ipcomp == other->use_ipcomp && + this->inactivity == other->inactivity && + this->reqid == other->reqid && + this->mark_in.value == other->mark_in.value && + this->mark_in.mask == other->mark_in.mask && + this->mark_out.value == other->mark_out.value && + this->mark_out.mask == other->mark_out.mask && + this->tfc == other->tfc && + this->replay_window == other->replay_window && + this->proxy_mode == other->proxy_mode && + this->install_policy == other->install_policy && + streq(this->updown, other->updown); +} + METHOD(child_cfg_t, get_ref, child_cfg_t*, private_child_cfg_t *this) { @@ -593,6 +644,7 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime, .set_replay_window = _set_replay_window, .use_proxy_mode = _use_proxy_mode, .install_policy = _install_policy, + .equals = _equals, .get_ref = _get_ref, .destroy = _destroy, }, diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h index 9f7a92b70..22641f77e 100644 --- a/src/libcharon/config/child_cfg.h +++ b/src/libcharon/config/child_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -273,6 +273,14 @@ struct child_cfg_t { */ bool (*install_policy)(child_cfg_t *this); + /** + * Check if two child_cfg objects are equal. + * + * @param other candidate to check for equality against this + * @return TRUE if equal + */ + bool (*equals)(child_cfg_t *this, child_cfg_t *other); + /** * Increase the reference count. * diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c index dee9e4c29..a720e1493 100644 --- a/src/libcharon/config/ike_cfg.c +++ b/src/libcharon/config/ike_cfg.c @@ -371,9 +371,6 @@ METHOD(ike_cfg_t, equals, bool, private_ike_cfg_t *this, ike_cfg_t *other_public) { private_ike_cfg_t *other = (private_ike_cfg_t*)other_public; - enumerator_t *e1, *e2; - proposal_t *p1, *p2; - bool eq = TRUE; if (this == other) { @@ -383,25 +380,12 @@ METHOD(ike_cfg_t, equals, bool, { return FALSE; } - if (this->proposals->get_count(this->proposals) != - other->proposals->get_count(other->proposals)) + if (!this->proposals->equals_offset(this->proposals, other->proposals, + offsetof(proposal_t, equals))) { return FALSE; } - e1 = this->proposals->create_enumerator(this->proposals); - e2 = other->proposals->create_enumerator(other->proposals); - while (e1->enumerate(e1, &p1) && e2->enumerate(e2, &p2)) - { - if (!p1->equals(p1, p2)) - { - eq = FALSE; - break; - } - } - e1->destroy(e1); - e2->destroy(e2); - - return (eq && + return this->version == other->version && this->certreq == other->certreq && this->force_encap == other->force_encap && @@ -409,7 +393,7 @@ METHOD(ike_cfg_t, equals, bool, streq(this->me, other->me) && streq(this->other, other->other) && this->my_port == other->my_port && - this->other_port == other->other_port); + this->other_port == other->other_port; } METHOD(ike_cfg_t, get_ref, ike_cfg_t*, diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c index aa2a39ce5..d28a79507 100644 --- a/src/libcharon/config/peer_cfg.c +++ b/src/libcharon/config/peer_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2008 Tobias Brunner + * Copyright (C) 2007-2015 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -200,6 +200,117 @@ METHOD(peer_cfg_t, add_child_cfg, void, this->mutex->unlock(this->mutex); } +typedef struct { + enumerator_t public; + linked_list_t *removed; + linked_list_t *added; + enumerator_t *wrapped; + bool add; +} child_cfgs_replace_enumerator_t; + +METHOD(enumerator_t, child_cfgs_replace_enumerate, bool, + child_cfgs_replace_enumerator_t *this, child_cfg_t **chd, bool *added) +{ + child_cfg_t *child_cfg; + + if (!this->wrapped) + { + this->wrapped = this->removed->create_enumerator(this->removed); + } + while (TRUE) + { + if (this->wrapped->enumerate(this->wrapped, &child_cfg)) + { + if (chd) + { + *chd = child_cfg; + } + if (added) + { + *added = this->add; + } + return TRUE; + } + if (this->add) + { + break; + } + this->wrapped = this->added->create_enumerator(this->added); + this->add = TRUE; + } + return FALSE; +} + +METHOD(enumerator_t, child_cfgs_replace_enumerator_destroy, void, + child_cfgs_replace_enumerator_t *this) +{ + DESTROY_IF(this->wrapped); + this->removed->destroy_offset(this->removed, offsetof(child_cfg_t, destroy)); + this->added->destroy_offset(this->added, offsetof(child_cfg_t, destroy)); + free(this); +} + +METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*, + private_peer_cfg_t *this, peer_cfg_t *other_pub) +{ + private_peer_cfg_t *other = (private_peer_cfg_t*)other_pub; + linked_list_t *removed, *added; + enumerator_t *mine, *others; + child_cfg_t *my_cfg, *other_cfg; + child_cfgs_replace_enumerator_t *enumerator; + bool found; + + removed = linked_list_create(); + + other->mutex->lock(other->mutex); + added = linked_list_create_from_enumerator( + other->child_cfgs->create_enumerator(other->child_cfgs)); + added->invoke_offset(added, offsetof(child_cfg_t, get_ref)); + other->mutex->unlock(other->mutex); + + this->mutex->lock(this->mutex); + others = added->create_enumerator(added); + mine = this->child_cfgs->create_enumerator(this->child_cfgs); + while (mine->enumerate(mine, &my_cfg)) + { + found = FALSE; + while (others->enumerate(others, &other_cfg)) + { + if (my_cfg->equals(my_cfg, other_cfg)) + { + added->remove_at(added, others); + other_cfg->destroy(other_cfg); + found = TRUE; + break; + } + } + added->reset_enumerator(added, others); + if (!found) + { + this->child_cfgs->remove_at(this->child_cfgs, mine); + removed->insert_last(removed, my_cfg); + } + } + while (others->enumerate(others, &other_cfg)) + { + this->child_cfgs->insert_last(this->child_cfgs, + other_cfg->get_ref(other_cfg)); + } + others->destroy(others); + mine->destroy(mine); + this->mutex->unlock(this->mutex); + + INIT(enumerator, + .public = { + .enumerate = (void*)_child_cfgs_replace_enumerate, + .destroy = (void*)_child_cfgs_replace_enumerator_destroy, + }, + .removed = removed, + .added = added, + ); + return &enumerator->public; +} + /** * child_cfg enumerator */ @@ -538,10 +649,6 @@ static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other) METHOD(peer_cfg_t, equals, bool, private_peer_cfg_t *this, private_peer_cfg_t *other) { - enumerator_t *e1, *e2; - host_t *vip1, *vip2; - char *pool1, *pool2; - if (this == other) { return TRUE; @@ -550,44 +657,15 @@ METHOD(peer_cfg_t, equals, bool, { return FALSE; } - - if (this->vips->get_count(this->vips) != other->vips->get_count(other->vips)) + if (!this->vips->equals_offset(this->vips, other->vips, + offsetof(host_t, ip_equals))) { return FALSE; } - e1 = create_virtual_ip_enumerator(this); - e2 = create_virtual_ip_enumerator(other); - if (e1->enumerate(e1, &vip1) && e2->enumerate(e2, &vip2)) - { - if (!vip1->ip_equals(vip1, vip2)) - { - e1->destroy(e1); - e2->destroy(e2); - return FALSE; - } - } - e1->destroy(e1); - e2->destroy(e2); - - if (this->pools->get_count(this->pools) != - other->pools->get_count(other->pools)) + if (!this->pools->equals_function(this->pools, other->pools, (void*)streq)) { return FALSE; } - e1 = create_pool_enumerator(this); - e2 = create_pool_enumerator(other); - if (e1->enumerate(e1, &pool1) && e2->enumerate(e2, &pool2)) - { - if (!streq(pool1, pool2)) - { - e1->destroy(e1); - e2->destroy(e2); - return FALSE; - } - } - e1->destroy(e1); - e2->destroy(e2); - return ( get_ike_version(this) == get_ike_version(other) && this->cert_policy == other->cert_policy && @@ -666,6 +744,10 @@ peer_cfg_t *peer_cfg_create(char *name, { jitter_time = reauth_time; } + if (dpd && dpd_timeout && dpd > dpd_timeout) + { + dpd_timeout = dpd; + } INIT(this, .public = { @@ -674,6 +756,7 @@ peer_cfg_t *peer_cfg_create(char *name, .get_ike_cfg = _get_ike_cfg, .add_child_cfg = _add_child_cfg, .remove_child_cfg = (void*)_remove_child_cfg, + .replace_child_cfgs = _replace_child_cfgs, .create_child_cfg_enumerator = _create_child_cfg_enumerator, .select_child_cfg = _select_child_cfg, .get_cert_policy = _get_cert_policy, diff --git a/src/libcharon/config/peer_cfg.h b/src/libcharon/config/peer_cfg.h index 3e780394a..b612a2ef1 100644 --- a/src/libcharon/config/peer_cfg.h +++ b/src/libcharon/config/peer_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2008 Tobias Brunner + * Copyright (C) 2007-2015 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -153,6 +153,20 @@ struct peer_cfg_t { */ void (*remove_child_cfg)(peer_cfg_t *this, enumerator_t *enumerator); + /** + * Replace the CHILD configs with those in the given PEER config. + * + * Configs that are equal are not replaced. + * + * The enumerator enumerates the removed and added CHILD configs + * (child_cfg_t*, bool), where the flag is FALSE for removed configs and + * TRUE for added configs. + * + * @param other other config to get CHILD configs from + * @return an enumerator over removed/added CHILD configs + */ + enumerator_t* (*replace_child_cfgs)(peer_cfg_t *this, peer_cfg_t *other); + /** * Create an enumerator for all attached CHILD configs. * diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index e59dcd9ec..95b6a00ea 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008-2014 Tobias Brunner * Copyright (C) 2006-2010 Martin Willi + * Copyright (C) 2013-2015 Andreas Steffen * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -640,20 +641,41 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) if (aead) { + /* Round 1 adds algorithms with at least 128 bit security strength */ enumerator = lib->crypto->create_aead_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &encryption, &plugin_name)) { switch (encryption) { - case ENCR_AES_CCM_ICV8: - case ENCR_AES_CCM_ICV12: + case ENCR_AES_GCM_ICV16: case ENCR_AES_CCM_ICV16: - case ENCR_AES_GCM_ICV8: + case ENCR_CAMELLIA_CCM_ICV16: + /* we assume that we support all AES/Camellia sizes */ + add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128); + add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192); + add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256); + break; + case ENCR_CHACHA20_POLY1305: + add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256); + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + /* Round 2 adds algorithms with less than 128 bit security strength */ + enumerator = lib->crypto->create_aead_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &encryption, &plugin_name)) + { + switch (encryption) + { case ENCR_AES_GCM_ICV12: - case ENCR_AES_GCM_ICV16: - case ENCR_CAMELLIA_CCM_ICV8: + case ENCR_AES_GCM_ICV8: + case ENCR_AES_CCM_ICV12: + case ENCR_AES_CCM_ICV8: case ENCR_CAMELLIA_CCM_ICV12: - case ENCR_CAMELLIA_CCM_ICV16: + case ENCR_CAMELLIA_CCM_ICV8: /* we assume that we support all AES/Camellia sizes */ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128); add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192); @@ -672,6 +694,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) } else { + /* Round 1 adds algorithms with at least 128 bit security strength */ enumerator = lib->crypto->create_crypter_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &encryption, &plugin_name)) { @@ -686,6 +709,18 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192); add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256); break; + default: + break; + } + } + enumerator->destroy(enumerator); + + /* Round 2 adds algorithms with less than 128 bit security strength */ + enumerator = lib->crypto->create_crypter_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &encryption, &plugin_name)) + { + switch (encryption) + { case ENCR_3DES: add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0); break; @@ -703,18 +738,33 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) return FALSE; } + /* Round 1 adds algorithms with at least 128 bit security strength */ enumerator = lib->crypto->create_signer_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &integrity, &plugin_name)) { switch (integrity) { - case AUTH_HMAC_SHA1_96: case AUTH_HMAC_SHA2_256_128: case AUTH_HMAC_SHA2_384_192: case AUTH_HMAC_SHA2_512_256: - case AUTH_HMAC_MD5_96: + add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0); + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + /* Round 2 adds algorithms with less than 128 bit security strength */ + enumerator = lib->crypto->create_signer_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &integrity, &plugin_name)) + { + switch (integrity) + { case AUTH_AES_XCBC_96: case AUTH_AES_CMAC_96: + case AUTH_HMAC_SHA1_96: + case AUTH_HMAC_MD5_96: add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0); break; default: @@ -724,16 +774,15 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) enumerator->destroy(enumerator); } + /* Round 1 adds algorithms with at least 128 bit security strength */ enumerator = lib->crypto->create_prf_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &prf, &plugin_name)) { switch (prf) { - case PRF_HMAC_SHA1: case PRF_HMAC_SHA2_256: case PRF_HMAC_SHA2_384: case PRF_HMAC_SHA2_512: - case PRF_HMAC_MD5: case PRF_AES128_XCBC: case PRF_AES128_CMAC: add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0); @@ -744,6 +793,63 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) } enumerator->destroy(enumerator); + /* Round 2 adds algorithms with less than 128 bit security strength */ + enumerator = lib->crypto->create_prf_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &prf, &plugin_name)) + { + switch (prf) + { + case PRF_HMAC_SHA1: + case PRF_HMAC_MD5: + add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0); + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + /* Round 1 adds ECC and NTRU algorithms with at least 128 bit security strength */ + enumerator = lib->crypto->create_dh_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &group, &plugin_name)) + { + switch (group) + { + case ECP_256_BIT: + case ECP_384_BIT: + case ECP_521_BIT: + case ECP_256_BP: + case ECP_384_BP: + case ECP_512_BP: + case NTRU_128_BIT: + case NTRU_192_BIT: + case NTRU_256_BIT: + add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0); + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + /* Round 2 adds other algorithms with at least 128 bit security strength */ + enumerator = lib->crypto->create_dh_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &group, &plugin_name)) + { + switch (group) + { + case MODP_3072_BIT: + case MODP_4096_BIT: + case MODP_8192_BIT: + add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0); + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + /* Round 3 adds algorithms with less than 128 bit security strength */ enumerator = lib->crypto->create_dh_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &group, &plugin_name)) { @@ -755,28 +861,16 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) case MODP_768_BIT: /* weak */ break; - case MODP_1024_BIT: - case MODP_1536_BIT: case MODP_2048_BIT: - case MODP_3072_BIT: - case MODP_4096_BIT: - case MODP_8192_BIT: - case ECP_256_BIT: - case ECP_384_BIT: - case ECP_521_BIT: - case MODP_1024_160: - case MODP_2048_224: case MODP_2048_256: - case ECP_192_BIT: + case MODP_2048_224: + case MODP_1536_BIT: + case MODP_1024_BIT: + case MODP_1024_160: case ECP_224_BIT: case ECP_224_BP: - case ECP_256_BP: - case ECP_384_BP: - case ECP_512_BP: + case ECP_192_BIT: case NTRU_112_BIT: - case NTRU_128_BIT: - case NTRU_192_BIT: - case NTRU_256_BIT: add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0); break; default: @@ -805,21 +899,27 @@ proposal_t *proposal_create_default(protocol_id_t protocol) } break; case PROTO_ESP: - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES, 0); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0); - add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); + add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128); + add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192); + add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256); + add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES, 0); + add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0); + add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); break; case PROTO_AH: - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0); - add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0); - add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0); + add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0); + add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); break; default: break; diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index dce2a7144..cef8b8992 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -16,6 +16,29 @@ * for more details. */ +/* + * Copyright (C) 2016 secunet Security Networks AG + * Copyright (C) 2016 Thomas Egerer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include #include #include @@ -110,6 +133,70 @@ static void dbg_bus(debug_t group, level_t level, char *fmt, ...) va_end(args); } +/** + * Data for registered custom loggers + */ +typedef struct { + /** + * Name of the custom logger (also used for loglevel configuration) + */ + char *name; + + /** + * Constructor to be called for custom logger creation + */ + custom_logger_constructor_t constructor; + +} custom_logger_entry_t; + +#define MAX_CUSTOM_LOGGERS 10 + +/** + * Static array for logger registration using __attribute__((constructor)) + */ +static custom_logger_entry_t custom_loggers[MAX_CUSTOM_LOGGERS]; +static int custom_logger_count; + +/** + * Described in header + */ +void register_custom_logger(char *name, + custom_logger_constructor_t constructor) +{ + if (custom_logger_count < MAX_CUSTOM_LOGGERS - 1) + { + custom_loggers[custom_logger_count].name = name; + custom_loggers[custom_logger_count].constructor = constructor; + custom_logger_count++; + } + else + { + fprintf(stderr, "failed to register custom logger, please increase " + "MAX_CUSTOM_LOGGERS"); + } +} + +/** + * Types of supported loggers + */ +typedef enum { + /** + * Syslog logger instance + */ + SYS_LOGGER, + + /** + * File logger instance + */ + FILE_LOGGER, + + /** + * Custom logger instance + */ + CUSTOM_LOGGER, + +} logger_type_t; + /** * Some metadata about configured loggers */ @@ -120,9 +207,9 @@ typedef struct { char *target; /** - * TRUE if this is a file logger + * Type of logger */ - bool file; + logger_type_t type; /** * The actual logger @@ -130,6 +217,7 @@ typedef struct { union { sys_logger_t *sys; file_logger_t *file; + custom_logger_t *custom; } logger; } logger_entry_t; @@ -139,13 +227,17 @@ typedef struct { */ static void logger_entry_destroy(logger_entry_t *this) { - if (this->file) - { - DESTROY_IF(this->logger.file); - } - else + switch (this->type) { - DESTROY_IF(this->logger.sys); + case FILE_LOGGER: + DESTROY_IF(this->logger.file); + break; + case SYS_LOGGER: + DESTROY_IF(this->logger.sys); + break; + case CUSTOM_LOGGER: + DESTROY_IF(this->logger.custom); + break; } free(this->target); free(this); @@ -156,13 +248,18 @@ static void logger_entry_destroy(logger_entry_t *this) */ static void logger_entry_unregister_destroy(logger_entry_t *this) { - if (this->file) + switch (this->type) { - charon->bus->remove_logger(charon->bus, &this->logger.file->logger); - } - else - { - charon->bus->remove_logger(charon->bus, &this->logger.sys->logger); + case FILE_LOGGER: + charon->bus->remove_logger(charon->bus, &this->logger.file->logger); + break; + case SYS_LOGGER: + charon->bus->remove_logger(charon->bus, &this->logger.sys->logger); + break; + case CUSTOM_LOGGER: + charon->bus->remove_logger(charon->bus, + &this->logger.custom->logger); + break; } logger_entry_destroy(this); } @@ -170,9 +267,10 @@ static void logger_entry_unregister_destroy(logger_entry_t *this) /** * Match a logger entry by target and whether it is a file or syslog logger */ -static bool logger_entry_match(logger_entry_t *this, char *target, bool *file) +static bool logger_entry_match(logger_entry_t *this, char *target, + logger_type_t *type) { - return this->file == *file && streq(this->target, target); + return this->type == *type && streq(this->target, target); } /** @@ -228,28 +326,45 @@ static int get_syslog_facility(char *facility) * Returns an existing or newly created logger entry (if found, it is removed * from the given linked list of existing loggers) */ -static logger_entry_t *get_logger_entry(char *target, bool is_file_logger, - linked_list_t *existing) +static logger_entry_t *get_logger_entry(char *target, logger_type_t type, + linked_list_t *existing, + custom_logger_constructor_t constructor) { logger_entry_t *entry; if (existing->find_first(existing, (void*)logger_entry_match, - (void**)&entry, target, &is_file_logger) != SUCCESS) + (void**)&entry, target, &type) != SUCCESS) { INIT(entry, .target = strdup(target), - .file = is_file_logger, + .type = type, ); - if (is_file_logger) + switch (type) { - entry->logger.file = file_logger_create(target); - } + case FILE_LOGGER: + entry->logger.file = file_logger_create(target); + break; + case SYS_LOGGER: #ifdef HAVE_SYSLOG - else - { - entry->logger.sys = sys_logger_create(get_syslog_facility(target)); - } + entry->logger.sys = sys_logger_create( + get_syslog_facility(target)); + break; +#else + free(entry); + return NULL; #endif /* HAVE_SYSLOG */ + case CUSTOM_LOGGER: + if (constructor) + { + entry->logger.custom = constructor(target); + } + if (!entry->logger.custom) + { + free(entry); + return NULL; + } + break; + } } else { @@ -266,9 +381,12 @@ static sys_logger_t *add_sys_logger(private_daemon_t *this, char *facility, { logger_entry_t *entry; - entry = get_logger_entry(facility, FALSE, current_loggers); - this->loggers->insert_last(this->loggers, entry); - return entry->logger.sys; + entry = get_logger_entry(facility, SYS_LOGGER, current_loggers, NULL); + if (entry) + { + this->loggers->insert_last(this->loggers, entry); + } + return entry ? entry->logger.sys : NULL; } /** @@ -279,9 +397,30 @@ static file_logger_t *add_file_logger(private_daemon_t *this, char *filename, { logger_entry_t *entry; - entry = get_logger_entry(filename, TRUE, current_loggers); - this->loggers->insert_last(this->loggers, entry); - return entry->logger.file; + entry = get_logger_entry(filename, FILE_LOGGER, current_loggers, NULL); + if (entry) + { + this->loggers->insert_last(this->loggers, entry); + } + return entry ? entry->logger.file : NULL; +} + + /** + * Create or reuse a custom logger + */ +static custom_logger_t *add_custom_logger(private_daemon_t *this, + custom_logger_entry_t *custom, + linked_list_t *current_loggers) +{ + logger_entry_t *entry; + + entry = get_logger_entry(custom->name, CUSTOM_LOGGER, current_loggers, + custom->constructor); + if (entry) + { + this->loggers->insert_last(this->loggers, entry); + } + return entry ? entry->logger.custom : NULL; } /** @@ -300,6 +439,11 @@ static void load_sys_logger(private_daemon_t *this, char *facility, } sys_logger = add_sys_logger(this, facility, current_loggers); + if (!sys_logger) + { + return; + } + sys_logger->set_options(sys_logger, lib->settings->get_bool(lib->settings, "%s.syslog.%s.ike_name", FALSE, lib->ns, facility)); @@ -339,6 +483,11 @@ static void load_file_logger(private_daemon_t *this, char *filename, "%s.filelog.%s.append", TRUE, lib->ns, filename); file_logger = add_file_logger(this, filename, current_loggers); + if (!file_logger) + { + return; + } + file_logger->set_options(file_logger, time_format, add_ms, ike_name); file_logger->open(file_logger, flush_line, append); @@ -353,12 +502,41 @@ static void load_file_logger(private_daemon_t *this, char *filename, charon->bus->add_logger(charon->bus, &file_logger->logger); } +/** + * Load the given custom logger configured in strongswan.conf + */ +static void load_custom_logger(private_daemon_t *this, + custom_logger_entry_t *entry, + linked_list_t *current_loggers) +{ + custom_logger_t *custom_logger; + debug_t group; + level_t def; + + custom_logger = add_custom_logger(this, entry, current_loggers); + if (!custom_logger) + { + return; + } + + def = lib->settings->get_int(lib->settings, "%s.customlog.%s.default", 1, + lib->ns, entry->name); + for (group = 0; group < DBG_MAX; group++) + { + custom_logger->set_level(custom_logger, group, + lib->settings->get_int(lib->settings, "%s.customlog.%s.%N", def, + lib->ns, entry->name, debug_lower_names, group)); + } + charon->bus->add_logger(charon->bus, &custom_logger->logger); +} + METHOD(daemon_t, load_loggers, void, private_daemon_t *this, level_t levels[DBG_MAX], bool to_stderr) { enumerator_t *enumerator; linked_list_t *current_loggers; char *target; + int i; this->mutex->lock(this->mutex); handle_syslog_identifier(this); @@ -380,6 +558,11 @@ METHOD(daemon_t, load_loggers, void, } enumerator->destroy(enumerator); + for (i = 0; i < custom_logger_count; ++i) + { + load_custom_logger(this, &custom_loggers[i], current_loggers); + } + if (!this->loggers->get_count(this->loggers) && levels) { /* setup legacy style default loggers configured via command-line */ file_logger_t *file_logger; @@ -431,15 +614,24 @@ METHOD(daemon_t, set_level, void, enumerator = this->loggers->create_enumerator(this->loggers); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->file) - { - entry->logger.file->set_level(entry->logger.file, group, level); - charon->bus->add_logger(charon->bus, &entry->logger.file->logger); - } - else + switch (entry->type) { - entry->logger.sys->set_level(entry->logger.sys, group, level); - charon->bus->add_logger(charon->bus, &entry->logger.sys->logger); + case FILE_LOGGER: + entry->logger.file->set_level(entry->logger.file, group, level); + charon->bus->add_logger(charon->bus, + &entry->logger.file->logger); + break; + case SYS_LOGGER: + entry->logger.sys->set_level(entry->logger.sys, group, level); + charon->bus->add_logger(charon->bus, + &entry->logger.sys->logger); + break; + case CUSTOM_LOGGER: + entry->logger.custom->set_level(entry->logger.custom, group, + level); + charon->bus->add_logger(charon->bus, + &entry->logger.sys->logger); + break; } } enumerator->destroy(enumerator); @@ -488,11 +680,13 @@ static void destroy(private_daemon_t *this) DESTROY_IF(this->kernel_handler); DESTROY_IF(this->public.traps); DESTROY_IF(this->public.shunts); + DESTROY_IF(this->public.redirect); DESTROY_IF(this->public.controller); DESTROY_IF(this->public.eap); DESTROY_IF(this->public.xauth); DESTROY_IF(this->public.backends); DESTROY_IF(this->public.socket); + DESTROY_IF(this->public.kernel); /* rehook library logging, shutdown logging */ dbg = dbg_old; @@ -670,6 +864,7 @@ private_daemon_t *daemon_create() .ref = 1, ); charon = &this->public; + this->public.kernel = kernel_interface_create(); this->public.attributes = attribute_manager_create(); this->public.controller = controller_create(); this->public.eap = eap_manager_create(); @@ -678,6 +873,7 @@ private_daemon_t *daemon_create() this->public.socket = socket_manager_create(); this->public.traps = trap_manager_create(); this->public.shunts = shunt_manager_create(); + this->public.redirect = redirect_manager_create(); this->kernel_handler = kernel_handler_create(); return this; diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h index d16bf1ddb..48b9c7ec3 100644 --- a/src/libcharon/daemon.h +++ b/src/libcharon/daemon.h @@ -16,6 +16,29 @@ * for more details. */ +/* + * Copyright (C) 2016 secunet Security Networks AG + * Copyright (C) 2016 Thomas Egerer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup libcharon libcharon * @@ -40,7 +63,7 @@ * @defgroup payloads payloads * @ingroup encoding * - * @defgroup ckernel kernel + * @defgroup kernel kernel * @ingroup libcharon * * @defgroup network network @@ -156,15 +179,18 @@ typedef struct daemon_t daemon_t; #include +#include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -214,6 +240,11 @@ struct daemon_t { */ socket_manager_t *socket; + /** + * Kernel interface to communicate with kernel + */ + kernel_interface_t *kernel; + /** * A ike_sa_manager_t instance. */ @@ -234,6 +265,11 @@ struct daemon_t { */ shunt_manager_t *shunts; + /** + * Manager for IKE redirect providers + */ + redirect_manager_t *redirect; + /** * Manager for the different configuration backends. */ @@ -311,8 +347,8 @@ struct daemon_t { bool to_stderr); /** - * Set the log level for the given log group for all configured file- and - * syslog-loggers. + * Set the log level for the given log group for all configured file-, + * syslog and custom-loggers. * * @param group log group * @param level log level @@ -345,4 +381,15 @@ bool libcharon_init(); */ void libcharon_deinit(); +/** + * Register a custom logger constructor. + * + * To be called from __attribute__((constructor)) functions. + * + * @param name name of the logger (also used for loglevel config) + * @param constructor constructor to create custom logger + */ +void register_custom_logger(char *name, + custom_logger_constructor_t constructor); + #endif /** DAEMON_H_ @}*/ diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 3303024cd..bbdc4629d 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -551,13 +551,13 @@ static payload_order_t aggressive_i_order[] = { {PLV1_NONCE, 0}, {PLV1_ID, 0}, {PLV1_CERTIFICATE, 0}, + {PLV1_CERTREQ, 0}, + {PLV1_NOTIFY, 0}, + {PLV1_VENDOR_ID, 0}, {PLV1_NAT_D, 0}, {PLV1_NAT_D_DRAFT_00_03, 0}, {PLV1_SIGNATURE, 0}, {PLV1_HASH, 0}, - {PLV1_CERTREQ, 0}, - {PLV1_NOTIFY, 0}, - {PLV1_VENDOR_ID, 0}, {PLV1_FRAGMENT, 0}, }; @@ -591,13 +591,13 @@ static payload_order_t aggressive_r_order[] = { {PLV1_NONCE, 0}, {PLV1_ID, 0}, {PLV1_CERTIFICATE, 0}, + {PLV1_CERTREQ, 0}, + {PLV1_NOTIFY, 0}, + {PLV1_VENDOR_ID, 0}, {PLV1_NAT_D, 0}, {PLV1_NAT_D_DRAFT_00_03, 0}, {PLV1_SIGNATURE, 0}, {PLV1_HASH, 0}, - {PLV1_CERTREQ, 0}, - {PLV1_NOTIFY, 0}, - {PLV1_VENDOR_ID, 0}, {PLV1_FRAGMENT, 0}, }; diff --git a/src/libcharon/encoding/payloads/configuration_attribute.c b/src/libcharon/encoding/payloads/configuration_attribute.c index 481bb7bc6..4ecdf569d 100644 --- a/src/libcharon/encoding/payloads/configuration_attribute.c +++ b/src/libcharon/encoding/payloads/configuration_attribute.c @@ -132,6 +132,7 @@ METHOD(payload_t, verify, status_t, case INTERNAL_IP4_NBNS: case INTERNAL_ADDRESS_EXPIRY: case INTERNAL_IP4_DHCP: + case P_CSCF_IP4_ADDRESS: if (this->length_or_value != 0 && this->length_or_value != 4) { failed = TRUE; @@ -144,6 +145,13 @@ METHOD(payload_t, verify, status_t, } break; case INTERNAL_IP6_ADDRESS: + if (this->type == PLV1_CONFIGURATION_ATTRIBUTE && + this->length_or_value == 16) + { /* 16 bytes are correct for IKEv1, but older releases sent a + * prefix byte so we still accept 0 or 17 as in IKEv2 */ + break; + } + /* fall-through */ case INTERNAL_IP6_SUBNET: if (this->length_or_value != 0 && this->length_or_value != 17) { @@ -153,6 +161,7 @@ METHOD(payload_t, verify, status_t, case INTERNAL_IP6_DNS: case INTERNAL_IP6_NBNS: case INTERNAL_IP6_DHCP: + case P_CSCF_IP6_ADDRESS: if (this->length_or_value != 0 && this->length_or_value != 16) { failed = TRUE; diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c index 9c0e2602b..be37d30e5 100644 --- a/src/libcharon/kernel/kernel_handler.c +++ b/src/libcharon/kernel/kernel_handler.c @@ -15,7 +15,6 @@ #include "kernel_handler.h" -#include #include #include #include @@ -135,8 +134,7 @@ METHOD(kernel_listener_t, roam, bool, METHOD(kernel_handler_t, destroy, void, private_kernel_handler_t *this) { - hydra->kernel_interface->remove_listener(hydra->kernel_interface, - &this->public.listener); + charon->kernel->remove_listener(charon->kernel, &this->public.listener); free(this); } @@ -157,8 +155,7 @@ kernel_handler_t *kernel_handler_create() }, ); - hydra->kernel_interface->add_listener(hydra->kernel_interface, - &this->public.listener); + charon->kernel->add_listener(charon->kernel, &this->public.listener); return &this->public; } diff --git a/src/libcharon/kernel/kernel_handler.h b/src/libcharon/kernel/kernel_handler.h index 48ad6889c..f1fa0bdfc 100644 --- a/src/libcharon/kernel/kernel_handler.h +++ b/src/libcharon/kernel/kernel_handler.h @@ -15,7 +15,7 @@ /** * @defgroup kernel_handler kernel_handler - * @{ @ingroup ckernel + * @{ @ingroup kernel */ #ifndef KERNEL_HANDLER_H_ diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c new file mode 100644 index 000000000..40c4ee589 --- /dev/null +++ b/src/libcharon/kernel/kernel_interface.c @@ -0,0 +1,1085 @@ +/* + * Copyright (C) 2008-2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/* + * Copyright (c) 2012 Nanoteq Pty Ltd + * + * 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 "kernel_interface.h" + +#include +#include +#include +#include +#include + +typedef struct private_kernel_interface_t private_kernel_interface_t; + +typedef struct kernel_algorithm_t kernel_algorithm_t; + +/** + * Mapping of IKE algorithms to kernel-specific algorithm identifiers + */ +struct kernel_algorithm_t { + + /** + * Transform type of the algorithm + */ + transform_type_t type; + + /** + * Identifier specified in IKE + */ + u_int16_t ike; + + /** + * Identifier as defined in pfkeyv2.h + */ + u_int16_t kernel; + + /** + * Name of the algorithm in linux crypto API + */ + char *name; +}; + +/** + * Private data of a kernel_interface_t object. + */ +struct private_kernel_interface_t { + + /** + * Public part of kernel_interface_t object. + */ + kernel_interface_t public; + + /** + * Registered IPsec constructor + */ + kernel_ipsec_constructor_t ipsec_constructor; + + /** + * Registered net constructor + */ + kernel_net_constructor_t net_constructor; + + /** + * ipsec interface + */ + kernel_ipsec_t *ipsec; + + /** + * network interface + */ + kernel_net_t *net; + + /** + * mutex for listeners + */ + mutex_t *mutex; + + /** + * list of registered listeners + */ + linked_list_t *listeners; + + /** + * Reqid entries indexed by reqids + */ + hashtable_t *reqids; + + /** + * Reqid entries indexed by traffic selectors + */ + hashtable_t *reqids_by_ts; + + /** + * mutex for algorithm mappings + */ + mutex_t *mutex_algs; + + /** + * List of algorithm mappings (kernel_algorithm_t*) + */ + linked_list_t *algorithms; + + /** + * List of interface names to include or exclude (char*), NULL if interfaces + * are not filtered + */ + linked_list_t *ifaces_filter; + + /** + * TRUE to exclude interfaces listed in ifaces_filter, FALSE to consider + * only those listed there + */ + bool ifaces_exclude; +}; + +METHOD(kernel_interface_t, get_features, kernel_feature_t, + private_kernel_interface_t *this) +{ + kernel_feature_t features = 0; + + if (this->ipsec && this->ipsec->get_features) + { + features |= this->ipsec->get_features(this->ipsec); + } + if (this->net && this->net->get_features) + { + features |= this->net->get_features(this->net); + } + return features; +} + +METHOD(kernel_interface_t, get_spi, status_t, + private_kernel_interface_t *this, host_t *src, host_t *dst, + u_int8_t protocol, u_int32_t *spi) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->get_spi(this->ipsec, src, dst, protocol, spi); +} + +METHOD(kernel_interface_t, get_cpi, status_t, + private_kernel_interface_t *this, host_t *src, host_t *dst, + u_int16_t *cpi) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->get_cpi(this->ipsec, src, dst, cpi); +} + +/** + * Reqid mapping entry + */ +typedef struct { + /** allocated reqid */ + u_int32_t reqid; + /** references to this entry */ + u_int refs; + /** inbound mark used for SA */ + mark_t mark_in; + /** outbound mark used for SA */ + mark_t mark_out; + /** local traffic selectors */ + array_t *local; + /** remote traffic selectors */ + array_t *remote; +} reqid_entry_t; + +/** + * Destroy a reqid mapping entry + */ +static void reqid_entry_destroy(reqid_entry_t *entry) +{ + array_destroy_offset(entry->local, offsetof(traffic_selector_t, destroy)); + array_destroy_offset(entry->remote, offsetof(traffic_selector_t, destroy)); + free(entry); +} + +/** + * Hashtable hash function for reqid entries using reqid as key + */ +static u_int hash_reqid(reqid_entry_t *entry) +{ + return chunk_hash_inc(chunk_from_thing(entry->reqid), + chunk_hash_inc(chunk_from_thing(entry->mark_in), + chunk_hash(chunk_from_thing(entry->mark_out)))); +} + +/** + * Hashtable equals function for reqid entries using reqid as key + */ +static bool equals_reqid(reqid_entry_t *a, reqid_entry_t *b) +{ + return a->reqid == b->reqid && + a->mark_in.value == b->mark_in.value && + a->mark_in.mask == b->mark_in.mask && + a->mark_out.value == b->mark_out.value && + a->mark_out.mask == b->mark_out.mask; +} + +/** + * Hash an array of traffic selectors + */ +static u_int hash_ts_array(array_t *array, u_int hash) +{ + enumerator_t *enumerator; + traffic_selector_t *ts; + + enumerator = array_create_enumerator(array); + while (enumerator->enumerate(enumerator, &ts)) + { + hash = ts->hash(ts, hash); + } + enumerator->destroy(enumerator); + + return hash; +} + +/** + * Hashtable hash function for reqid entries using traffic selectors as key + */ +static u_int hash_reqid_by_ts(reqid_entry_t *entry) +{ + return hash_ts_array(entry->local, hash_ts_array(entry->remote, + chunk_hash_inc(chunk_from_thing(entry->mark_in), + chunk_hash(chunk_from_thing(entry->mark_out))))); +} + +/** + * Compare two array with traffic selectors for equality + */ +static bool ts_array_equals(array_t *a, array_t *b) +{ + traffic_selector_t *tsa, *tsb; + enumerator_t *ae, *be; + bool equal = TRUE; + + if (array_count(a) != array_count(b)) + { + return FALSE; + } + + ae = array_create_enumerator(a); + be = array_create_enumerator(b); + while (equal && ae->enumerate(ae, &tsa) && be->enumerate(be, &tsb)) + { + equal = tsa->equals(tsa, tsb); + } + ae->destroy(ae); + be->destroy(be); + + return equal; +} + +/** + * Hashtable equals function for reqid entries using traffic selectors as key + */ +static bool equals_reqid_by_ts(reqid_entry_t *a, reqid_entry_t *b) +{ + return ts_array_equals(a->local, b->local) && + ts_array_equals(a->remote, b->remote) && + a->mark_in.value == b->mark_in.value && + a->mark_in.mask == b->mark_in.mask && + a->mark_out.value == b->mark_out.value && + a->mark_out.mask == b->mark_out.mask; +} + +/** + * Create an array from copied traffic selector list items + */ +static array_t *array_from_ts_list(linked_list_t *list) +{ + enumerator_t *enumerator; + traffic_selector_t *ts; + array_t *array; + + array = array_create(0, 0); + + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &ts)) + { + array_insert(array, ARRAY_TAIL, ts->clone(ts)); + } + enumerator->destroy(enumerator); + + return array; +} + +METHOD(kernel_interface_t, alloc_reqid, status_t, + private_kernel_interface_t *this, + linked_list_t *local_ts, linked_list_t *remote_ts, + mark_t mark_in, mark_t mark_out, u_int32_t *reqid) +{ + static u_int32_t counter = 0; + reqid_entry_t *entry = NULL, *tmpl; + status_t status = SUCCESS; + + INIT(tmpl, + .local = array_from_ts_list(local_ts), + .remote = array_from_ts_list(remote_ts), + .mark_in = mark_in, + .mark_out = mark_out, + .reqid = *reqid, + ); + + this->mutex->lock(this->mutex); + if (tmpl->reqid) + { + /* search by reqid if given */ + entry = this->reqids->get(this->reqids, tmpl); + } + if (entry) + { + /* we don't require a traffic selector match for explicit reqids, + * as we wan't to reuse a reqid for trap-triggered policies that + * got narrowed during negotiation. */ + reqid_entry_destroy(tmpl); + } + else + { + /* search by traffic selectors */ + entry = this->reqids_by_ts->get(this->reqids_by_ts, tmpl); + if (entry) + { + reqid_entry_destroy(tmpl); + } + else + { + /* none found, create a new entry, allocating a reqid */ + entry = tmpl; + entry->reqid = ++counter; + this->reqids_by_ts->put(this->reqids_by_ts, entry, entry); + this->reqids->put(this->reqids, entry, entry); + } + *reqid = entry->reqid; + } + entry->refs++; + this->mutex->unlock(this->mutex); + + return status; +} + +METHOD(kernel_interface_t, release_reqid, status_t, + private_kernel_interface_t *this, u_int32_t reqid, + mark_t mark_in, mark_t mark_out) +{ + reqid_entry_t *entry, tmpl = { + .reqid = reqid, + .mark_in = mark_in, + .mark_out = mark_out, + }; + + this->mutex->lock(this->mutex); + entry = this->reqids->remove(this->reqids, &tmpl); + if (entry) + { + if (--entry->refs == 0) + { + entry = this->reqids_by_ts->remove(this->reqids_by_ts, entry); + if (entry) + { + reqid_entry_destroy(entry); + } + } + else + { + this->reqids->put(this->reqids, entry, entry); + } + } + this->mutex->unlock(this->mutex); + + if (entry) + { + return SUCCESS; + } + return NOT_FOUND; +} + +METHOD(kernel_interface_t, add_sa, status_t, + private_kernel_interface_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark, + u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, + u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, + u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid, + mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode, + ipcomp, cpi, replay_window, initiator, encap, esn, inbound, + update, src_ts, dst_ts); +} + +METHOD(kernel_interface_t, update_sa, status_t, + private_kernel_interface_t *this, u_int32_t spi, u_int8_t protocol, + u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst, + bool encap, bool new_encap, mark_t mark) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->update_sa(this->ipsec, spi, protocol, cpi, src, dst, + new_src, new_dst, encap, new_encap, mark); +} + +METHOD(kernel_interface_t, query_sa, status_t, + private_kernel_interface_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, mark_t mark, + u_int64_t *bytes, u_int64_t *packets, time_t *time) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, mark, + bytes, packets, time); +} + +METHOD(kernel_interface_t, del_sa, status_t, + private_kernel_interface_t *this, host_t *src, host_t *dst, u_int32_t spi, + u_int8_t protocol, u_int16_t cpi, mark_t mark) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi, mark); +} + +METHOD(kernel_interface_t, flush_sas, status_t, + private_kernel_interface_t *this) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->flush_sas(this->ipsec); +} + +METHOD(kernel_interface_t, add_policy, status_t, + private_kernel_interface_t *this, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, + mark_t mark, policy_priority_t priority) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts, + direction, type, sa, mark, priority); +} + +METHOD(kernel_interface_t, query_policy, status_t, + private_kernel_interface_t *this, traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, + time_t *use_time) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->query_policy(this->ipsec, src_ts, dst_ts, + direction, mark, use_time); +} + +METHOD(kernel_interface_t, del_policy, status_t, + private_kernel_interface_t *this, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, + mark_t mark, policy_priority_t priority) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->del_policy(this->ipsec, src, dst, src_ts, dst_ts, + direction, type, sa, mark, priority); +} + +METHOD(kernel_interface_t, flush_policies, status_t, + private_kernel_interface_t *this) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->flush_policies(this->ipsec); +} + +METHOD(kernel_interface_t, get_source_addr, host_t*, + private_kernel_interface_t *this, host_t *dest, host_t *src) +{ + if (!this->net) + { + return NULL; + } + return this->net->get_source_addr(this->net, dest, src); +} + +METHOD(kernel_interface_t, get_nexthop, host_t*, + private_kernel_interface_t *this, host_t *dest, int prefix, host_t *src) +{ + if (!this->net) + { + return NULL; + } + return this->net->get_nexthop(this->net, dest, prefix, src); +} + +METHOD(kernel_interface_t, get_interface, bool, + private_kernel_interface_t *this, host_t *host, char **name) +{ + if (!this->net) + { + return NULL; + } + return this->net->get_interface(this->net, host, name); +} + +METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*, + private_kernel_interface_t *this, kernel_address_type_t which) +{ + if (!this->net) + { + return enumerator_create_empty(); + } + return this->net->create_address_enumerator(this->net, which); +} + +METHOD(kernel_interface_t, add_ip, status_t, + private_kernel_interface_t *this, host_t *virtual_ip, int prefix, + char *iface) +{ + if (!this->net) + { + return NOT_SUPPORTED; + } + return this->net->add_ip(this->net, virtual_ip, prefix, iface); +} + +METHOD(kernel_interface_t, del_ip, status_t, + private_kernel_interface_t *this, host_t *virtual_ip, int prefix, bool wait) +{ + if (!this->net) + { + return NOT_SUPPORTED; + } + return this->net->del_ip(this->net, virtual_ip, prefix, wait); +} + +METHOD(kernel_interface_t, add_route, status_t, + private_kernel_interface_t *this, chunk_t dst_net, + u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name) +{ + if (!this->net) + { + return NOT_SUPPORTED; + } + return this->net->add_route(this->net, dst_net, prefixlen, gateway, + src_ip, if_name); +} + +METHOD(kernel_interface_t, del_route, status_t, + private_kernel_interface_t *this, chunk_t dst_net, + u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name) +{ + if (!this->net) + { + return NOT_SUPPORTED; + } + return this->net->del_route(this->net, dst_net, prefixlen, gateway, + src_ip, if_name); +} + +METHOD(kernel_interface_t, bypass_socket, bool, + private_kernel_interface_t *this, int fd, int family) +{ + if (!this->ipsec) + { + return FALSE; + } + return this->ipsec->bypass_socket(this->ipsec, fd, family); +} + +METHOD(kernel_interface_t, enable_udp_decap, bool, + private_kernel_interface_t *this, int fd, int family, u_int16_t port) +{ + if (!this->ipsec) + { + return FALSE; + } + return this->ipsec->enable_udp_decap(this->ipsec, fd, family, port); +} + +METHOD(kernel_interface_t, is_interface_usable, bool, + private_kernel_interface_t *this, const char *iface) +{ + status_t expected; + + if (!this->ifaces_filter) + { + return TRUE; + } + expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS; + return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq, + NULL, iface) == expected; +} + +METHOD(kernel_interface_t, all_interfaces_usable, bool, + private_kernel_interface_t *this) +{ + return this->ifaces_filter == NULL; +} + +METHOD(kernel_interface_t, get_address_by_ts, status_t, + private_kernel_interface_t *this, traffic_selector_t *ts, + host_t **ip, bool *vip) +{ + enumerator_t *addrs; + host_t *host; + int family; + bool found = FALSE; + + DBG2(DBG_KNL, "getting a local address in traffic selector %R", ts); + + /* if we have a family which includes localhost, we do not + * search for an IP, we use the default */ + family = ts->get_type(ts) == TS_IPV4_ADDR_RANGE ? AF_INET : AF_INET6; + + if (family == AF_INET) + { + host = host_create_from_string("127.0.0.1", 0); + } + else + { + host = host_create_from_string("::1", 0); + } + + if (ts->includes(ts, host)) + { + *ip = host_create_any(family); + host->destroy(host); + DBG2(DBG_KNL, "using host %H", *ip); + return SUCCESS; + } + host->destroy(host); + + /* try virtual IPs only first (on all interfaces) */ + addrs = create_address_enumerator(this, + ADDR_TYPE_ALL ^ ADDR_TYPE_REGULAR); + while (addrs->enumerate(addrs, (void**)&host)) + { + if (ts->includes(ts, host)) + { + found = TRUE; + *ip = host->clone(host); + if (vip) + { + *vip = TRUE; + } + break; + } + } + addrs->destroy(addrs); + + if (!found) + { /* then try the regular addresses (on all interfaces) */ + addrs = create_address_enumerator(this, + ADDR_TYPE_ALL ^ ADDR_TYPE_VIRTUAL); + while (addrs->enumerate(addrs, (void**)&host)) + { + if (ts->includes(ts, host)) + { + found = TRUE; + *ip = host->clone(host); + if (vip) + { + *vip = FALSE; + } + break; + } + } + addrs->destroy(addrs); + } + + if (!found) + { + DBG2(DBG_KNL, "no local address found in traffic selector %R", ts); + return FAILED; + } + + DBG2(DBG_KNL, "using host %H", *ip); + return SUCCESS; +} + + +METHOD(kernel_interface_t, add_ipsec_interface, bool, + private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor) +{ + if (!this->ipsec) + { + this->ipsec_constructor = constructor; + this->ipsec = constructor(); + return this->ipsec != NULL; + } + return FALSE; +} + +METHOD(kernel_interface_t, remove_ipsec_interface, bool, + private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor) +{ + if (constructor == this->ipsec_constructor && this->ipsec) + { + this->ipsec->destroy(this->ipsec); + this->ipsec = NULL; + return TRUE; + } + return FALSE; +} + +METHOD(kernel_interface_t, add_net_interface, bool, + private_kernel_interface_t *this, kernel_net_constructor_t constructor) +{ + if (!this->net) + { + this->net_constructor = constructor; + this->net = constructor(); + return this->net != NULL; + } + return FALSE; +} + +METHOD(kernel_interface_t, remove_net_interface, bool, + private_kernel_interface_t *this, kernel_net_constructor_t constructor) +{ + if (constructor == this->net_constructor && this->net) + { + this->net->destroy(this->net); + this->net = NULL; + return TRUE; + } + return FALSE; +} + +METHOD(kernel_interface_t, add_listener, void, + private_kernel_interface_t *this, kernel_listener_t *listener) +{ + this->mutex->lock(this->mutex); + this->listeners->insert_last(this->listeners, listener); + this->mutex->unlock(this->mutex); +} + +METHOD(kernel_interface_t, remove_listener, void, + private_kernel_interface_t *this, kernel_listener_t *listener) +{ + this->mutex->lock(this->mutex); + this->listeners->remove(this->listeners, listener, NULL); + this->mutex->unlock(this->mutex); +} + +METHOD(kernel_interface_t, acquire, void, + private_kernel_interface_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts) +{ + kernel_listener_t *listener; + enumerator_t *enumerator; + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &listener)) + { + if (listener->acquire && + !listener->acquire(listener, reqid, src_ts, dst_ts)) + { + this->listeners->remove_at(this->listeners, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +METHOD(kernel_interface_t, expire, void, + private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard) +{ + kernel_listener_t *listener; + enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &listener)) + { + if (listener->expire && + !listener->expire(listener, protocol, spi, dst, hard)) + { + this->listeners->remove_at(this->listeners, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +METHOD(kernel_interface_t, mapping, void, + private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, host_t *remote) +{ + kernel_listener_t *listener; + enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &listener)) + { + if (listener->mapping && + !listener->mapping(listener, protocol, spi, dst, remote)) + { + this->listeners->remove_at(this->listeners, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +METHOD(kernel_interface_t, migrate, void, + private_kernel_interface_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, host_t *local, host_t *remote) +{ + kernel_listener_t *listener; + enumerator_t *enumerator; + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &listener)) + { + if (listener->migrate && + !listener->migrate(listener, reqid, src_ts, dst_ts, direction, + local, remote)) + { + this->listeners->remove_at(this->listeners, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +static bool call_roam(kernel_listener_t *listener, bool *roam) +{ + return listener->roam && !listener->roam(listener, *roam); +} + +METHOD(kernel_interface_t, roam, void, + private_kernel_interface_t *this, bool address) +{ + this->mutex->lock(this->mutex); + this->listeners->remove(this->listeners, &address, (void*)call_roam); + this->mutex->unlock(this->mutex); +} + +METHOD(kernel_interface_t, tun, void, + private_kernel_interface_t *this, tun_device_t *tun, bool created) +{ + kernel_listener_t *listener; + enumerator_t *enumerator; + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &listener)) + { + if (listener->tun && + !listener->tun(listener, tun, created)) + { + this->listeners->remove_at(this->listeners, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +METHOD(kernel_interface_t, register_algorithm, void, + private_kernel_interface_t *this, u_int16_t alg_id, transform_type_t type, + u_int16_t kernel_id, char *kernel_name) +{ + kernel_algorithm_t *algorithm; + + INIT(algorithm, + .type = type, + .ike = alg_id, + .kernel = kernel_id, + .name = strdup(kernel_name), + ); + + this->mutex_algs->lock(this->mutex_algs); + this->algorithms->insert_first(this->algorithms, algorithm); + this->mutex_algs->unlock(this->mutex_algs); +} + +METHOD(kernel_interface_t, lookup_algorithm, bool, + private_kernel_interface_t *this, u_int16_t alg_id, transform_type_t type, + u_int16_t *kernel_id, char **kernel_name) +{ + kernel_algorithm_t *algorithm; + enumerator_t *enumerator; + bool found = FALSE; + + this->mutex_algs->lock(this->mutex_algs); + enumerator = this->algorithms->create_enumerator(this->algorithms); + while (enumerator->enumerate(enumerator, &algorithm)) + { + if (algorithm->type == type && algorithm->ike == alg_id) + { + if (kernel_id) + { + *kernel_id = algorithm->kernel; + } + if (kernel_name) + { + *kernel_name = algorithm->name; + } + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + this->mutex_algs->unlock(this->mutex_algs); + return found; +} + +METHOD(kernel_interface_t, destroy, void, + private_kernel_interface_t *this) +{ + kernel_algorithm_t *algorithm; + + while (this->algorithms->remove_first(this->algorithms, + (void**)&algorithm) == SUCCESS) + { + free(algorithm->name); + free(algorithm); + } + this->algorithms->destroy(this->algorithms); + this->mutex_algs->destroy(this->mutex_algs); + DESTROY_IF(this->ipsec); + DESTROY_IF(this->net); + DESTROY_FUNCTION_IF(this->ifaces_filter, (void*)free); + this->reqids->destroy(this->reqids); + this->reqids_by_ts->destroy(this->reqids_by_ts); + this->listeners->destroy(this->listeners); + this->mutex->destroy(this->mutex); + free(this); +} + +/* + * Described in header-file + */ +kernel_interface_t *kernel_interface_create() +{ + private_kernel_interface_t *this; + char *ifaces; + + INIT(this, + .public = { + .get_features = _get_features, + .get_spi = _get_spi, + .get_cpi = _get_cpi, + .alloc_reqid = _alloc_reqid, + .release_reqid = _release_reqid, + .add_sa = _add_sa, + .update_sa = _update_sa, + .query_sa = _query_sa, + .del_sa = _del_sa, + .flush_sas = _flush_sas, + .add_policy = _add_policy, + .query_policy = _query_policy, + .del_policy = _del_policy, + .flush_policies = _flush_policies, + .get_source_addr = _get_source_addr, + .get_nexthop = _get_nexthop, + .get_interface = _get_interface, + .create_address_enumerator = _create_address_enumerator, + .add_ip = _add_ip, + .del_ip = _del_ip, + .add_route = _add_route, + .del_route = _del_route, + .bypass_socket = _bypass_socket, + .enable_udp_decap = _enable_udp_decap, + + .is_interface_usable = _is_interface_usable, + .all_interfaces_usable = _all_interfaces_usable, + .get_address_by_ts = _get_address_by_ts, + .add_ipsec_interface = _add_ipsec_interface, + .remove_ipsec_interface = _remove_ipsec_interface, + .add_net_interface = _add_net_interface, + .remove_net_interface = _remove_net_interface, + + .add_listener = _add_listener, + .remove_listener = _remove_listener, + .register_algorithm = _register_algorithm, + .lookup_algorithm = _lookup_algorithm, + .acquire = _acquire, + .expire = _expire, + .mapping = _mapping, + .migrate = _migrate, + .roam = _roam, + .tun = _tun, + .destroy = _destroy, + }, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .listeners = linked_list_create(), + .mutex_algs = mutex_create(MUTEX_TYPE_DEFAULT), + .algorithms = linked_list_create(), + .reqids = hashtable_create((hashtable_hash_t)hash_reqid, + (hashtable_equals_t)equals_reqid, 8), + .reqids_by_ts = hashtable_create((hashtable_hash_t)hash_reqid_by_ts, + (hashtable_equals_t)equals_reqid_by_ts, 8), + ); + + ifaces = lib->settings->get_str(lib->settings, + "%s.interfaces_use", NULL, lib->ns); + if (!ifaces) + { + this->ifaces_exclude = TRUE; + ifaces = lib->settings->get_str(lib->settings, + "%s.interfaces_ignore", NULL, lib->ns); + } + if (ifaces) + { + enumerator_t *enumerator; + char *iface; + + enumerator = enumerator_create_token(ifaces, ",", " "); + while (enumerator->enumerate(enumerator, &iface)) + { + if (!this->ifaces_filter) + { + this->ifaces_filter = linked_list_create(); + } + this->ifaces_filter->insert_last(this->ifaces_filter, + strdup(iface)); + } + enumerator->destroy(enumerator); + } + + return &this->public; +} diff --git a/src/libcharon/kernel/kernel_interface.h b/src/libcharon/kernel/kernel_interface.h new file mode 100644 index 000000000..6793c6cc6 --- /dev/null +++ b/src/libcharon/kernel/kernel_interface.h @@ -0,0 +1,655 @@ +/* + * Copyright (C) 2006-2015 Tobias Brunner + * Copyright (C) 2006 Daniel Roethlisberger + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/* + * Copyright (c) 2012 Nanoteq Pty Ltd + * + * 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 kernel_interface kernel_interface + * @{ @ingroup kernel + */ + +#ifndef KERNEL_INTERFACE_H_ +#define KERNEL_INTERFACE_H_ + +typedef struct kernel_interface_t kernel_interface_t; +typedef enum kernel_feature_t kernel_feature_t; + +#include +#include + +#include +#include +#include + +/** + * Bitfield of optional features a kernel backend supports. + * + * This feature-set is for both, kernel_ipsec_t and kernel_net_t. Each + * backend returns a subset of these features. + */ +enum kernel_feature_t { + /** IPsec can process ESPv3 (RFC 4303) TFC padded packets */ + KERNEL_ESP_V3_TFC = (1<<0), + /** Networking requires an "exclude" route for IKE/ESP packets */ + KERNEL_REQUIRE_EXCLUDE_ROUTE = (1<<1), + /** IPsec implementation requires UDP encapsulation of ESP packets */ + KERNEL_REQUIRE_UDP_ENCAPSULATION = (1<<2), + /** IPsec backend does not require a policy reinstall on SA updates */ + KERNEL_NO_POLICY_UPDATES = (1<<3), +}; + +/** + * Constructor function for ipsec kernel interface + */ +typedef kernel_ipsec_t* (*kernel_ipsec_constructor_t)(void); + +/** + * Constructor function for network kernel interface + */ +typedef kernel_net_t* (*kernel_net_constructor_t)(void); + +/** + * Manager and wrapper for different kernel interfaces. + * + * The kernel interface handles the communication with the kernel + * for SA and policy management and interface and IP address management. + */ +struct kernel_interface_t { + + /** + * Get the feature set supported by the net and ipsec kernel backends. + * + * @return ORed feature-set of backends + */ + kernel_feature_t (*get_features)(kernel_interface_t *this); + + /** + * Get a SPI from the kernel. + * + * @param src source address of SA + * @param dst destination address of SA + * @param protocol protocol for SA (ESP/AH) + * @param spi allocated spi + * @return SUCCESS if operation completed + */ + status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst, + u_int8_t protocol, u_int32_t *spi); + + /** + * Get a Compression Parameter Index (CPI) from the kernel. + * + * @param src source address of SA + * @param dst destination address of SA + * @param cpi allocated cpi + * @return SUCCESS if operation completed + */ + status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst, + u_int16_t *cpi); + + /** + * Allocate or confirm a reqid to use for a given SA pair. + * + * Each returned reqid by a successful call to alloc_reqid() must be + * released using release_reqid(). + * + * The reqid parameter is an in/out parameter. If it points to non-zero, + * the reqid is confirmed and registered for use. If it points to zero, + * a reqid is allocated for the given selectors, and returned to reqid. + * + * @param local_ts traffic selectors of local side for SA + * @param remote_ts traffic selectors of remote side for SA + * @param mark_in inbound mark on SA + * @param mark_out outbound mark on SA + * @param reqid allocated reqid + * @return SUCCESS if reqid allocated + */ + status_t (*alloc_reqid)(kernel_interface_t *this, + linked_list_t *local_ts, linked_list_t *remote_ts, + mark_t mark_in, mark_t mark_out, + u_int32_t *reqid); + + /** + * Release a previously allocated reqid. + * + * @param reqid reqid to release + * @param mark_in inbound mark on SA + * @param mark_out outbound mark on SA + * @return SUCCESS if reqid released + */ + status_t (*release_reqid)(kernel_interface_t *this, u_int32_t reqid, + mark_t mark_in, mark_t mark_out); + + /** + * Add an SA to the SAD. + * + * This function does install a single SA for a single protocol in one + * direction. + * + * @param src source address for this SA + * @param dst destination address for this SA + * @param spi SPI allocated by us or remote peer + * @param protocol protocol for this SA (ESP/AH) + * @param reqid reqid for this SA + * @param mark optional mark for this SA + * @param tfc Traffic Flow Confidentiality padding for this SA + * @param lifetime lifetime_cfg_t for this SA + * @param enc_alg Algorithm to use for encryption (ESP only) + * @param enc_key key to use for encryption + * @param int_alg Algorithm to use for integrity protection + * @param int_key key to use for integrity protection + * @param mode mode of the SA (tunnel, transport) + * @param ipcomp IPComp transform to use + * @param cpi CPI for IPComp + * @param replay_window anti-replay window size + * @param initiator TRUE if initiator of the exchange creating this SA + * @param encap enable UDP encapsulation for NAT traversal + * @param esn TRUE to use Extended Sequence Numbers + * @param inbound TRUE if this is an inbound SA + * @param update TRUE if an SPI has already been allocated for SA + * @param src_ts list of source traffic selectors + * @param dst_ts list of destination traffic selectors + * @return SUCCESS if operation completed + */ + status_t (*add_sa) (kernel_interface_t *this, + host_t *src, host_t *dst, u_int32_t spi, + u_int8_t protocol, u_int32_t reqid, mark_t mark, + u_int32_t tfc, lifetime_cfg_t *lifetime, + u_int16_t enc_alg, chunk_t enc_key, + u_int16_t int_alg, chunk_t int_key, + ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, + u_int32_t replay_window, bool initiator, bool encap, + bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts); + + /** + * Update the hosts on an installed SA. + * + * We cannot directly update the destination address as the kernel + * requires the spi, the protocol AND the destination address (and family) + * to identify SAs. Therefore if the destination address changed we + * create a new SA and delete the old one. + * + * @param spi SPI of the SA + * @param protocol protocol for this SA (ESP/AH) + * @param cpi CPI for IPComp, 0 if no IPComp is used + * @param src current source address + * @param dst current destination address + * @param new_src new source address + * @param new_dst new destination address + * @param encap current use of UDP encapsulation + * @param new_encap new use of UDP encapsulation + * @param mark optional mark for this SA + * @return SUCCESS if operation completed, NOT_SUPPORTED if + * the kernel interface can't update the SA + */ + status_t (*update_sa)(kernel_interface_t *this, + u_int32_t spi, u_int8_t protocol, u_int16_t cpi, + host_t *src, host_t *dst, + host_t *new_src, host_t *new_dst, + bool encap, bool new_encap, mark_t mark); + + /** + * Query the number of bytes processed by an SA from the SAD. + * + * @param src source address for this SA + * @param dst destination address for this SA + * @param spi SPI allocated by us or remote peer + * @param protocol protocol for this SA (ESP/AH) + * @param mark optional mark for this SA + * @param[out] bytes the number of bytes processed by SA + * @param[out] packets number of packets processed by SA + * @param[out] time last (monotonic) time of SA use + * @return SUCCESS if operation completed + */ + status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, mark_t mark, + u_int64_t *bytes, u_int64_t *packets, time_t *time); + + /** + * Delete a previously installed SA from the SAD. + * + * @param src source address for this SA + * @param dst destination address for this SA + * @param spi SPI allocated by us or remote peer + * @param protocol protocol for this SA (ESP/AH) + * @param cpi CPI for IPComp or 0 + * @param mark optional mark for this SA + * @return SUCCESS if operation completed + */ + status_t (*del_sa) (kernel_interface_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, u_int16_t cpi, + mark_t mark); + + /** + * Flush all SAs from the SAD. + * + * @return SUCCESS if operation completed + */ + status_t (*flush_sas) (kernel_interface_t *this); + + /** + * Add a policy to the SPD. + * + * @param src source address of SA + * @param dst dest address of SA + * @param src_ts traffic selector to match traffic source + * @param dst_ts traffic selector to match traffic dest + * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param type type of policy, POLICY_(IPSEC|PASS|DROP) + * @param sa details about the SA(s) tied to this policy + * @param mark mark for this policy + * @param priority priority of this policy + * @return SUCCESS if operation completed + */ + status_t (*add_policy) (kernel_interface_t *this, + host_t *src, host_t *dst, + traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, + ipsec_sa_cfg_t *sa, mark_t mark, + policy_priority_t priority); + + /** + * Query the use time of a policy. + * + * The use time of a policy is the time the policy was used + * for the last time. + * + * @param src_ts traffic selector to match traffic source + * @param dst_ts traffic selector to match traffic dest + * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param mark optional mark + * @param[out] use_time the (monotonic) time of this SA's last use + * @return SUCCESS if operation completed + */ + status_t (*query_policy) (kernel_interface_t *this, + traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, + policy_dir_t direction, mark_t mark, + time_t *use_time); + + /** + * Remove a policy from the SPD. + * + * @param src source address of SA + * @param dst dest address of SA + * @param src_ts traffic selector to match traffic source + * @param dst_ts traffic selector to match traffic dest + * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param type type of policy, POLICY_(IPSEC|PASS|DROP) + * @param sa details about the SA(s) tied to this policy + * @param mark mark for this policy + * @param priority priority of the policy + * @return SUCCESS if operation completed + */ + status_t (*del_policy) (kernel_interface_t *this, + host_t *src, host_t *dst, + traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, + ipsec_sa_cfg_t *sa, mark_t mark, + policy_priority_t priority); + + /** + * Flush all policies from the SPD. + * + * @return SUCCESS if operation completed + */ + status_t (*flush_policies) (kernel_interface_t *this); + + /** + * Get our outgoing source address for a destination. + * + * Does a route lookup to get the source address used to reach dest. + * The returned host is allocated and must be destroyed. + * An optional src address can be used to check if a route is available + * for the given source to dest. + * + * @param dest target destination address + * @param src source address to check, or NULL + * @return outgoing source address, NULL if unreachable + */ + host_t* (*get_source_addr)(kernel_interface_t *this, + host_t *dest, host_t *src); + + /** + * Get the next hop for a destination. + * + * Does a route lookup to get the next hop used to reach dest. + * The returned host is allocated and must be destroyed. + * An optional src address can be used to check if a route is available + * for the given source to dest. + * + * @param dest target destination address + * @param prefix prefix length if dest is a subnet, -1 for auto + * @param src source address to check, or NULL + * @return next hop address, NULL if unreachable + */ + host_t* (*get_nexthop)(kernel_interface_t *this, host_t *dest, + int prefix, host_t *src); + + /** + * Get the interface name of a local address. Interfaces that are down or + * ignored by config are not considered. + * + * @param host address to get interface name from + * @param name allocated interface name (optional) + * @return TRUE if interface found and usable + */ + bool (*get_interface)(kernel_interface_t *this, host_t *host, char **name); + + /** + * Creates an enumerator over all local addresses. + * + * This function blocks an internal cached address list until the + * enumerator gets destroyed. + * The hosts are read-only, do not modify of free. + * + * @param which a combination of address types to enumerate + * @return enumerator over host_t's + */ + enumerator_t *(*create_address_enumerator) (kernel_interface_t *this, + kernel_address_type_t which); + + /** + * Add a virtual IP to an interface. + * + * Virtual IPs are attached to an interface. If an IP is added multiple + * times, the IP is refcounted and not removed until del_ip() was called + * as many times as add_ip(). + * + * @param virtual_ip virtual ip address to assign + * @param prefix prefix length to install IP with, -1 for auto + * @param iface interface to install virtual IP on + * @return SUCCESS if operation completed + */ + status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip, int prefix, + char *iface); + + /** + * Remove a virtual IP from an interface. + * + * The kernel interface uses refcounting, see add_ip(). + * + * @param virtual_ip virtual ip address to remove + * @param prefix prefix length of the IP to uninstall, -1 for auto + * @param wait TRUE to wait untily IP is gone + * @return SUCCESS if operation completed + */ + status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip, + int prefix, bool wait); + + /** + * Add a route. + * + * @param dst_net destination net + * @param prefixlen destination net prefix length + * @param gateway gateway for this route + * @param src_ip source ip of the route + * @param if_name name of the interface the route is bound to + * @return SUCCESS if operation completed + * ALREADY_DONE if the route already exists + */ + status_t (*add_route) (kernel_interface_t *this, chunk_t dst_net, + u_int8_t prefixlen, host_t *gateway, host_t *src_ip, + char *if_name); + + /** + * Delete a route. + * + * @param dst_net destination net + * @param prefixlen destination net prefix length + * @param gateway gateway for this route + * @param src_ip source ip of the route + * @param if_name name of the interface the route is bound to + * @return SUCCESS if operation completed + */ + status_t (*del_route) (kernel_interface_t *this, chunk_t dst_net, + u_int8_t prefixlen, host_t *gateway, host_t *src_ip, + char *if_name); + + /** + * Set up a bypass policy for a given socket. + * + * @param fd socket file descriptor to setup policy for + * @param family protocol family of the socket + * @return TRUE if policy set up successfully + */ + bool (*bypass_socket)(kernel_interface_t *this, int fd, int family); + + /** + * Enable decapsulation of ESP-in-UDP packets for the given port/socket. + * + * @param fd socket file descriptor + * @param family protocol family of the socket + * @param port the UDP port + * @return TRUE if UDP decapsulation was enabled successfully + */ + bool (*enable_udp_decap)(kernel_interface_t *this, int fd, int family, + u_int16_t port); + + + /** + * manager methods + */ + + /** + * Verifies that the given interface is usable and not excluded by + * configuration. + * + * @param iface interface name + * @return TRUE if usable + */ + bool (*is_interface_usable)(kernel_interface_t *this, const char *iface); + + /** + * Check if interfaces are excluded by config. + * + * @return TRUE if no interfaces are exclued by config + */ + bool (*all_interfaces_usable)(kernel_interface_t *this); + + /** + * Tries to find an IP address of a local interface that is included in the + * supplied traffic selector. + * + * @param ts traffic selector + * @param ip returned IP address (has to be destroyed) + * @param vip set to TRUE if returned address is a virtual IP + * @return SUCCESS if address found + */ + status_t (*get_address_by_ts)(kernel_interface_t *this, + traffic_selector_t *ts, host_t **ip, bool *vip); + + /** + * Register an ipsec kernel interface constructor on the manager. + * + * @param create constructor to register + * @return TRUE if the ipsec kernel interface was registered + * successfully, FALSE if an interface was already + * registered or the registration failed + */ + bool (*add_ipsec_interface)(kernel_interface_t *this, + kernel_ipsec_constructor_t create); + + /** + * Unregister an ipsec kernel interface constructor. + * + * @param create constructor to unregister + * @return TRUE if the ipsec kernel interface was unregistered + * successfully, FALSE otherwise + */ + bool (*remove_ipsec_interface)(kernel_interface_t *this, + kernel_ipsec_constructor_t create); + + /** + * Register a network kernel interface constructor on the manager. + * + * @param create constructor to register + * @return TRUE if the kernel net interface was registered + * successfully, FALSE if an interface was already + * registered or the registration failed + */ + bool (*add_net_interface)(kernel_interface_t *this, + kernel_net_constructor_t create); + + /** + * Unregister a network kernel interface constructor. + * + * @param create constructor to unregister + * @return TRUE if the kernel net interface was unregistered + * successfully, FALSE otherwise + */ + bool (*remove_net_interface)(kernel_interface_t *this, + kernel_net_constructor_t create); + + /** + * Add a listener to the kernel interface. + * + * @param listener listener to add + */ + void (*add_listener)(kernel_interface_t *this, + kernel_listener_t *listener); + + /** + * Remove a listener from the kernel interface. + * + * @param listener listener to remove + */ + void (*remove_listener)(kernel_interface_t *this, + kernel_listener_t *listener); + + /** + * Raise an acquire event. + * + * @param reqid reqid of the policy to acquire + * @param src_ts source traffic selector + * @param dst_ts destination traffic selector + */ + void (*acquire)(kernel_interface_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts); + + /** + * Raise an expire event. + * + * @param protocol protocol of the expired SA + * @param spi spi of the expired SA + * @param dst destination address of expired SA + * @param hard TRUE if it is a hard expire, FALSE otherwise + */ + void (*expire)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard); + + /** + * Raise a mapping event. + * + * @param protocol protocol of affected SA + * @param spi spi of the SA + * @param dst original destination address of SA + * @param remote new remote host + */ + void (*mapping)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, host_t *remote); + + /** + * Raise a migrate event. + * + * @param reqid reqid of the policy + * @param src_ts source traffic selector + * @param dst_ts destination traffic selector + * @param direction direction of the policy (in|out) + * @param local local host address to be used in the IKE_SA + * @param remote remote host address to be used in the IKE_SA + */ + void (*migrate)(kernel_interface_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, host_t *local, host_t *remote); + + /** + * Raise a roam event. + * + * @param address TRUE if address list, FALSE if routing changed + */ + void (*roam)(kernel_interface_t *this, bool address); + + /** + * Raise a tun event. + * + * @param tun TUN device + * @param created TRUE if created, FALSE if going to be destroyed + */ + void (*tun)(kernel_interface_t *this, tun_device_t *tun, bool created); + + /** + * Register a new algorithm with the kernel interface. + * + * @param alg_id the IKE id of the algorithm + * @param type the transform type of the algorithm + * @param kernel_id the kernel id of the algorithm + * @param kernel_name the kernel name of the algorithm + */ + void (*register_algorithm)(kernel_interface_t *this, u_int16_t alg_id, + transform_type_t type, u_int16_t kernel_id, + char *kernel_name); + + /** + * Return the kernel-specific id and/or name for an algorithms depending on + * the arguments specified. + * + * @param alg_id the IKE id of the algorithm + * @param type the transform type of the algorithm + * @param kernel_id the kernel id of the algorithm (optional) + * @param kernel_name the kernel name of the algorithm (optional) + * @return TRUE if algorithm was found + */ + bool (*lookup_algorithm)(kernel_interface_t *this, u_int16_t alg_id, + transform_type_t type, u_int16_t *kernel_id, + char **kernel_name); + + /** + * Destroys a kernel_interface_t object. + */ + void (*destroy) (kernel_interface_t *this); +}; + +/** + * Creates an object of type kernel_interface_t. + */ +kernel_interface_t *kernel_interface_create(void); + +#endif /** KERNEL_INTERFACE_H_ @}*/ diff --git a/src/libcharon/kernel/kernel_ipsec.c b/src/libcharon/kernel/kernel_ipsec.c new file mode 100644 index 000000000..0440f11bb --- /dev/null +++ b/src/libcharon/kernel/kernel_ipsec.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "kernel_ipsec.h" + +#include + +/** + * See header + */ +bool kernel_ipsec_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data) +{ + if (reg) + { + return charon->kernel->add_ipsec_interface(charon->kernel, + (kernel_ipsec_constructor_t)data); + } + else + { + return charon->kernel->remove_ipsec_interface(charon->kernel, + (kernel_ipsec_constructor_t)data); + } +} diff --git a/src/libcharon/kernel/kernel_ipsec.h b/src/libcharon/kernel/kernel_ipsec.h new file mode 100644 index 000000000..31e06308e --- /dev/null +++ b/src/libcharon/kernel/kernel_ipsec.h @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2006-2015 Tobias Brunner + * Copyright (C) 2006 Daniel Roethlisberger + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_ipsec kernel_ipsec + * @{ @ingroup kernel + */ + +#ifndef KERNEL_IPSEC_H_ +#define KERNEL_IPSEC_H_ + +typedef struct kernel_ipsec_t kernel_ipsec_t; + +#include +#include +#include +#include +#include + +/** + * Interface to the ipsec subsystem of the kernel. + * + * The kernel ipsec interface handles the communication with the kernel + * for SA and policy management. It allows setup of these, and provides + * further the handling of kernel events. + * Policy information are cached in the interface. This is necessary to do + * reference counting. The Linux kernel does not allow the same policy + * installed twice, but we need this as CHILD_SA exist multiple times + * when rekeying. Thats why we do reference counting of policies. + */ +struct kernel_ipsec_t { + + /** + * Get the feature set supported by this kernel backend. + * + * @return ORed feature-set of backend + */ + kernel_feature_t (*get_features)(kernel_ipsec_t *this); + + /** + * Get a SPI from the kernel. + * + * @param src source address of SA + * @param dst destination address of SA + * @param protocol protocol for SA (ESP/AH) + * @param spi allocated spi + * @return SUCCESS if operation completed + */ + status_t (*get_spi)(kernel_ipsec_t *this, host_t *src, host_t *dst, + u_int8_t protocol, u_int32_t *spi); + + /** + * Get a Compression Parameter Index (CPI) from the kernel. + * + * @param src source address of SA + * @param dst destination address of SA + * @param cpi allocated cpi + * @return SUCCESS if operation completed + */ + status_t (*get_cpi)(kernel_ipsec_t *this, host_t *src, host_t *dst, + u_int16_t *cpi); + + /** + * Add an SA to the SAD. + * + * This function does install a single SA for a single protocol in one + * direction. + * + * @param src source address for this SA + * @param dst destination address for this SA + * @param spi SPI allocated by us or remote peer + * @param protocol protocol for this SA (ESP/AH) + * @param reqid unique ID for this SA + * @param mark mark for this SA + * @param tfc Traffic Flow Confidentiality padding for this SA + * @param lifetime lifetime_cfg_t for this SA + * @param enc_alg Algorithm to use for encryption (ESP only) + * @param enc_key key to use for encryption + * @param int_alg Algorithm to use for integrity protection + * @param int_key key to use for integrity protection + * @param mode mode of the SA (tunnel, transport) + * @param ipcomp IPComp transform to use + * @param cpi CPI for IPComp + * @param replay_window anti-replay window size + * @param initiator TRUE if initiator of the exchange creating this SA + * @param encap enable UDP encapsulation for NAT traversal + * @param esn TRUE to use Extended Sequence Numbers + * @param inbound TRUE if this is an inbound SA + * @param update TRUE if an SPI has already been allocated for SA + * @param src_ts list of source traffic selectors + * @param dst_ts list of destination traffic selectors + * @return SUCCESS if operation completed + */ + status_t (*add_sa) (kernel_ipsec_t *this, + host_t *src, host_t *dst, u_int32_t spi, + u_int8_t protocol, u_int32_t reqid, + mark_t mark, u_int32_t tfc, lifetime_cfg_t *lifetime, + u_int16_t enc_alg, chunk_t enc_key, + u_int16_t int_alg, chunk_t int_key, + ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, + u_int32_t replay_window, bool initiator, bool encap, + bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts); + + /** + * Update the hosts on an installed SA. + * + * We cannot directly update the destination address as the kernel + * requires the spi, the protocol AND the destination address (and family) + * to identify SAs. Therefore if the destination address changed we + * create a new SA and delete the old one. + * + * @param spi SPI of the SA + * @param protocol protocol for this SA (ESP/AH) + * @param cpi CPI for IPComp, 0 if no IPComp is used + * @param src current source address + * @param dst current destination address + * @param new_src new source address + * @param new_dst new destination address + * @param encap current use of UDP encapsulation + * @param new_encap new use of UDP encapsulation + * @param mark optional mark for this SA + * @return SUCCESS if operation completed, NOT_SUPPORTED if + * the kernel interface can't update the SA + */ + status_t (*update_sa)(kernel_ipsec_t *this, + u_int32_t spi, u_int8_t protocol, u_int16_t cpi, + host_t *src, host_t *dst, + host_t *new_src, host_t *new_dst, + bool encap, bool new_encap, mark_t mark); + + /** + * Query the number of bytes processed by an SA from the SAD. + * + * @param src source address for this SA + * @param dst destination address for this SA + * @param spi SPI allocated by us or remote peer + * @param protocol protocol for this SA (ESP/AH) + * @param mark optional mark for this SA + * @param[out] bytes the number of bytes processed by SA + * @param[out] packets number of packets processed by SA + * @param[out] time last (monotonic) time of SA use + * @return SUCCESS if operation completed + */ + status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, mark_t mark, + u_int64_t *bytes, u_int64_t *packets, time_t *time); + + /** + * Delete a previusly installed SA from the SAD. + * + * @param src source address for this SA + * @param dst destination address for this SA + * @param spi SPI allocated by us or remote peer + * @param protocol protocol for this SA (ESP/AH) + * @param cpi CPI for IPComp or 0 + * @param mark optional mark for this SA + * @return SUCCESS if operation completed + */ + status_t (*del_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, u_int16_t cpi, + mark_t mark); + + /** + * Flush all SAs from the SAD. + * + * @return SUCCESS if operation completed + */ + status_t (*flush_sas) (kernel_ipsec_t *this); + + /** + * Add a policy to the SPD. + * + * @param src source address of SA + * @param dst dest address of SA + * @param src_ts traffic selector to match traffic source + * @param dst_ts traffic selector to match traffic dest + * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param type type of policy, POLICY_(IPSEC|PASS|DROP) + * @param sa details about the SA(s) tied to this policy + * @param mark mark for this policy + * @param priority priority of this policy + * @return SUCCESS if operation completed + */ + status_t (*add_policy) (kernel_ipsec_t *this, + host_t *src, host_t *dst, + traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, + ipsec_sa_cfg_t *sa, mark_t mark, + policy_priority_t priority); + + /** + * Query the use time of a policy. + * + * The use time of a policy is the time the policy was used for the last + * time. It is not the system time, but a monotonic timestamp as returned + * by time_monotonic. + * + * @param src_ts traffic selector to match traffic source + * @param dst_ts traffic selector to match traffic dest + * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param mark optional mark + * @param[out] use_time the monotonic timestamp of this SA's last use + * @return SUCCESS if operation completed + */ + status_t (*query_policy) (kernel_ipsec_t *this, + traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, + policy_dir_t direction, mark_t mark, + time_t *use_time); + + /** + * Remove a policy from the SPD. + * + * @param src source address of SA + * @param dst dest address of SA + * @param src_ts traffic selector to match traffic source + * @param dst_ts traffic selector to match traffic dest + * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param type type of policy, POLICY_(IPSEC|PASS|DROP) + * @param sa details about the SA(s) tied to this policy + * @param mark mark for this policy + * @param priority priority of the policy + * @return SUCCESS if operation completed + */ + status_t (*del_policy) (kernel_ipsec_t *this, + host_t *src, host_t *dst, + traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, + ipsec_sa_cfg_t *sa, mark_t mark, + policy_priority_t priority); + + /** + * Flush all policies from the SPD. + * + * @return SUCCESS if operation completed + */ + status_t (*flush_policies) (kernel_ipsec_t *this); + + /** + * Install a bypass policy for the given socket. + * + * @param fd socket file descriptor to setup policy for + * @param family protocol family of the socket + * @return TRUE of policy set up successfully + */ + bool (*bypass_socket)(kernel_ipsec_t *this, int fd, int family); + + /** + * Enable decapsulation of ESP-in-UDP packets for the given port/socket. + * + * @param fd socket file descriptor + * @param family protocol family of the socket + * @param port the UDP port + * @return TRUE if UDP decapsulation was enabled successfully + */ + bool (*enable_udp_decap)(kernel_ipsec_t *this, int fd, int family, + u_int16_t port); + + /** + * Destroy the implementation. + */ + void (*destroy) (kernel_ipsec_t *this); +}; + +/** + * Helper function to (un-)register IPsec kernel interfaces from plugin features. + * + * This function is a plugin_feature_callback_t and can be used with the + * PLUGIN_CALLBACK macro to register an IPsec kernel interface constructor. + * + * @param plugin plugin registering the kernel interface + * @param feature associated plugin feature + * @param reg TRUE to register, FALSE to unregister + * @param data data passed to callback, an kernel_ipsec_constructor_t + */ +bool kernel_ipsec_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data); + +#endif /** KERNEL_IPSEC_H_ @}*/ diff --git a/src/libcharon/kernel/kernel_listener.h b/src/libcharon/kernel/kernel_listener.h new file mode 100644 index 000000000..6426fae2a --- /dev/null +++ b/src/libcharon/kernel/kernel_listener.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2010-2013 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 kernel_listener kernel_listener + * @{ @ingroup kernel + */ + +#ifndef KERNEL_LISTENER_H_ +#define KERNEL_LISTENER_H_ + +typedef struct kernel_listener_t kernel_listener_t; + +#include +#include +#include +#include + +/** + * Interface for components interested in kernel events. + * + * All hooks are optional. + */ +struct kernel_listener_t { + + /** + * Hook called if an acquire event for a policy is received. + * + * @param reqid reqid of the policy to acquire + * @param src_ts source traffic selector + * @param dst_ts destination traffic selector + * @return TRUE to remain registered, FALSE to unregister + */ + bool (*acquire)(kernel_listener_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts); + + /** + * Hook called if an exire event for an IPsec SA is received. + * + * @param protocol protocol of the expired SA + * @param spi spi of the expired SA + * @param dst destination address of expired SA + * @param hard TRUE if it is a hard expire, FALSE otherwise + * @return TRUE to remain registered, FALSE to unregister + */ + bool (*expire)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard); + + /** + * Hook called if the NAT mappings of an IPsec SA changed. + * + * @param protocol IPsec protocol of affected SA + * @param spi spi of the SA + * @param dst old destinatino address of SA + * @param remote new remote host + * @return TRUE to remain registered, FALSE to unregister + */ + bool (*mapping)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, host_t *remote); + + /** + * Hook called if a migrate event for a policy is received. + * + * @param reqid reqid of the policy + * @param src_ts source traffic selector + * @param dst_ts destination traffic selector + * @param direction direction of the policy (in|out) + * @param local local host address to be used in the IKE_SA + * @param remote remote host address to be used in the IKE_SA + * @return TRUE to remain registered, FALSE to unregister + */ + bool (*migrate)(kernel_listener_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, host_t *local, host_t *remote); + + /** + * Hook called if changes in the networking layer occurred (interfaces + * up/down, routes added/deleted etc.). + * + * @param address TRUE if address list, FALSE if routing changed + * @return TRUE to remain registered, FALSE to unregister + */ + bool (*roam)(kernel_listener_t *this, bool address); + + /** + * Hook called after a TUN device was created for a virtual IP address, or + * before such a device gets destroyed. + * + * @param tun TUN device + * @param created TRUE if created, FALSE if going to be destroyed + */ + bool (*tun)(kernel_listener_t *this, tun_device_t *tun, bool created); +}; + +#endif /** KERNEL_LISTENER_H_ @}*/ diff --git a/src/libcharon/kernel/kernel_net.c b/src/libcharon/kernel/kernel_net.c new file mode 100644 index 000000000..f169cad14 --- /dev/null +++ b/src/libcharon/kernel/kernel_net.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "kernel_net.h" + +#include + +/** + * See header + */ +bool kernel_net_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data) +{ + if (reg) + { + return charon->kernel->add_net_interface(charon->kernel, + (kernel_net_constructor_t)data); + } + else + { + return charon->kernel->remove_net_interface(charon->kernel, + (kernel_net_constructor_t)data); + } +} diff --git a/src/libcharon/kernel/kernel_net.h b/src/libcharon/kernel/kernel_net.h new file mode 100644 index 000000000..7fc644a7e --- /dev/null +++ b/src/libcharon/kernel/kernel_net.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2008-2012 Tobias Brunner + * Copyright (C) 2007 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_net kernel_net + * @{ @ingroup kernel + */ + +#ifndef KERNEL_NET_H_ +#define KERNEL_NET_H_ + +typedef struct kernel_net_t kernel_net_t; +typedef enum kernel_address_type_t kernel_address_type_t; + +#include +#include +#include +#include + +/** + * Type of addresses (e.g. when enumerating them) + */ +enum kernel_address_type_t { + /** normal addresses (on regular, up, non-ignored) interfaces */ + ADDR_TYPE_REGULAR = (1 << 0), + /** addresses on down interfaces */ + ADDR_TYPE_DOWN = (1 << 1), + /** addresses on ignored interfaces */ + ADDR_TYPE_IGNORED = (1 << 2), + /** addresses on loopback interfaces */ + ADDR_TYPE_LOOPBACK = (1 << 3), + /** virtual IP addresses */ + ADDR_TYPE_VIRTUAL = (1 << 4), + /** to enumerate all available addresses */ + ADDR_TYPE_ALL = (1 << 5) - 1, +}; + +/** + * Interface to the network subsystem of the kernel. + * + * The kernel network interface handles the communication with the kernel + * for interface and IP address management. + */ +struct kernel_net_t { + + /** + * Get the feature set supported by this kernel backend. + * + * @return ORed feature-set of backend + */ + kernel_feature_t (*get_features)(kernel_net_t *this); + + /** + * Get our outgoing source address for a destination. + * + * Does a route lookup to get the source address used to reach dest. + * The returned host is allocated and must be destroyed. + * An optional src address can be used to check if a route is available + * for the given source to dest. + * + * @param dest target destination address + * @param src source address to check, or NULL + * @return outgoing source address, NULL if unreachable + */ + host_t* (*get_source_addr)(kernel_net_t *this, host_t *dest, host_t *src); + + /** + * Get the next hop for a destination. + * + * Does a route lookup to get the next hop used to reach dest. + * The returned host is allocated and must be destroyed. + * An optional src address can be used to check if a route is available + * for the given source to dest. + * + * @param dest target destination address + * @param prefix prefix length if dest is a subnet, -1 for auto + * @param src source address to check, or NULL + * @return next hop address, NULL if unreachable + */ + host_t* (*get_nexthop)(kernel_net_t *this, host_t *dest, int prefix, + host_t *src); + + /** + * Get the interface name of a local address. Interfaces that are down or + * ignored by config are not considered. + * + * @param host address to get interface name from + * @param name allocated interface name (optional) + * @return TRUE if interface found and usable + */ + bool (*get_interface) (kernel_net_t *this, host_t *host, char **name); + + /** + * Creates an enumerator over all local addresses. + * + * This function blocks an internal cached address list until the + * enumerator gets destroyed. + * The hosts are read-only, do not modify of free. + * + * @param which a combination of address types to enumerate + * @return enumerator over host_t's + */ + enumerator_t *(*create_address_enumerator) (kernel_net_t *this, + kernel_address_type_t which); + + /** + * Add a virtual IP to an interface. + * + * Virtual IPs are attached to an interface. If an IP is added multiple + * times, the IP is refcounted and not removed until del_ip() was called + * as many times as add_ip(). + * + * @param virtual_ip virtual ip address to assign + * @param prefix prefix length to install with IP address, -1 for auto + * @param iface interface to install virtual IP on + * @return SUCCESS if operation completed + */ + status_t (*add_ip) (kernel_net_t *this, host_t *virtual_ip, int prefix, + char *iface); + + /** + * Remove a virtual IP from an interface. + * + * The kernel interface uses refcounting, see add_ip(). + * + * @param virtual_ip virtual ip address to remove + * @param prefix prefix length of the IP to uninstall, -1 for auto + * @param wait TRUE to wait until IP is gone + * @return SUCCESS if operation completed + */ + status_t (*del_ip) (kernel_net_t *this, host_t *virtual_ip, int prefix, + bool wait); + + /** + * Add a route. + * + * @param dst_net destination net + * @param prefixlen destination net prefix length + * @param gateway gateway for this route + * @param src_ip source ip of the route + * @param if_name name of the interface the route is bound to + * @return SUCCESS if operation completed + * ALREADY_DONE if the route already exists + */ + status_t (*add_route) (kernel_net_t *this, chunk_t dst_net, + u_int8_t prefixlen, host_t *gateway, host_t *src_ip, + char *if_name); + + /** + * Delete a route. + * + * @param dst_net destination net + * @param prefixlen destination net prefix length + * @param gateway gateway for this route + * @param src_ip source ip of the route + * @param if_name name of the interface the route is bound to + * @return SUCCESS if operation completed + */ + status_t (*del_route) (kernel_net_t *this, chunk_t dst_net, + u_int8_t prefixlen, host_t *gateway, host_t *src_ip, + char *if_name); + + /** + * Destroy the implementation. + */ + void (*destroy) (kernel_net_t *this); +}; + +/** + * Helper function to (un-)register net kernel interfaces from plugin features. + * + * This function is a plugin_feature_callback_t and can be used with the + * PLUGIN_CALLBACK macro to register an net kernel interface constructor. + * + * @param plugin plugin registering the kernel interface + * @param feature associated plugin feature + * @param reg TRUE to register, FALSE to unregister + * @param data data passed to callback, an kernel_net_constructor_t + */ +bool kernel_net_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data); + +#endif /** KERNEL_NET_H_ @}*/ diff --git a/src/libcharon/network/receiver.c b/src/libcharon/network/receiver.c index a2f2016ff..ee357ca4d 100644 --- a/src/libcharon/network/receiver.c +++ b/src/libcharon/network/receiver.c @@ -20,7 +20,6 @@ #include "receiver.h" -#include #include #include #include @@ -451,9 +450,8 @@ static job_requeue_t receive_packets(private_receiver_t *this) dst = packet->get_destination(packet); src = packet->get_source(packet); - if (!hydra->kernel_interface->all_interfaces_usable(hydra->kernel_interface) - && !hydra->kernel_interface->get_interface(hydra->kernel_interface, - dst, NULL)) + if (!charon->kernel->all_interfaces_usable(charon->kernel) + && !charon->kernel->get_interface(charon->kernel, dst, NULL)) { DBG3(DBG_NET, "received packet from %#H to %#H on ignored interface", src, dst); diff --git a/src/libcharon/plugins/addrblock/Makefile.am b/src/libcharon/plugins/addrblock/Makefile.am index 33ee60d86..ddb2706c8 100644 --- a/src/libcharon/plugins/addrblock/Makefile.am +++ b/src/libcharon/plugins/addrblock/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in index 0554465b9..b4ae6fa3e 100644 --- a/src/libcharon/plugins/addrblock/Makefile.in +++ b/src/libcharon/plugins/addrblock/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/android_dns/Makefile.am b/src/libcharon/plugins/android_dns/Makefile.am index 1a0d6e6f2..e606a832c 100644 --- a/src/libcharon/plugins/android_dns/Makefile.am +++ b/src/libcharon/plugins/android_dns/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/android_dns/Makefile.in b/src/libcharon/plugins/android_dns/Makefile.in index 58cf97b6e..d90149827 100644 --- a/src/libcharon/plugins/android_dns/Makefile.in +++ b/src/libcharon/plugins/android_dns/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/android_log/Makefile.am b/src/libcharon/plugins/android_log/Makefile.am index 79c61b51e..9f82f6e60 100644 --- a/src/libcharon/plugins/android_log/Makefile.am +++ b/src/libcharon/plugins/android_log/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/android_log/Makefile.in b/src/libcharon/plugins/android_log/Makefile.in index 8ce92e577..64fecd9e3 100644 --- a/src/libcharon/plugins/android_log/Makefile.in +++ b/src/libcharon/plugins/android_log/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/attr/Makefile.am b/src/libcharon/plugins/attr/Makefile.am index 6bc7e77d8..ecbb76d1a 100644 --- a/src/libcharon/plugins/attr/Makefile.am +++ b/src/libcharon/plugins/attr/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/attr/Makefile.in b/src/libcharon/plugins/attr/Makefile.in index 486b3c0b0..acb7d07c0 100644 --- a/src/libcharon/plugins/attr/Makefile.in +++ b/src/libcharon/plugins/attr/Makefile.in @@ -413,6 +413,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -428,7 +430,6 @@ 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 = \ diff --git a/src/libcharon/plugins/attr/attr_provider.c b/src/libcharon/plugins/attr/attr_provider.c index cac0ae4bf..1de571c3f 100644 --- a/src/libcharon/plugins/attr/attr_provider.c +++ b/src/libcharon/plugins/attr/attr_provider.c @@ -54,6 +54,8 @@ struct attribute_entry_t { configuration_attribute_type_t type; /** attribute value */ chunk_t value; + /** associated IKE version */ + ike_version_t ike; }; /** @@ -65,27 +67,52 @@ static void attribute_destroy(attribute_entry_t *this) free(this); } +/** + * Data for attribute enumerator + */ +typedef struct { + rwlock_t *lock; + ike_version_t ike; +} enumerator_data_t; + /** * convert enumerator value from attribute_entry */ -static bool attr_enum_filter(void *null, attribute_entry_t **in, +static bool attr_enum_filter(enumerator_data_t *data, attribute_entry_t **in, configuration_attribute_type_t *type, void* none, chunk_t *value) { - *type = (*in)->type; - *value = (*in)->value; - return TRUE; + if ((*in)->ike == IKE_ANY || (*in)->ike == data->ike) + { + *type = (*in)->type; + *value = (*in)->value; + return TRUE; + } + return FALSE; +} + +CALLBACK(attr_enum_destroy, void, + enumerator_data_t *data) +{ + data->lock->unlock(data->lock); + free(data); } METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_attr_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa, linked_list_t *vips) { + enumerator_data_t *data; + if (vips->get_count(vips)) { + INIT(data, + .lock = this->lock, + .ike = ike_sa->get_version(ike_sa), + ); this->lock->read_lock(this->lock); return enumerator_create_filter( this->attributes->create_enumerator(this->attributes), - (void*)attr_enum_filter, this->lock, (void*)this->lock->unlock); + (void*)attr_enum_filter, data, attr_enum_destroy); } return enumerator_create_empty(); } @@ -116,8 +143,6 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr, host = host_create_from_string(str, 0); if (host) { - entry = malloc_thing(attribute_entry_t); - if (host->get_family(host) == AF_INET6) { switch (type) @@ -132,8 +157,11 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr, break; } } - entry->type = type; - entry->value = chunk_clone(host->get_address(host)); + INIT(entry, + .type = type, + .value = chunk_clone(host->get_address(host)), + .ike = IKE_ANY, + ); host->destroy(host); DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B", configuration_attribute_type_names, entry->type, &entry->value); @@ -149,18 +177,20 @@ typedef struct { char *name; configuration_attribute_type_t v4; configuration_attribute_type_t v6; + ike_version_t ike; } attribute_type_key_t; static attribute_type_key_t keys[] = { - {"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS}, - {"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS}, - {"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS}, - {"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP}, - {"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK}, - {"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER}, - {"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET}, - {"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE}, - {"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN}, + {"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS, IKE_ANY}, + {"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS, IKE_ANY}, + {"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS, IKE_ANY}, + {"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP, IKE_ANY}, + {"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK, IKE_ANY}, + {"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, IKE_ANY}, + {"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET, IKE_ANY}, + {"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS, IKEV2}, + {"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE, IKEV1}, + {"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN, IKEV1}, }; /** @@ -275,6 +305,7 @@ static void load_entries(private_attr_provider_t *this) INIT(entry, .type = type, .value = data, + .ike = mapped ? mapped->ike : IKE_ANY, ); DBG2(DBG_CFG, "loaded attribute %N: %#B", configuration_attribute_type_names, entry->type, &entry->value); diff --git a/src/libcharon/plugins/attr_sql/Makefile.am b/src/libcharon/plugins/attr_sql/Makefile.am index 366c902f7..e65ef36a1 100644 --- a/src/libcharon/plugins/attr_sql/Makefile.am +++ b/src/libcharon/plugins/attr_sql/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/attr_sql/Makefile.in b/src/libcharon/plugins/attr_sql/Makefile.in index 8f1b3c0ff..8ee9f3f92 100644 --- a/src/libcharon/plugins/attr_sql/Makefile.in +++ b/src/libcharon/plugins/attr_sql/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/certexpire/Makefile.am b/src/libcharon/plugins/certexpire/Makefile.am index b8c241dfb..d2d38efea 100644 --- a/src/libcharon/plugins/certexpire/Makefile.am +++ b/src/libcharon/plugins/certexpire/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in index f946d73c1..be19d615e 100644 --- a/src/libcharon/plugins/certexpire/Makefile.in +++ b/src/libcharon/plugins/certexpire/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/connmark/Makefile.am b/src/libcharon/plugins/connmark/Makefile.am index cc4d0ec8d..561efa0af 100644 --- a/src/libcharon/plugins/connmark/Makefile.am +++ b/src/libcharon/plugins/connmark/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/connmark/Makefile.in b/src/libcharon/plugins/connmark/Makefile.in index 65f53fde9..eaf4f1ec9 100644 --- a/src/libcharon/plugins/connmark/Makefile.in +++ b/src/libcharon/plugins/connmark/Makefile.in @@ -417,6 +417,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ 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 = \ diff --git a/src/libcharon/plugins/connmark/connmark_listener.c b/src/libcharon/plugins/connmark/connmark_listener.c index 23df690e8..607316f7b 100644 --- a/src/libcharon/plugins/connmark/connmark_listener.c +++ b/src/libcharon/plugins/connmark/connmark_listener.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * @@ -25,6 +28,14 @@ #include #include +/** + * Add a struct at the current position in the buffer + */ +#define ADD_STRUCT(pos, st, ...) ({\ + typeof(pos) _cur = pos; pos += XT_ALIGN(sizeof(st));\ + *(st*)_cur = (st){ __VA_ARGS__ };\ + (st*)_cur;\ +}) typedef struct private_connmark_listener_t private_connmark_listener_t; @@ -90,7 +101,10 @@ static bool manage_rule(struct iptc_handle *ipth, const char *chain, } else { - if (!iptc_delete_entry(chain, e, "", ipth)) + u_char matchmask[e->next_offset]; + + memset(matchmask, 255, sizeof(matchmask)); + if (!iptc_delete_entry(chain, e, matchmask, ipth)) { DBG1(DBG_CFG, "deleting %s rule failed: %s", chain, iptc_strerror(errno)); @@ -108,54 +122,54 @@ static bool manage_pre_esp_in_udp(private_connmark_listener_t *this, u_int mark, u_int32_t spi, host_t *dst, host_t *src) { - struct { - struct ipt_entry e; - struct ipt_entry_match m; - struct xt_udp udp; - struct ipt_entry_target t; - struct xt_mark_tginfo2 tm; - } ipt = { - .e = { - .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + - sizeof(ipt.udp)), - .next_offset = sizeof(ipt), - .ip = { - .proto = IPPROTO_UDP, - }, + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + + XT_ALIGN(sizeof(struct xt_udp)); + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + + XT_ALIGN(sizeof(struct xt_mark_tginfo2)); + u_int16_t entry_size = target_offset + target_size; + u_char ipt[entry_size], *pos = ipt; + struct ipt_entry *e; + + memset(ipt, 0, sizeof(ipt)); + e = ADD_STRUCT(pos, struct ipt_entry, + .target_offset = target_offset, + .next_offset = entry_size, + .ip = { + .proto = IPPROTO_UDP, }, - .m = { - .u = { - .user = { - .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)), - .name = "udp", - }, + ); + if (!host2in(dst, &e->ip.dst, &e->ip.dmsk) || + !host2in(src, &e->ip.src, &e->ip.smsk)) + { + return FALSE; + } + ADD_STRUCT(pos, struct ipt_entry_match, + .u = { + .user = { + .match_size = match_size, + .name = "udp", }, }, - .udp = { - .spts = { src->get_port(src), src->get_port(src) }, - .dpts = { dst->get_port(dst), dst->get_port(dst) }, - }, - .t = { - .u = { - .user = { - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), - .name = "MARK", - .revision = 2, - }, + ); + ADD_STRUCT(pos, struct xt_udp, + .spts = { src->get_port(src), src->get_port(src) }, + .dpts = { dst->get_port(dst), dst->get_port(dst) }, + ); + ADD_STRUCT(pos, struct ipt_entry_target, + .u = { + .user = { + .target_size = target_size, + .name = "MARK", + .revision = 2, }, }, - .tm = { - .mark = mark, - .mask = ~0, - }, - }; - - if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || - !host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) - { - return FALSE; - } - return manage_rule(ipth, "PREROUTING", add, &ipt.e); + ); + ADD_STRUCT(pos, struct xt_mark_tginfo2, + .mark = mark, + .mask = ~0, + ); + return manage_rule(ipth, "PREROUTING", add, e); } /** @@ -166,53 +180,53 @@ static bool manage_pre_esp(private_connmark_listener_t *this, u_int mark, u_int32_t spi, host_t *dst, host_t *src) { - struct { - struct ipt_entry e; - struct ipt_entry_match m; - struct xt_esp esp; - struct ipt_entry_target t; - struct xt_mark_tginfo2 tm; - } ipt = { - .e = { - .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + - sizeof(ipt.esp)), - .next_offset = sizeof(ipt), - .ip = { - .proto = IPPROTO_ESP, - }, + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + + XT_ALIGN(sizeof(struct xt_esp)); + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + + XT_ALIGN(sizeof(struct xt_mark_tginfo2)); + u_int16_t entry_size = target_offset + target_size; + u_char ipt[entry_size], *pos = ipt; + struct ipt_entry *e; + + memset(ipt, 0, sizeof(ipt)); + e = ADD_STRUCT(pos, struct ipt_entry, + .target_offset = target_offset, + .next_offset = entry_size, + .ip = { + .proto = IPPROTO_ESP, }, - .m = { - .u = { - .user = { - .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)), - .name = "esp", - }, + ); + if (!host2in(dst, &e->ip.dst, &e->ip.dmsk) || + !host2in(src, &e->ip.src, &e->ip.smsk)) + { + return FALSE; + } + ADD_STRUCT(pos, struct ipt_entry_match, + .u = { + .user = { + .match_size = match_size, + .name = "esp", }, }, - .esp = { - .spis = { htonl(spi), htonl(spi) }, - }, - .t = { - .u = { - .user = { - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), - .name = "MARK", - .revision = 2, - }, + ); + ADD_STRUCT(pos, struct xt_esp, + .spis = { htonl(spi), htonl(spi) }, + ); + ADD_STRUCT(pos, struct ipt_entry_target, + .u = { + .user = { + .target_size = target_size, + .name = "MARK", + .revision = 2, }, }, - .tm = { - .mark = mark, - .mask = ~0, - }, - }; - - if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || - !host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) - { - return FALSE; - } - return manage_rule(ipth, "PREROUTING", add, &ipt.e); + ); + ADD_STRUCT(pos, struct xt_mark_tginfo2, + .mark = mark, + .mask = ~0, + ); + return manage_rule(ipth, "PREROUTING", add, e); } /** @@ -238,99 +252,115 @@ static bool manage_in(private_connmark_listener_t *this, u_int mark, u_int32_t spi, traffic_selector_t *dst, traffic_selector_t *src) { - struct { - struct ipt_entry e; - struct ipt_entry_match m; - struct xt_policy_info p; - struct ipt_entry_target t; - struct xt_connmark_tginfo1 cm; - } ipt = { - .e = { - .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + - sizeof(ipt.p)), - .next_offset = sizeof(ipt), - }, - .m = { - .u = { - .user = { - .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.p)), - .name = "policy", - }, + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + + XT_ALIGN(sizeof(struct xt_policy_info)); + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + + XT_ALIGN(sizeof(struct xt_connmark_tginfo1)); + u_int16_t entry_size = target_offset + target_size; + u_char ipt[entry_size], *pos = ipt; + struct ipt_entry *e; + + memset(ipt, 0, sizeof(ipt)); + e = ADD_STRUCT(pos, struct ipt_entry, + .target_offset = target_offset, + .next_offset = entry_size, + ); + if (!ts2in(dst, &e->ip.dst, &e->ip.dmsk) || + !ts2in(src, &e->ip.src, &e->ip.smsk)) + { + return FALSE; + } + ADD_STRUCT(pos, struct ipt_entry_match, + .u = { + .user = { + .match_size = match_size, + .name = "policy", }, }, - .p = { - .pol = { - { - .spi = spi, - .match.spi = 1, - }, + ); + ADD_STRUCT(pos, struct xt_policy_info, + .pol = { + { + .spi = spi, + .match.spi = 1, }, - .len = 1, - .flags = XT_POLICY_MATCH_IN, }, - .t = { - .u = { - .user = { - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)), - .name = "CONNMARK", - .revision = 1, - }, + .len = 1, + .flags = XT_POLICY_MATCH_IN, + ); + ADD_STRUCT(pos, struct ipt_entry_target, + .u = { + .user = { + .target_size = target_size, + .name = "CONNMARK", + .revision = 1, }, }, - .cm = { - .ctmark = mark, - .ctmask = ~0, - .nfmask = ~0, - .mode = XT_CONNMARK_SET, - }, - }; - - if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || - !ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) - { - return FALSE; - } - return manage_rule(ipth, "INPUT", add, &ipt.e); + ); + ADD_STRUCT(pos, struct xt_connmark_tginfo1, + .ctmark = mark, + .ctmask = ~0, + .nfmask = ~0, + .mode = XT_CONNMARK_SET, + ); + return manage_rule(ipth, "INPUT", add, e); } /** - * Add outbund rule restoring CONNMARK on matching traffic + * Add outbund rule restoring CONNMARK on matching traffic unless the packet + * already has a mark set */ static bool manage_out(private_connmark_listener_t *this, struct iptc_handle *ipth, bool add, traffic_selector_t *dst, traffic_selector_t *src) { - struct { - struct ipt_entry e; - struct ipt_entry_target t; - struct xt_connmark_tginfo1 cm; - } ipt = { - .e = { - .target_offset = XT_ALIGN(sizeof(ipt.e)), - .next_offset = sizeof(ipt), - }, - .t = { - .u = { - .user = { - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)), - .name = "CONNMARK", - .revision = 1, - }, - }, - }, - .cm = { - .ctmask = ~0, - .nfmask = ~0, - .mode = XT_CONNMARK_RESTORE, - }, - }; - - if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || - !ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + + XT_ALIGN(sizeof(struct xt_mark_mtinfo1)); + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + + XT_ALIGN(sizeof(struct xt_connmark_tginfo1)); + u_int16_t entry_size = target_offset + target_size; + u_char ipt[entry_size], *pos = ipt; + struct ipt_entry *e; + + memset(ipt, 0, sizeof(ipt)); + e = ADD_STRUCT(pos, struct ipt_entry, + .target_offset = target_offset, + .next_offset = entry_size, + ); + if (!ts2in(dst, &e->ip.dst, &e->ip.dmsk) || + !ts2in(src, &e->ip.src, &e->ip.smsk)) { return FALSE; } - return manage_rule(ipth, "OUTPUT", add, &ipt.e); + ADD_STRUCT(pos, struct ipt_entry_match, + .u = { + .user = { + .match_size = match_size, + .name = "mark", + .revision = 1, + }, + }, + ); + ADD_STRUCT(pos, struct xt_mark_mtinfo1, + .mask = ~0, + ); + ADD_STRUCT(pos, struct ipt_entry_target, + .u = { + .user = { + .target_size = target_size, + .name = "CONNMARK", + .revision = 1, + }, + }, + ); + ADD_STRUCT(pos, struct xt_connmark_tginfo1, + .ctmask = ~0, + .nfmask = ~0, + .mode = XT_CONNMARK_RESTORE, + ); + return manage_rule(ipth, "OUTPUT", add, e); } /** diff --git a/src/libcharon/plugins/coupling/Makefile.am b/src/libcharon/plugins/coupling/Makefile.am index badc7b7b2..62695aabe 100644 --- a/src/libcharon/plugins/coupling/Makefile.am +++ b/src/libcharon/plugins/coupling/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in index dff80c37f..44598c3ea 100644 --- a/src/libcharon/plugins/coupling/Makefile.in +++ b/src/libcharon/plugins/coupling/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/dhcp/Makefile.am b/src/libcharon/plugins/dhcp/Makefile.am index 3c09db016..9ae68be35 100644 --- a/src/libcharon/plugins/dhcp/Makefile.am +++ b/src/libcharon/plugins/dhcp/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in index 1e84f04e2..3d39fda29 100644 --- a/src/libcharon/plugins/dhcp/Makefile.in +++ b/src/libcharon/plugins/dhcp/Makefile.in @@ -414,6 +414,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -429,7 +431,6 @@ 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 = \ diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c index b8c1b4059..0fd1d33fd 100644 --- a/src/libcharon/plugins/dhcp/dhcp_socket.c +++ b/src/libcharon/plugins/dhcp/dhcp_socket.c @@ -31,7 +31,6 @@ #include #include -#include #include #include @@ -209,8 +208,7 @@ static int prepare_dhcp(private_dhcp_socket_t *this, else { /* act as relay agent */ - src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, - this->dst, NULL); + src = charon->kernel->get_source_addr(charon->kernel, this->dst, NULL); if (src) { memcpy(&dhcp->gateway_address, src->get_address(src).ptr, diff --git a/src/libcharon/plugins/dnscert/Makefile.am b/src/libcharon/plugins/dnscert/Makefile.am index 145562522..8181bfc9e 100644 --- a/src/libcharon/plugins/dnscert/Makefile.am +++ b/src/libcharon/plugins/dnscert/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/dnscert/Makefile.in b/src/libcharon/plugins/dnscert/Makefile.in index ed873b316..04fc31a3a 100644 --- a/src/libcharon/plugins/dnscert/Makefile.in +++ b/src/libcharon/plugins/dnscert/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/duplicheck/Makefile.am b/src/libcharon/plugins/duplicheck/Makefile.am index 338a114fe..32b850ccb 100644 --- a/src/libcharon/plugins/duplicheck/Makefile.am +++ b/src/libcharon/plugins/duplicheck/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in index 41862cb2a..da4534c21 100644 --- a/src/libcharon/plugins/duplicheck/Makefile.in +++ b/src/libcharon/plugins/duplicheck/Makefile.in @@ -423,6 +423,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -438,7 +440,6 @@ 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 \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/duplicheck/duplicheck.c b/src/libcharon/plugins/duplicheck/duplicheck.c index 508e8e386..7c4cd5ce1 100644 --- a/src/libcharon/plugins/duplicheck/duplicheck.c +++ b/src/libcharon/plugins/duplicheck/duplicheck.c @@ -19,8 +19,10 @@ #include #include #include +#include #include #include +#include #include "duplicheck_msg.h" diff --git a/src/libcharon/plugins/eap_aka/Makefile.am b/src/libcharon/plugins/eap_aka/Makefile.am index 75e8eafb2..5d7ab8485 100644 --- a/src/libcharon/plugins/eap_aka/Makefile.am +++ b/src/libcharon/plugins/eap_aka/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in index dacddfb87..b5ffd8c24 100644 --- a/src/libcharon/plugins/eap_aka/Makefile.in +++ b/src/libcharon/plugins/eap_aka/Makefile.in @@ -417,6 +417,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ 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 \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am index ec145a39e..d68bfc4c4 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am +++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in index 3c26b8511..e0ad6fe2e 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in +++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in @@ -418,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -433,7 +435,6 @@ 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 \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_dynamic/Makefile.am b/src/libcharon/plugins/eap_dynamic/Makefile.am index 58b827a78..fd08846a9 100644 --- a/src/libcharon/plugins/eap_dynamic/Makefile.am +++ b/src/libcharon/plugins/eap_dynamic/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/eap_dynamic/Makefile.in b/src/libcharon/plugins/eap_dynamic/Makefile.in index 402c7cadc..821f6de6c 100644 --- a/src/libcharon/plugins/eap_dynamic/Makefile.in +++ b/src/libcharon/plugins/eap_dynamic/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/eap_gtc/Makefile.am b/src/libcharon/plugins/eap_gtc/Makefile.am index c3a12ba3e..a7d1f6275 100644 --- a/src/libcharon/plugins/eap_gtc/Makefile.am +++ b/src/libcharon/plugins/eap_gtc/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in index 2279b2514..cfd7c4e24 100644 --- a/src/libcharon/plugins/eap_gtc/Makefile.in +++ b/src/libcharon/plugins/eap_gtc/Makefile.in @@ -415,6 +415,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -430,7 +432,6 @@ 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 = \ diff --git a/src/libcharon/plugins/eap_identity/Makefile.am b/src/libcharon/plugins/eap_identity/Makefile.am index 6c5b43f00..4c44962bd 100644 --- a/src/libcharon/plugins/eap_identity/Makefile.am +++ b/src/libcharon/plugins/eap_identity/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in index 30d2c88d1..1c544f360 100644 --- a/src/libcharon/plugins/eap_identity/Makefile.in +++ b/src/libcharon/plugins/eap_identity/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/eap_md5/Makefile.am b/src/libcharon/plugins/eap_md5/Makefile.am index 16aa1919b..b27e8cc54 100644 --- a/src/libcharon/plugins/eap_md5/Makefile.am +++ b/src/libcharon/plugins/eap_md5/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in index 14616c214..e967262b6 100644 --- a/src/libcharon/plugins/eap_md5/Makefile.in +++ b/src/libcharon/plugins/eap_md5/Makefile.in @@ -415,6 +415,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -430,7 +432,6 @@ 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 = \ diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.am b/src/libcharon/plugins/eap_mschapv2/Makefile.am index 4276a082d..ded9bbe3f 100644 --- a/src/libcharon/plugins/eap_mschapv2/Makefile.am +++ b/src/libcharon/plugins/eap_mschapv2/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in index 78dfd29e3..d96343a5c 100644 --- a/src/libcharon/plugins/eap_mschapv2/Makefile.in +++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/eap_peap/Makefile.am b/src/libcharon/plugins/eap_peap/Makefile.am index 8960b84bd..ef226169d 100644 --- a/src/libcharon/plugins/eap_peap/Makefile.am +++ b/src/libcharon/plugins/eap_peap/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libtls diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in index 2f0d65d6d..0f920fef8 100644 --- a/src/libcharon/plugins/eap_peap/Makefile.in +++ b/src/libcharon/plugins/eap_peap/Makefile.in @@ -417,6 +417,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ 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 \ -I$(top_srcdir)/src/libtls diff --git a/src/libcharon/plugins/eap_radius/Makefile.am b/src/libcharon/plugins/eap_radius/Makefile.am index bc7a7765d..78cf99184 100644 --- a/src/libcharon/plugins/eap_radius/Makefile.am +++ b/src/libcharon/plugins/eap_radius/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libradius diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in index 47534372b..881a5b7e3 100644 --- a/src/libcharon/plugins/eap_radius/Makefile.in +++ b/src/libcharon/plugins/eap_radius/Makefile.in @@ -418,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -433,7 +435,6 @@ 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 \ -I$(top_srcdir)/src/libradius diff --git a/src/libcharon/plugins/eap_sim/Makefile.am b/src/libcharon/plugins/eap_sim/Makefile.am index f68138579..8d93077e2 100644 --- a/src/libcharon/plugins/eap_sim/Makefile.am +++ b/src/libcharon/plugins/eap_sim/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in index 251eeeeba..aaa24bb17 100644 --- a/src/libcharon/plugins/eap_sim/Makefile.in +++ b/src/libcharon/plugins/eap_sim/Makefile.in @@ -417,6 +417,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ 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 \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.am b/src/libcharon/plugins/eap_sim_file/Makefile.am index c38e55e2c..5c5694c18 100644 --- a/src/libcharon/plugins/eap_sim_file/Makefile.am +++ b/src/libcharon/plugins/eap_sim_file/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libsimaka \ -DIPSEC_CONFDIR=\"${sysconfdir}\" diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in index bffcbc0df..6e61f99de 100644 --- a/src/libcharon/plugins/eap_sim_file/Makefile.in +++ b/src/libcharon/plugins/eap_sim_file/Makefile.in @@ -418,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -433,7 +435,6 @@ 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 \ -I$(top_srcdir)/src/libsimaka \ -DIPSEC_CONFDIR=\"${sysconfdir}\" diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.am b/src/libcharon/plugins/eap_sim_pcsc/Makefile.am index 22922049d..5e235e7ea 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.am +++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in index 78682ce37..e821e3ee2 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in +++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in @@ -419,6 +419,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -434,7 +436,6 @@ 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 \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am index f40efbd6f..c0d7b914c 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am +++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in index 2a6be5fd9..b883f0abd 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in @@ -419,6 +419,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -434,7 +436,6 @@ 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 \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.am b/src/libcharon/plugins/eap_simaka_reauth/Makefile.am index 0fb622220..9e55bb188 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.am +++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in index de504d4cd..5417f9639 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in @@ -418,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -433,7 +435,6 @@ 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 \ -I$(top_srcdir)/src/libsimaka diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.am b/src/libcharon/plugins/eap_simaka_sql/Makefile.am index b7d6fd43e..f4c478dba 100644 --- a/src/libcharon/plugins/eap_simaka_sql/Makefile.am +++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libsimaka \ -DIPSEC_CONFDIR=\"${sysconfdir}\" diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in index de3508a07..c858e467c 100644 --- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in @@ -417,6 +417,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ 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 \ -I$(top_srcdir)/src/libsimaka \ -DIPSEC_CONFDIR=\"${sysconfdir}\" diff --git a/src/libcharon/plugins/eap_tls/Makefile.am b/src/libcharon/plugins/eap_tls/Makefile.am index 825beb841..551ecb380 100644 --- a/src/libcharon/plugins/eap_tls/Makefile.am +++ b/src/libcharon/plugins/eap_tls/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libtls diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in index d4219b876..c953d0e9c 100644 --- a/src/libcharon/plugins/eap_tls/Makefile.in +++ b/src/libcharon/plugins/eap_tls/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 \ -I$(top_srcdir)/src/libtls diff --git a/src/libcharon/plugins/eap_tnc/Makefile.am b/src/libcharon/plugins/eap_tnc/Makefile.am index 6fc78bc9a..186ae45e2 100644 --- a/src/libcharon/plugins/eap_tnc/Makefile.am +++ b/src/libcharon/plugins/eap_tnc/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libtls \ -I$(top_srcdir)/src/libtncif \ diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in index 6c34ed098..2f197ed33 100644 --- a/src/libcharon/plugins/eap_tnc/Makefile.in +++ b/src/libcharon/plugins/eap_tnc/Makefile.in @@ -417,6 +417,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ 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 \ -I$(top_srcdir)/src/libtls \ -I$(top_srcdir)/src/libtncif \ diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c index 350001bb4..621caffee 100644 --- a/src/libcharon/plugins/eap_tnc/eap_tnc.c +++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c @@ -328,7 +328,7 @@ static eap_tnc_t *eap_tnc_create(identification_t *server, tnccs = tnc->tnccs->create_instance(tnc->tnccs, tnccs_type, is_server, server, peer, server_ip, peer_ip, (type == EAP_TNC) ? TNC_IFT_EAP_1_1 : TNC_IFT_EAP_2_0, - is_server ? enforce_recommendation : NULL); + enforce_recommendation); if (!tnccs) { DBG1(DBG_TNC, "TNCCS protocol '%s' not enabled", protocol); diff --git a/src/libcharon/plugins/eap_ttls/Makefile.am b/src/libcharon/plugins/eap_ttls/Makefile.am index 3a7a8cda3..3db20e348 100644 --- a/src/libcharon/plugins/eap_ttls/Makefile.am +++ b/src/libcharon/plugins/eap_ttls/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libtls \ -I$(top_srcdir)/src/libradius diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in index 0babf1766..b563acdda 100644 --- a/src/libcharon/plugins/eap_ttls/Makefile.in +++ b/src/libcharon/plugins/eap_ttls/Makefile.in @@ -418,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -433,7 +435,6 @@ 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 \ -I$(top_srcdir)/src/libtls \ -I$(top_srcdir)/src/libradius diff --git a/src/libcharon/plugins/error_notify/Makefile.am b/src/libcharon/plugins/error_notify/Makefile.am index 1c64bd2cc..766bb4c51 100644 --- a/src/libcharon/plugins/error_notify/Makefile.am +++ b/src/libcharon/plugins/error_notify/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/error_notify/Makefile.in b/src/libcharon/plugins/error_notify/Makefile.in index 0a07aa7a3..03dfe3d60 100644 --- a/src/libcharon/plugins/error_notify/Makefile.in +++ b/src/libcharon/plugins/error_notify/Makefile.in @@ -424,6 +424,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -439,7 +441,6 @@ 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 \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/ext_auth/Makefile.am b/src/libcharon/plugins/ext_auth/Makefile.am index d51ea8881..7028819aa 100644 --- a/src/libcharon/plugins/ext_auth/Makefile.am +++ b/src/libcharon/plugins/ext_auth/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/ext_auth/Makefile.in b/src/libcharon/plugins/ext_auth/Makefile.in index d23e680aa..fce2e8e63 100644 --- a/src/libcharon/plugins/ext_auth/Makefile.in +++ b/src/libcharon/plugins/ext_auth/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/farp/Makefile.am b/src/libcharon/plugins/farp/Makefile.am index 0d862b0a9..6d96f3abb 100644 --- a/src/libcharon/plugins/farp/Makefile.am +++ b/src/libcharon/plugins/farp/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in index 318400fc9..2afc5ad76 100644 --- a/src/libcharon/plugins/farp/Makefile.in +++ b/src/libcharon/plugins/farp/Makefile.in @@ -414,6 +414,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -429,7 +431,6 @@ 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 = \ diff --git a/src/libcharon/plugins/forecast/Makefile.am b/src/libcharon/plugins/forecast/Makefile.am index ce573135d..77535294e 100644 --- a/src/libcharon/plugins/forecast/Makefile.am +++ b/src/libcharon/plugins/forecast/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/forecast/Makefile.in b/src/libcharon/plugins/forecast/Makefile.in index 7b190ca25..4f2a407b4 100644 --- a/src/libcharon/plugins/forecast/Makefile.in +++ b/src/libcharon/plugins/forecast/Makefile.in @@ -417,6 +417,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ 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 = \ diff --git a/src/libcharon/plugins/forecast/forecast_forwarder.c b/src/libcharon/plugins/forecast/forecast_forwarder.c index 07a3d4953..40aaa7f25 100644 --- a/src/libcharon/plugins/forecast/forecast_forwarder.c +++ b/src/libcharon/plugins/forecast/forecast_forwarder.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -428,8 +427,7 @@ METHOD(forecast_forwarder_t, destroy, void, lib->watcher->remove(lib->watcher, this->kernel.pkt); close(this->kernel.pkt); } - hydra->kernel_interface->remove_listener(hydra->kernel_interface, - &this->kernel.listener); + charon->kernel->remove_listener(charon->kernel, &this->kernel.listener); free(this); } @@ -486,8 +484,8 @@ forecast_forwarder_t *forecast_forwarder_create(forecast_listener_t *listener) setup_interface(&this->kernel); - hydra->kernel_interface->add_listener(hydra->kernel_interface, - &this->kernel.listener); + charon->kernel->add_listener(charon->kernel, + &this->kernel.listener); lib->watcher->add(lib->watcher, this->kernel.pkt, WATCHER_READ, (watcher_cb_t)receive_casts, this); diff --git a/src/libcharon/plugins/forecast/forecast_listener.c b/src/libcharon/plugins/forecast/forecast_listener.c index 63a8cb15b..8f7f2600c 100644 --- a/src/libcharon/plugins/forecast/forecast_listener.c +++ b/src/libcharon/plugins/forecast/forecast_listener.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010-2014 Martin Willi * Copyright (C) 2010-2014 revosec AG * @@ -25,6 +28,15 @@ #include #include +/** + * Add a struct at the current position in the buffer + */ +#define ADD_STRUCT(pos, st, ...) ({\ + typeof(pos) _cur = pos; pos += XT_ALIGN(sizeof(st));\ + *(st*)_cur = (st){ __VA_ARGS__ };\ + (st*)_cur;\ +}) + typedef struct private_forecast_listener_t private_forecast_listener_t; /** @@ -148,7 +160,10 @@ static bool manage_rule(struct iptc_handle *ipth, const char *chain, } else { - if (!iptc_delete_entry(chain, e, "", ipth)) + u_char matchmask[e->next_offset]; + + memset(matchmask, 255, sizeof(matchmask)); + if (!iptc_delete_entry(chain, e, matchmask, ipth)) { DBG1(DBG_CFG, "deleting %s rule failed: %s", chain, iptc_strerror(errno)); @@ -164,60 +179,60 @@ static bool manage_rule(struct iptc_handle *ipth, const char *chain, static bool manage_pre_esp_in_udp(struct iptc_handle *ipth, entry_t *entry, bool add) { - struct { - struct ipt_entry e; - struct ipt_entry_match m; - struct xt_udp udp; - struct ipt_entry_target t; - struct xt_mark_tginfo2 tm; - } ipt = { - .e = { - .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + - sizeof(ipt.udp)), - .next_offset = sizeof(ipt), - .ip = { - .proto = IPPROTO_UDP, - }, + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + + XT_ALIGN(sizeof(struct xt_udp)); + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + + XT_ALIGN(sizeof(struct xt_mark_tginfo2)); + u_int16_t entry_size = target_offset + target_size; + u_char ipt[entry_size], *pos = ipt; + struct ipt_entry *e; + + memset(ipt, 0, sizeof(ipt)); + e = ADD_STRUCT(pos, struct ipt_entry, + .target_offset = target_offset, + .next_offset = entry_size, + .ip = { + .proto = IPPROTO_UDP, }, - .m = { - .u = { - .user = { - .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)), - .name = "udp", - }, + ); + if (!host2in(entry->lhost, &e->ip.dst, &e->ip.dmsk) || + !host2in(entry->rhost, &e->ip.src, &e->ip.smsk)) + { + return FALSE; + } + ADD_STRUCT(pos, struct ipt_entry_match, + .u = { + .user = { + .match_size = match_size, + .name = "udp", }, }, - .udp = { - .spts = { - entry->rhost->get_port(entry->rhost), - entry->rhost->get_port(entry->lhost) - }, - .dpts = { - entry->lhost->get_port(entry->lhost), - entry->lhost->get_port(entry->lhost) - }, + ); + ADD_STRUCT(pos, struct xt_udp, + .spts = { + entry->rhost->get_port(entry->rhost), + entry->rhost->get_port(entry->lhost) }, - .t = { - .u = { - .user = { - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), - .name = "MARK", - .revision = 2, - }, - }, + .dpts = { + entry->lhost->get_port(entry->lhost), + entry->lhost->get_port(entry->lhost) }, - .tm = { - .mark = entry->mark, - .mask = ~0, + ); + ADD_STRUCT(pos, struct ipt_entry_target, + .u = { + .user = { + .target_size = target_size, + .name = "MARK", + .revision = 2, + }, }, - }; - - if (!host2in(entry->lhost, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || - !host2in(entry->rhost, &ipt.e.ip.src, &ipt.e.ip.smsk)) - { - return FALSE; - } - return manage_rule(ipth, "PREROUTING", add, &ipt.e); + ); + ADD_STRUCT(pos, struct xt_mark_tginfo2, + .mark = entry->mark, + .mask = ~0, + ); + return manage_rule(ipth, "PREROUTING", add, e); } /** @@ -225,53 +240,53 @@ static bool manage_pre_esp_in_udp(struct iptc_handle *ipth, */ static bool manage_pre_esp(struct iptc_handle *ipth, entry_t *entry, bool add) { - struct { - struct ipt_entry e; - struct ipt_entry_match m; - struct xt_esp esp; - struct ipt_entry_target t; - struct xt_mark_tginfo2 tm; - } ipt = { - .e = { - .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + - sizeof(ipt.esp)), - .next_offset = sizeof(ipt), - .ip = { - .proto = IPPROTO_ESP, - }, + u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) + + XT_ALIGN(sizeof(struct xt_esp)); + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size; + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + + XT_ALIGN(sizeof(struct xt_mark_tginfo2)); + u_int16_t entry_size = target_offset + target_size; + u_char ipt[entry_size], *pos = ipt; + struct ipt_entry *e; + + memset(ipt, 0, sizeof(ipt)); + e = ADD_STRUCT(pos, struct ipt_entry, + .target_offset = target_offset, + .next_offset = entry_size, + .ip = { + .proto = IPPROTO_ESP, }, - .m = { - .u = { - .user = { - .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)), - .name = "esp", - }, + ); + if (!host2in(entry->lhost, &e->ip.dst, &e->ip.dmsk) || + !host2in(entry->rhost, &e->ip.src, &e->ip.smsk)) + { + return FALSE; + } + ADD_STRUCT(pos, struct ipt_entry_match, + .u = { + .user = { + .match_size = match_size, + .name = "esp", }, }, - .esp = { - .spis = { htonl(entry->spi), htonl(entry->spi) }, - }, - .t = { - .u = { - .user = { - .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), - .name = "MARK", - .revision = 2, - }, + ); + ADD_STRUCT(pos, struct xt_esp, + .spis = { htonl(entry->spi), htonl(entry->spi) }, + ); + ADD_STRUCT(pos, struct ipt_entry_target, + .u = { + .user = { + .target_size = target_size, + .name = "MARK", + .revision = 2, }, }, - .tm = { - .mark = entry->mark, - .mask = ~0, - }, - }; - - if (!host2in(entry->lhost, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || - !host2in(entry->rhost, &ipt.e.ip.src, &ipt.e.ip.smsk)) - { - return FALSE; - } - return manage_rule(ipth, "PREROUTING", add, &ipt.e); + ); + ADD_STRUCT(pos, struct xt_mark_tginfo2, + .mark = entry->mark, + .mask = ~0, + ); + return manage_rule(ipth, "PREROUTING", add, e); } /** @@ -291,45 +306,52 @@ static bool manage_pre(struct iptc_handle *ipth, entry_t *entry, bool add) */ static bool manage_out(struct iptc_handle *ipth, entry_t *entry, bool add) { - struct { - struct ipt_entry e; - struct ipt_entry_target t; - struct xt_mark_tginfo2 m; - } ipt = { - .e = { - .target_offset = XT_ALIGN(sizeof(ipt.e)), - .next_offset = sizeof(ipt), - }, - .t = { - .u.user.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.m)), - .u.user.name = "MARK", - .u.user.revision = 2, - }, - .m = { - .mark = entry->mark, - .mask = ~0, + u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)); + u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) + + XT_ALIGN(sizeof(struct xt_mark_tginfo2)); + u_int16_t entry_size = target_offset + target_size; + u_char ipt[entry_size], *pos = ipt; + struct ipt_entry *e; + + memset(ipt, 0, sizeof(ipt)); + e = ADD_STRUCT(pos, struct ipt_entry, + .target_offset = target_offset, + .next_offset = entry_size, + ); + ADD_STRUCT(pos, struct ipt_entry_target, + .u = { + .user = { + .target_size = target_size, + .name = "MARK", + .revision = 2, + }, }, - }; + ); + ADD_STRUCT(pos, struct xt_mark_tginfo2, + .mark = entry->mark, + .mask = ~0, + ); + enumerator_t *enumerator; traffic_selector_t *ts; enumerator = array_create_enumerator(entry->rts); while (enumerator->enumerate(enumerator, &ts)) { - if (!ts2in(ts, &ipt.e.ip.dst, &ipt.e.ip.dmsk)) + if (!ts2in(ts, &e->ip.dst, &e->ip.dmsk)) { continue; } - if (ipt.e.ip.dst.s_addr == 0xffffffff || - ipt.e.ip.dst.s_addr == entry->broadcast || - memeq(&ipt.e.ip.dst.s_addr, "\xe0", 1)) + if (e->ip.dst.s_addr == 0xffffffff || + e->ip.dst.s_addr == entry->broadcast || + memeq(&e->ip.dst.s_addr, "\xe0", 1)) { /* skip broadcast/multicast selectors, they are shared and the mark * is set by the socket we use for reinjection */ continue; } - if (!manage_rule(ipth, "PREROUTING", add, &ipt.e) || - !manage_rule(ipth, "OUTPUT", add, &ipt.e)) + if (!manage_rule(ipth, "PREROUTING", add, e) || + !manage_rule(ipth, "OUTPUT", add, e)) { enumerator->destroy(enumerator); return FALSE; diff --git a/src/libcharon/plugins/ha/Makefile.am b/src/libcharon/plugins/ha/Makefile.am index 50d342389..d501834d7 100644 --- a/src/libcharon/plugins/ha/Makefile.am +++ b/src/libcharon/plugins/ha/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in index de74f88cc..677c36afe 100644 --- a/src/libcharon/plugins/ha/Makefile.in +++ b/src/libcharon/plugins/ha/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/ha/ha_child.c b/src/libcharon/plugins/ha/ha_child.c index dbb6adc8f..7dafb1693 100644 --- a/src/libcharon/plugins/ha/ha_child.c +++ b/src/libcharon/plugins/ha/ha_child.c @@ -91,6 +91,10 @@ METHOD(listener_t, child_keys, bool, { m->add_attribute(m, HA_ALG_INTEG, alg); } + if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &alg, NULL)) + { + m->add_attribute(m, HA_ALG_DH, alg); + } if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, &alg, NULL)) { m->add_attribute(m, HA_ESN, alg); diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c index 07ef607c6..ce90f5bfe 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -132,6 +132,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message ike_sa_t *ike_sa = NULL, *old_sa = NULL; ike_version_t version = IKEV2; u_int16_t encr = 0, len = 0, integ = 0, prf = 0, old_prf = PRF_UNDEFINED; + u_int16_t dh_grp = 0; chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty; chunk_t secret = chunk_empty, old_skd = chunk_empty; chunk_t dh_local = chunk_empty, dh_remote = chunk_empty, psk = chunk_empty; @@ -193,6 +194,9 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message case HA_ALG_OLD_PRF: old_prf = value.u16; break; + case HA_ALG_DH: + dh_grp = value.u16; + break; default: break; } @@ -217,6 +221,10 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message { proposal->add_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, prf, 0); } + if (dh_grp) + { + proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP, dh_grp, 0); + } charon->bus->set_sa(charon->bus, ike_sa); dh = ha_diffie_hellman_create(secret, dh_local); if (ike_sa->get_version(ike_sa) == IKEV2) @@ -647,7 +655,7 @@ static void process_child_add(private_ha_dispatcher_t *this, u_int32_t inbound_spi = 0, outbound_spi = 0; u_int16_t inbound_cpi = 0, outbound_cpi = 0; u_int8_t mode = MODE_TUNNEL, ipcomp = 0; - u_int16_t encr = 0, integ = 0, len = 0; + u_int16_t encr = 0, integ = 0, len = 0, dh_grp = 0; u_int16_t esn = NO_EXT_SEQ_NUMBERS; u_int seg_i, seg_o; chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty, secret = chunk_empty; @@ -697,6 +705,9 @@ static void process_child_add(private_ha_dispatcher_t *this, case HA_ALG_INTEG: integ = value.u16; break; + case HA_ALG_DH: + dh_grp = value.u16; + break; case HA_ESN: esn = value.u16; break; @@ -747,6 +758,10 @@ static void process_child_add(private_ha_dispatcher_t *this, { proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, len); } + if (dh_grp) + { + proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP, dh_grp, 0); + } proposal->add_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, esn, 0); if (secret.len) { diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c index 7492dd06e..3ffcaee6b 100644 --- a/src/libcharon/plugins/ha/ha_ike.c +++ b/src/libcharon/plugins/ha/ha_ike.c @@ -121,6 +121,10 @@ METHOD(listener_t, ike_keys, bool, { m->add_attribute(m, HA_ALG_PRF, alg); } + if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &alg, NULL)) + { + m->add_attribute(m, HA_ALG_DH, alg); + } m->add_attribute(m, HA_NONCE_I, nonce_i); m->add_attribute(m, HA_NONCE_R, nonce_r); m->add_attribute(m, HA_SECRET, secret); @@ -310,27 +314,31 @@ METHOD(listener_t, message_hook, bool, sync_vips(this, ike_sa); } } - if (!plain && ike_sa->get_version(ike_sa) == IKEV1) + if (ike_sa->get_version(ike_sa) == IKEV1) { ha_message_t *m; keymat_v1_t *keymat; - u_int32_t mid; chunk_t iv; - mid = message->get_message_id(message); - if (mid == 0) + /* we need the last block (or expected next IV) of Phase 1, which gets + * upated after successful en-/decryption depending on direction */ + if (incoming == plain) { - keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa); - if (keymat->get_iv(keymat, mid, &iv)) + if (message->get_message_id(message) == 0) { - m = ha_message_create(HA_IKE_IV); - m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa)); - m->add_attribute(m, HA_IV, iv); - this->socket->push(this->socket, m); - this->cache->cache(this->cache, ike_sa, m); + keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa); + if (keymat->get_iv(keymat, 0, &iv)) + { + m = ha_message_create(HA_IKE_IV); + m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa)); + m->add_attribute(m, HA_IV, iv); + this->socket->push(this->socket, m); + this->cache->cache(this->cache, ike_sa, m); + } } } - if (!incoming && message->get_exchange_type(message) == TRANSACTION) + if (!plain && !incoming && + message->get_exchange_type(message) == TRANSACTION) { sync_vips(this, ike_sa); } diff --git a/src/libcharon/plugins/ha/ha_message.c b/src/libcharon/plugins/ha/ha_message.c index 6b00ed83f..b40219ce1 100644 --- a/src/libcharon/plugins/ha/ha_message.c +++ b/src/libcharon/plugins/ha/ha_message.c @@ -230,6 +230,7 @@ METHOD(ha_message_t, add_attribute, void, break; } /* u_int16_t */ + case HA_ALG_DH: case HA_ALG_PRF: case HA_ALG_OLD_PRF: case HA_ALG_ENCR: @@ -450,6 +451,7 @@ METHOD(enumerator_t, attribute_enumerate, bool, return TRUE; } /** u_int16_t */ + case HA_ALG_DH: case HA_ALG_PRF: case HA_ALG_OLD_PRF: case HA_ALG_ENCR: diff --git a/src/libcharon/plugins/ha/ha_message.h b/src/libcharon/plugins/ha/ha_message.h index 2ccb1fc55..fe1786edf 100644 --- a/src/libcharon/plugins/ha/ha_message.h +++ b/src/libcharon/plugins/ha/ha_message.h @@ -122,6 +122,8 @@ enum ha_message_attribute_t { HA_ALG_ENCR_LEN, /** u_int16_t, integrity protection algorithm */ HA_ALG_INTEG, + /** u_int16_t, DH group */ + HA_ALG_DH, /** u_int8_t, IPsec mode, TUNNEL|TRANSPORT|... */ HA_IPSEC_MODE, /** u_int8_t, IPComp protocol */ diff --git a/src/libcharon/plugins/ipseckey/Makefile.am b/src/libcharon/plugins/ipseckey/Makefile.am index aed63c122..b8933008c 100644 --- a/src/libcharon/plugins/ipseckey/Makefile.am +++ b/src/libcharon/plugins/ipseckey/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/ipseckey/Makefile.in b/src/libcharon/plugins/ipseckey/Makefile.in index f98e78ffc..0b7a29194 100644 --- a/src/libcharon/plugins/ipseckey/Makefile.in +++ b/src/libcharon/plugins/ipseckey/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/kernel_iph/Makefile.am b/src/libcharon/plugins/kernel_iph/Makefile.am index 56946ae1f..707570195 100644 --- a/src/libcharon/plugins/kernel_iph/Makefile.am +++ b/src/libcharon/plugins/kernel_iph/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/kernel_iph/Makefile.in b/src/libcharon/plugins/kernel_iph/Makefile.in index 7a2583d06..de5bfd517 100644 --- a/src/libcharon/plugins/kernel_iph/Makefile.in +++ b/src/libcharon/plugins/kernel_iph/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c index a4be4041e..6a8a96821 100644 --- a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c +++ b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c @@ -24,7 +24,7 @@ #include "kernel_iph_net.h" -#include +#include #include #include #include @@ -130,7 +130,7 @@ static job_requeue_t roam_event(private_kernel_iph_net_t *this) this->roam_address = FALSE; this->mutex->unlock(this->mutex); - hydra->kernel_interface->roam(hydra->kernel_interface, address); + charon->kernel->roam(charon->kernel, address); return JOB_REQUEUE_NONE; } diff --git a/src/libcharon/plugins/kernel_iph/kernel_iph_plugin.c b/src/libcharon/plugins/kernel_iph/kernel_iph_plugin.c index c5475e30b..c16381440 100644 --- a/src/libcharon/plugins/kernel_iph/kernel_iph_plugin.c +++ b/src/libcharon/plugins/kernel_iph/kernel_iph_plugin.c @@ -17,8 +17,6 @@ #include "kernel_iph_plugin.h" #include "kernel_iph_net.h" -#include - typedef struct private_kernel_iph_plugin_t private_kernel_iph_plugin_t; /** diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.am b/src/libcharon/plugins/kernel_libipsec/Makefile.am index eca2b2325..4757280b4 100644 --- a/src/libcharon/plugins/kernel_libipsec/Makefile.am +++ b/src/libcharon/plugins/kernel_libipsec/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libipsec diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.in b/src/libcharon/plugins/kernel_libipsec/Makefile.in index 6b6c95688..018a25a62 100644 --- a/src/libcharon/plugins/kernel_libipsec/Makefile.in +++ b/src/libcharon/plugins/kernel_libipsec/Makefile.in @@ -418,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -433,7 +435,6 @@ 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 \ -I$(top_srcdir)/src/libipsec diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index d738e6d13..4c8771e96 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include @@ -224,8 +224,7 @@ static inline bool policy_entry_equals(policy_entry_t *a, */ static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard) { - hydra->kernel_interface->expire(hydra->kernel_interface, protocol, - spi, dst, hard); + charon->kernel->expire(charon->kernel, protocol, spi, dst, hard); } METHOD(kernel_ipsec_t, get_features, kernel_feature_t, @@ -313,16 +312,13 @@ static void add_exclude_route(private_kernel_libipsec_ipsec_t *this, if (!route->exclude) { DBG2(DBG_KNL, "installing new exclude route for %H src %H", dst, src); - gtw = hydra->kernel_interface->get_nexthop(hydra->kernel_interface, - dst, -1, NULL); + gtw = charon->kernel->get_nexthop(charon->kernel, dst, -1, NULL); if (gtw) { char *if_name = NULL; - if (hydra->kernel_interface->get_interface( - hydra->kernel_interface, src, &if_name) && - hydra->kernel_interface->add_route(hydra->kernel_interface, - dst->get_address(dst), + if (charon->kernel->get_interface(charon->kernel, src, &if_name) && + charon->kernel->add_route(charon->kernel, dst->get_address(dst), dst->get_family(dst) == AF_INET ? 32 : 128, gtw, src, if_name) == SUCCESS) { @@ -367,14 +363,12 @@ static void remove_exclude_route(private_kernel_libipsec_ipsec_t *this, dst = route->exclude->dst; DBG2(DBG_KNL, "uninstalling exclude route for %H src %H", dst, route->exclude->src); - if (hydra->kernel_interface->get_interface( - hydra->kernel_interface, - route->exclude->src, &if_name) && - hydra->kernel_interface->del_route(hydra->kernel_interface, - dst->get_address(dst), - dst->get_family(dst) == AF_INET ? 32 : 128, - route->exclude->gtw, route->exclude->src, - if_name) != SUCCESS) + if (charon->kernel->get_interface(charon->kernel, route->exclude->src, + &if_name) && + charon->kernel->del_route(charon->kernel, dst->get_address(dst), + dst->get_family(dst) == AF_INET ? 32 : 128, + route->exclude->gtw, route->exclude->src, + if_name) != SUCCESS) { DBG1(DBG_KNL, "uninstalling exclude route for %H failed", dst); } @@ -402,8 +396,8 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this, return TRUE; } - if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface, - src_ts, &src_ip, &is_virtual) != SUCCESS) + if (charon->kernel->get_address_by_ts(charon->kernel, src_ts, &src_ip, + &is_virtual) != SUCCESS) { traffic_selector_t *multicast, *broadcast = NULL; bool ignore = FALSE; @@ -444,8 +438,7 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this, ); #ifndef __linux__ /* on Linux we cant't install a gateway */ - route->gateway = hydra->kernel_interface->get_nexthop( - hydra->kernel_interface, dst, -1, src); + route->gateway = charon->kernel->get_nexthop(charon->kernel, dst, -1, src); #endif if (policy->route) @@ -459,9 +452,9 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this, return TRUE; } /* uninstall previously installed route */ - if (hydra->kernel_interface->del_route(hydra->kernel_interface, - old->dst_net, old->prefixlen, old->gateway, - old->src_ip, old->if_name) != SUCCESS) + if (charon->kernel->del_route(charon->kernel, old->dst_net, + old->prefixlen, old->gateway, + old->src_ip, old->if_name) != SUCCESS) { DBG1(DBG_KNL, "error uninstalling route installed with policy " "%R === %R %N", src_ts, dst_ts, policy_dir_names, @@ -490,9 +483,9 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this, DBG2(DBG_KNL, "installing route: %R src %H dev %s", dst_ts, route->src_ip, route->if_name); - switch (hydra->kernel_interface->add_route(hydra->kernel_interface, - route->dst_net, route->prefixlen, route->gateway, - route->src_ip, route->if_name)) + switch (charon->kernel->add_route(charon->kernel, route->dst_net, + route->prefixlen, route->gateway, + route->src_ip, route->if_name)) { case ALREADY_DONE: /* route exists, do not uninstall */ @@ -571,8 +564,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t, policy_entry_t *policy, *found = NULL; status_t status; - status = ipsec->policies->del_policy(ipsec->policies, src_ts, dst_ts, - direction, sa->reqid, mark, priority); + status = ipsec->policies->del_policy(ipsec->policies, src, dst, src_ts, + dst_ts, direction, type, sa, mark, priority); policy = create_policy_entry(src_ts, dst_ts, direction); @@ -598,9 +591,9 @@ METHOD(kernel_ipsec_t, del_policy, status_t, { route_entry_t *route = policy->route; - if (hydra->kernel_interface->del_route(hydra->kernel_interface, - route->dst_net, route->prefixlen, route->gateway, route->src_ip, - route->if_name) != SUCCESS) + if (charon->kernel->del_route(charon->kernel, route->dst_net, + route->prefixlen, route->gateway, + route->src_ip, route->if_name) != SUCCESS) { DBG1(DBG_KNL, "error uninstalling route installed with " "policy %R === %R %N", src_ts, dst_ts, @@ -629,9 +622,9 @@ METHOD(kernel_ipsec_t, flush_policies, status_t, { route_entry_t *route = pol->route; - hydra->kernel_interface->del_route(hydra->kernel_interface, - route->dst_net, route->prefixlen, route->gateway, - route->src_ip, route->if_name); + charon->kernel->del_route(charon->kernel, route->dst_net, + route->prefixlen, route->gateway, + route->src_ip, route->if_name); remove_exclude_route(this, route); } policy_entry_destroy(pol); diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c index 830954e11..66141ad56 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c @@ -19,7 +19,6 @@ #include "kernel_libipsec_router.h" #include -#include #include #include #include @@ -298,8 +297,7 @@ METHOD(kernel_libipsec_router_t, destroy, void, (ipsec_outbound_cb_t)send_esp); ipsec->processor->unregister_inbound(ipsec->processor, (ipsec_inbound_cb_t)deliver_plain); - hydra->kernel_interface->remove_listener(hydra->kernel_interface, - &this->public.listener); + charon->kernel->remove_listener(charon->kernel, &this->public.listener); this->lock->destroy(this->lock); this->tuns->destroy(this->tuns); close(this->notify[0]); @@ -351,8 +349,7 @@ kernel_libipsec_router_t *kernel_libipsec_router_create() (hashtable_equals_t)tun_entry_equals, 4); this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT); - hydra->kernel_interface->add_listener(hydra->kernel_interface, - &this->public.listener); + charon->kernel->add_listener(charon->kernel, &this->public.listener); ipsec->processor->register_outbound(ipsec->processor, send_esp, NULL); ipsec->processor->register_inbound(ipsec->processor, (ipsec_inbound_cb_t)deliver_plain, this); diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.am b/src/libcharon/plugins/kernel_netlink/Makefile.am new file mode 100644 index 000000000..973e2c2f4 --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/Makefile.am @@ -0,0 +1,44 @@ +AM_CPPFLAGS = \ + -I${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libcharon \ + -DROUTING_TABLE=${routing_table} \ + -DROUTING_TABLE_PRIO=${routing_table_prio} + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-kernel-netlink.la +else +plugin_LTLIBRARIES = libstrongswan-kernel-netlink.la +endif + +libstrongswan_kernel_netlink_la_SOURCES = \ + kernel_netlink_plugin.h kernel_netlink_plugin.c \ + kernel_netlink_ipsec.h kernel_netlink_ipsec.c \ + kernel_netlink_net.h kernel_netlink_net.c \ + kernel_netlink_shared.h kernel_netlink_shared.c + +libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version + + +TESTS = tests + +check_PROGRAMS = $(TESTS) + +tests_SOURCES = \ + tests.h tests.c \ + suites/test_socket.c \ + kernel_netlink_shared.c + +tests_CFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + -DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \ + @COVERAGE_CFLAGS@ + +tests_LDFLAGS = @COVERAGE_LDFLAGS@ +tests_LDADD = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.in b/src/libcharon/plugins/kernel_netlink/Makefile.in new file mode 100644 index 000000000..55dcabf6f --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/Makefile.in @@ -0,0 +1,1007 @@ +# 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@ +TESTS = tests$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) +subdir = src/libcharon/plugins/kernel_netlink +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_kernel_netlink_la_LIBADD = +am_libstrongswan_kernel_netlink_la_OBJECTS = kernel_netlink_plugin.lo \ + kernel_netlink_ipsec.lo kernel_netlink_net.lo \ + kernel_netlink_shared.lo +libstrongswan_kernel_netlink_la_OBJECTS = \ + $(am_libstrongswan_kernel_netlink_la_OBJECTS) +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_kernel_netlink_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_kernel_netlink_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_kernel_netlink_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_kernel_netlink_la_rpath = +am__EXEEXT_1 = tests$(EXEEXT) +am__dirstamp = $(am__leading_dot)dirstamp +am_tests_OBJECTS = tests-tests.$(OBJEXT) \ + suites/tests-test_socket.$(OBJEXT) \ + tests-kernel_netlink_shared.$(OBJEXT) +tests_OBJECTS = $(am_tests_OBJECTS) +tests_DEPENDENCIES = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la +tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(tests_CFLAGS) $(CFLAGS) \ + $(tests_LDFLAGS) $(LDFLAGS) -o $@ +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_kernel_netlink_la_SOURCES) $(tests_SOURCES) +DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) \ + $(tests_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 +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +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@ +EASY_INSTALL = @EASY_INSTALL@ +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@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +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@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +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_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ +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${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libcharon \ + -DROUTING_TABLE=${routing_table} \ + -DROUTING_TABLE_PRIO=${routing_table_prio} + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-netlink.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-netlink.la +libstrongswan_kernel_netlink_la_SOURCES = \ + kernel_netlink_plugin.h kernel_netlink_plugin.c \ + kernel_netlink_ipsec.h kernel_netlink_ipsec.c \ + kernel_netlink_net.h kernel_netlink_net.c \ + kernel_netlink_shared.h kernel_netlink_shared.c + +libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version +tests_SOURCES = \ + tests.h tests.c \ + suites/test_socket.c \ + kernel_netlink_shared.c + +tests_CFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + -DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \ + @COVERAGE_CFLAGS@ + +tests_LDFLAGS = @COVERAGE_LDFLAGS@ +tests_LDADD = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la + +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/kernel_netlink/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_netlink/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-kernel-netlink.la: $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_DEPENDENCIES) $(EXTRA_libstrongswan_kernel_netlink_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_kernel_netlink_la_LINK) $(am_libstrongswan_kernel_netlink_la_rpath) $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +suites/$(am__dirstamp): + @$(MKDIR_P) suites + @: > suites/$(am__dirstamp) +suites/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) suites/$(DEPDIR) + @: > suites/$(DEPDIR)/$(am__dirstamp) +suites/tests-test_socket.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) + +tests$(EXEEXT): $(tests_OBJECTS) $(tests_DEPENDENCIES) $(EXTRA_tests_DEPENDENCIES) + @rm -f tests$(EXEEXT) + $(AM_V_CCLD)$(tests_LINK) $(tests_OBJECTS) $(tests_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f suites/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_ipsec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_net.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_shared.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests-kernel_netlink_shared.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests-tests.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_socket.Po@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 $@ $< + +tests-tests.o: tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-tests.o -MD -MP -MF $(DEPDIR)/tests-tests.Tpo -c -o tests-tests.o `test -f 'tests.c' || echo '$(srcdir)/'`tests.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-tests.Tpo $(DEPDIR)/tests-tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests.c' object='tests-tests.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-tests.o `test -f 'tests.c' || echo '$(srcdir)/'`tests.c + +tests-tests.obj: tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-tests.obj -MD -MP -MF $(DEPDIR)/tests-tests.Tpo -c -o tests-tests.obj `if test -f 'tests.c'; then $(CYGPATH_W) 'tests.c'; else $(CYGPATH_W) '$(srcdir)/tests.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-tests.Tpo $(DEPDIR)/tests-tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests.c' object='tests-tests.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-tests.obj `if test -f 'tests.c'; then $(CYGPATH_W) 'tests.c'; else $(CYGPATH_W) '$(srcdir)/tests.c'; fi` + +suites/tests-test_socket.o: suites/test_socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_socket.o -MD -MP -MF suites/$(DEPDIR)/tests-test_socket.Tpo -c -o suites/tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_socket.Tpo suites/$(DEPDIR)/tests-test_socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_socket.c' object='suites/tests-test_socket.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c + +suites/tests-test_socket.obj: suites/test_socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_socket.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_socket.Tpo -c -o suites/tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_socket.Tpo suites/$(DEPDIR)/tests-test_socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_socket.c' object='suites/tests-test_socket.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi` + +tests-kernel_netlink_shared.o: kernel_netlink_shared.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-kernel_netlink_shared.o -MD -MP -MF $(DEPDIR)/tests-kernel_netlink_shared.Tpo -c -o tests-kernel_netlink_shared.o `test -f 'kernel_netlink_shared.c' || echo '$(srcdir)/'`kernel_netlink_shared.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-kernel_netlink_shared.Tpo $(DEPDIR)/tests-kernel_netlink_shared.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kernel_netlink_shared.c' object='tests-kernel_netlink_shared.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-kernel_netlink_shared.o `test -f 'kernel_netlink_shared.c' || echo '$(srcdir)/'`kernel_netlink_shared.c + +tests-kernel_netlink_shared.obj: kernel_netlink_shared.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-kernel_netlink_shared.obj -MD -MP -MF $(DEPDIR)/tests-kernel_netlink_shared.Tpo -c -o tests-kernel_netlink_shared.obj `if test -f 'kernel_netlink_shared.c'; then $(CYGPATH_W) 'kernel_netlink_shared.c'; else $(CYGPATH_W) '$(srcdir)/kernel_netlink_shared.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-kernel_netlink_shared.Tpo $(DEPDIR)/tests-kernel_netlink_shared.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kernel_netlink_shared.c' object='tests-kernel_netlink_shared.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-kernel_netlink_shared.obj `if test -f 'kernel_netlink_shared.c'; then $(CYGPATH_W) 'kernel_netlink_shared.c'; else $(CYGPATH_W) '$(srcdir)/kernel_netlink_shared.c'; fi` + +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 + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +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 + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +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) + -rm -f suites/$(DEPDIR)/$(am__dirstamp) + -rm -f suites/$(am__dirstamp) + +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-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) suites/$(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) suites/$(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: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS 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/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c new file mode 100644 index 000000000..6d9d63a98 --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -0,0 +1,2975 @@ +/* + * Copyright (C) 2006-2015 Tobias Brunner + * Copyright (C) 2005-2009 Martin Willi + * Copyright (C) 2008-2016 Andreas Steffen + * Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser + * Copyright (C) 2006 Daniel Roethlisberger + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kernel_netlink_ipsec.h" +#include "kernel_netlink_shared.h" + +#include +#include +#include +#include +#include +#include + +/** Required for Linux 2.6.26 kernel and later */ +#ifndef XFRM_STATE_AF_UNSPEC +#define XFRM_STATE_AF_UNSPEC 32 +#endif + +/** From linux/in.h */ +#ifndef IP_XFRM_POLICY +#define IP_XFRM_POLICY 17 +#endif + +/** Missing on uclibc */ +#ifndef IPV6_XFRM_POLICY +#define IPV6_XFRM_POLICY 34 +#endif /*IPV6_XFRM_POLICY*/ + +/* from linux/udp.h */ +#ifndef UDP_ENCAP +#define UDP_ENCAP 100 +#endif + +#ifndef UDP_ENCAP_ESPINUDP +#define UDP_ENCAP_ESPINUDP 2 +#endif + +/* this is not defined on some platforms */ +#ifndef SOL_UDP +#define SOL_UDP IPPROTO_UDP +#endif + +/** Base priority for installed policies */ +#define PRIO_BASE 384 + +/** Default lifetime of an acquire XFRM state (in seconds) */ +#define DEFAULT_ACQUIRE_LIFETIME 165 + +/** + * Map the limit for bytes and packets to XFRM_INF by default + */ +#define XFRM_LIMIT(x) ((x) == 0 ? XFRM_INF : (x)) + +/** + * Create ORable bitfield of XFRM NL groups + */ +#define XFRMNLGRP(x) (1<<(XFRMNLGRP_##x-1)) + +/** + * Returns a pointer to the first rtattr following the nlmsghdr *nlh and the + * 'usual' netlink data x like 'struct xfrm_usersa_info' + */ +#define XFRM_RTA(nlh, x) ((struct rtattr*)(NLMSG_DATA(nlh) + \ + NLMSG_ALIGN(sizeof(x)))) +/** + * Returns the total size of attached rta data + * (after 'usual' netlink data x like 'struct xfrm_usersa_info') + */ +#define XFRM_PAYLOAD(nlh, x) NLMSG_PAYLOAD(nlh, sizeof(x)) + +typedef struct kernel_algorithm_t kernel_algorithm_t; + +/** + * Mapping of IKEv2 kernel identifier to linux crypto API names + */ +struct kernel_algorithm_t { + /** + * Identifier specified in IKEv2 + */ + int ikev2; + + /** + * Name of the algorithm in linux crypto API + */ + char *name; +}; + +ENUM(xfrm_msg_names, XFRM_MSG_NEWSA, XFRM_MSG_MAPPING, + "XFRM_MSG_NEWSA", + "XFRM_MSG_DELSA", + "XFRM_MSG_GETSA", + "XFRM_MSG_NEWPOLICY", + "XFRM_MSG_DELPOLICY", + "XFRM_MSG_GETPOLICY", + "XFRM_MSG_ALLOCSPI", + "XFRM_MSG_ACQUIRE", + "XFRM_MSG_EXPIRE", + "XFRM_MSG_UPDPOLICY", + "XFRM_MSG_UPDSA", + "XFRM_MSG_POLEXPIRE", + "XFRM_MSG_FLUSHSA", + "XFRM_MSG_FLUSHPOLICY", + "XFRM_MSG_NEWAE", + "XFRM_MSG_GETAE", + "XFRM_MSG_REPORT", + "XFRM_MSG_MIGRATE", + "XFRM_MSG_NEWSADINFO", + "XFRM_MSG_GETSADINFO", + "XFRM_MSG_NEWSPDINFO", + "XFRM_MSG_GETSPDINFO", + "XFRM_MSG_MAPPING" +); + +ENUM(xfrm_attr_type_names, XFRMA_UNSPEC, XFRMA_REPLAY_ESN_VAL, + "XFRMA_UNSPEC", + "XFRMA_ALG_AUTH", + "XFRMA_ALG_CRYPT", + "XFRMA_ALG_COMP", + "XFRMA_ENCAP", + "XFRMA_TMPL", + "XFRMA_SA", + "XFRMA_POLICY", + "XFRMA_SEC_CTX", + "XFRMA_LTIME_VAL", + "XFRMA_REPLAY_VAL", + "XFRMA_REPLAY_THRESH", + "XFRMA_ETIMER_THRESH", + "XFRMA_SRCADDR", + "XFRMA_COADDR", + "XFRMA_LASTUSED", + "XFRMA_POLICY_TYPE", + "XFRMA_MIGRATE", + "XFRMA_ALG_AEAD", + "XFRMA_KMADDRESS", + "XFRMA_ALG_AUTH_TRUNC", + "XFRMA_MARK", + "XFRMA_TFCPAD", + "XFRMA_REPLAY_ESN_VAL", +); + +/** + * Algorithms for encryption + */ +static kernel_algorithm_t encryption_algs[] = { +/* {ENCR_DES_IV64, "***" }, */ + {ENCR_DES, "des" }, + {ENCR_3DES, "des3_ede" }, +/* {ENCR_RC5, "***" }, */ +/* {ENCR_IDEA, "***" }, */ + {ENCR_CAST, "cast5" }, + {ENCR_BLOWFISH, "blowfish" }, +/* {ENCR_3IDEA, "***" }, */ +/* {ENCR_DES_IV32, "***" }, */ + {ENCR_NULL, "cipher_null" }, + {ENCR_AES_CBC, "aes" }, + {ENCR_AES_CTR, "rfc3686(ctr(aes))" }, + {ENCR_AES_CCM_ICV8, "rfc4309(ccm(aes))" }, + {ENCR_AES_CCM_ICV12, "rfc4309(ccm(aes))" }, + {ENCR_AES_CCM_ICV16, "rfc4309(ccm(aes))" }, + {ENCR_AES_GCM_ICV8, "rfc4106(gcm(aes))" }, + {ENCR_AES_GCM_ICV12, "rfc4106(gcm(aes))" }, + {ENCR_AES_GCM_ICV16, "rfc4106(gcm(aes))" }, + {ENCR_NULL_AUTH_AES_GMAC, "rfc4543(gcm(aes))" }, + {ENCR_CAMELLIA_CBC, "cbc(camellia)" }, +/* {ENCR_CAMELLIA_CTR, "***" }, */ +/* {ENCR_CAMELLIA_CCM_ICV8, "***" }, */ +/* {ENCR_CAMELLIA_CCM_ICV12, "***" }, */ +/* {ENCR_CAMELLIA_CCM_ICV16, "***" }, */ + {ENCR_SERPENT_CBC, "serpent" }, + {ENCR_TWOFISH_CBC, "twofish" }, + {ENCR_CHACHA20_POLY1305, "rfc7539esp(chacha20,poly1305)"}, +}; + +/** + * Algorithms for integrity protection + */ +static kernel_algorithm_t integrity_algs[] = { + {AUTH_HMAC_MD5_96, "md5" }, + {AUTH_HMAC_MD5_128, "hmac(md5)" }, + {AUTH_HMAC_SHA1_96, "sha1" }, + {AUTH_HMAC_SHA1_160, "hmac(sha1)" }, + {AUTH_HMAC_SHA2_256_96, "sha256" }, + {AUTH_HMAC_SHA2_256_128, "hmac(sha256)" }, + {AUTH_HMAC_SHA2_384_192, "hmac(sha384)" }, + {AUTH_HMAC_SHA2_512_256, "hmac(sha512)" }, +/* {AUTH_DES_MAC, "***" }, */ +/* {AUTH_KPDK_MD5, "***" }, */ + {AUTH_AES_XCBC_96, "xcbc(aes)" }, +}; + +/** + * Algorithms for IPComp + */ +static kernel_algorithm_t compression_algs[] = { +/* {IPCOMP_OUI, "***" }, */ + {IPCOMP_DEFLATE, "deflate" }, + {IPCOMP_LZS, "lzs" }, + {IPCOMP_LZJH, "lzjh" }, +}; + +/** + * Look up a kernel algorithm name and its key size + */ +static char* lookup_algorithm(transform_type_t type, int ikev2) +{ + kernel_algorithm_t *list; + int i, count; + char *name; + + switch (type) + { + case ENCRYPTION_ALGORITHM: + list = encryption_algs; + count = countof(encryption_algs); + break; + case INTEGRITY_ALGORITHM: + list = integrity_algs; + count = countof(integrity_algs); + break; + case COMPRESSION_ALGORITHM: + list = compression_algs; + count = countof(compression_algs); + break; + default: + return NULL; + } + for (i = 0; i < count; i++) + { + if (list[i].ikev2 == ikev2) + { + return list[i].name; + } + } + if (charon->kernel->lookup_algorithm(charon->kernel, ikev2, type, NULL, + &name)) + { + return name; + } + return NULL; +} + +typedef struct private_kernel_netlink_ipsec_t private_kernel_netlink_ipsec_t; + +/** + * Private variables and functions of kernel_netlink class. + */ +struct private_kernel_netlink_ipsec_t { + /** + * Public part of the kernel_netlink_t object + */ + kernel_netlink_ipsec_t public; + + /** + * Mutex to lock access to installed policies + */ + mutex_t *mutex; + + /** + * Hash table of installed policies (policy_entry_t) + */ + hashtable_t *policies; + + /** + * Hash table of IPsec SAs using policies (ipsec_sa_t) + */ + hashtable_t *sas; + + /** + * Netlink xfrm socket (IPsec) + */ + netlink_socket_t *socket_xfrm; + + /** + * Netlink xfrm socket to receive acquire and expire events + */ + int socket_xfrm_events; + + /** + * Whether to install routes along policies + */ + bool install_routes; + + /** + * Whether to set protocol and ports on selector installed with transport + * mode IPsec SAs + */ + bool proto_port_transport; + + /** + * Whether to always use UPDATE to install policies + */ + bool policy_update; + + /** + * Installed port based IKE bypass policies, as bypass_t + */ + array_t *bypass; +}; + +typedef struct route_entry_t route_entry_t; + +/** + * Installed routing entry + */ +struct route_entry_t { + /** Name of the interface the route is bound to */ + char *if_name; + + /** Source ip of the route */ + host_t *src_ip; + + /** Gateway for this route */ + host_t *gateway; + + /** Destination net */ + chunk_t dst_net; + + /** Destination net prefixlen */ + u_int8_t prefixlen; +}; + +/** + * Destroy a route_entry_t object + */ +static void route_entry_destroy(route_entry_t *this) +{ + free(this->if_name); + this->src_ip->destroy(this->src_ip); + DESTROY_IF(this->gateway); + chunk_free(&this->dst_net); + free(this); +} + +/** + * Compare two route_entry_t objects + */ +static bool route_entry_equals(route_entry_t *a, route_entry_t *b) +{ + return a->if_name && b->if_name && streq(a->if_name, b->if_name) && + a->src_ip->ip_equals(a->src_ip, b->src_ip) && + a->gateway->ip_equals(a->gateway, b->gateway) && + chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen; +} + +typedef struct ipsec_sa_t ipsec_sa_t; + +/** + * IPsec SA assigned to a policy. + */ +struct ipsec_sa_t { + /** Source address of this SA */ + host_t *src; + + /** Destination address of this SA */ + host_t *dst; + + /** Optional mark */ + mark_t mark; + + /** Description of this SA */ + ipsec_sa_cfg_t cfg; + + /** Reference count for this SA */ + refcount_t refcount; +}; + +/** + * Hash function for ipsec_sa_t objects + */ +static u_int ipsec_sa_hash(ipsec_sa_t *sa) +{ + return chunk_hash_inc(sa->src->get_address(sa->src), + chunk_hash_inc(sa->dst->get_address(sa->dst), + chunk_hash_inc(chunk_from_thing(sa->mark), + chunk_hash(chunk_from_thing(sa->cfg))))); +} + +/** + * Equality function for ipsec_sa_t objects + */ +static bool ipsec_sa_equals(ipsec_sa_t *sa, ipsec_sa_t *other_sa) +{ + return sa->src->ip_equals(sa->src, other_sa->src) && + sa->dst->ip_equals(sa->dst, other_sa->dst) && + memeq(&sa->mark, &other_sa->mark, sizeof(mark_t)) && + memeq(&sa->cfg, &other_sa->cfg, sizeof(ipsec_sa_cfg_t)); +} + +/** + * Allocate or reference an IPsec SA object + */ +static ipsec_sa_t *ipsec_sa_create(private_kernel_netlink_ipsec_t *this, + host_t *src, host_t *dst, mark_t mark, + ipsec_sa_cfg_t *cfg) +{ + ipsec_sa_t *sa, *found; + INIT(sa, + .src = src, + .dst = dst, + .mark = mark, + .cfg = *cfg, + ); + found = this->sas->get(this->sas, sa); + if (!found) + { + sa->src = src->clone(src); + sa->dst = dst->clone(dst); + this->sas->put(this->sas, sa, sa); + } + else + { + free(sa); + sa = found; + } + ref_get(&sa->refcount); + return sa; +} + +/** + * Release and destroy an IPsec SA object + */ +static void ipsec_sa_destroy(private_kernel_netlink_ipsec_t *this, + ipsec_sa_t *sa) +{ + if (ref_put(&sa->refcount)) + { + this->sas->remove(this->sas, sa); + DESTROY_IF(sa->src); + DESTROY_IF(sa->dst); + free(sa); + } +} + +typedef struct policy_sa_t policy_sa_t; +typedef struct policy_sa_fwd_t policy_sa_fwd_t; + +/** + * Mapping between a policy and an IPsec SA. + */ +struct policy_sa_t { + /** Priority assigned to the policy when installed with this SA */ + u_int32_t priority; + + /** Type of the policy */ + policy_type_t type; + + /** Assigned SA */ + ipsec_sa_t *sa; +}; + +/** + * For forward policies we also cache the traffic selectors in order to install + * the route. + */ +struct policy_sa_fwd_t { + /** Generic interface */ + policy_sa_t generic; + + /** Source traffic selector of this policy */ + traffic_selector_t *src_ts; + + /** Destination traffic selector of this policy */ + traffic_selector_t *dst_ts; +}; + +/** + * Create a policy_sa(_fwd)_t object + */ +static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this, + policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, mark_t mark, + ipsec_sa_cfg_t *cfg) +{ + policy_sa_t *policy; + + if (dir == POLICY_FWD) + { + policy_sa_fwd_t *fwd; + INIT(fwd, + .src_ts = src_ts->clone(src_ts), + .dst_ts = dst_ts->clone(dst_ts), + ); + policy = &fwd->generic; + } + else + { + INIT(policy, .priority = 0); + } + policy->type = type; + policy->sa = ipsec_sa_create(this, src, dst, mark, cfg); + return policy; +} + +/** + * Destroy a policy_sa(_fwd)_t object + */ +static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, + private_kernel_netlink_ipsec_t *this) +{ + if (*dir == POLICY_FWD) + { + policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)policy; + fwd->src_ts->destroy(fwd->src_ts); + fwd->dst_ts->destroy(fwd->dst_ts); + } + ipsec_sa_destroy(this, policy->sa); + free(policy); +} + +typedef struct policy_entry_t policy_entry_t; + +/** + * Installed kernel policy. + */ +struct policy_entry_t { + + /** Direction of this policy: in, out, forward */ + u_int8_t direction; + + /** Parameters of installed policy */ + struct xfrm_selector sel; + + /** Optional mark */ + u_int32_t mark; + + /** Associated route installed for this policy */ + route_entry_t *route; + + /** List of SAs this policy is used by, ordered by priority */ + linked_list_t *used_by; + + /** reqid for this policy */ + u_int32_t reqid; +}; + +/** + * Destroy a policy_entry_t object + */ +static void policy_entry_destroy(private_kernel_netlink_ipsec_t *this, + policy_entry_t *policy) +{ + if (policy->route) + { + route_entry_destroy(policy->route); + } + if (policy->used_by) + { + policy->used_by->invoke_function(policy->used_by, + (linked_list_invoke_t)policy_sa_destroy, + &policy->direction, this); + policy->used_by->destroy(policy->used_by); + } + free(policy); +} + +/** + * Hash function for policy_entry_t objects + */ +static u_int policy_hash(policy_entry_t *key) +{ + chunk_t chunk = chunk_from_thing(key->sel); + return chunk_hash_inc(chunk, chunk_hash(chunk_from_thing(key->mark))); +} + +/** + * Equality function for policy_entry_t objects + */ +static bool policy_equals(policy_entry_t *key, policy_entry_t *other_key) +{ + return memeq(&key->sel, &other_key->sel, sizeof(struct xfrm_selector)) && + key->mark == other_key->mark && + key->direction == other_key->direction; +} + +/** + * Calculate the priority of a policy + */ +static inline u_int32_t get_priority(policy_entry_t *policy, + policy_priority_t prio) +{ + u_int32_t priority = PRIO_BASE; + switch (prio) + { + case POLICY_PRIORITY_FALLBACK: + priority <<= 1; + /* fall-through */ + case POLICY_PRIORITY_ROUTED: + priority <<= 1; + /* fall-through */ + case POLICY_PRIORITY_DEFAULT: + priority <<= 1; + /* fall-through */ + case POLICY_PRIORITY_PASS: + break; + } + /* calculate priority based on selector size, small size = high prio */ + priority -= policy->sel.prefixlen_s; + priority -= policy->sel.prefixlen_d; + priority <<= 2; /* make some room for the two flags */ + priority += policy->sel.sport_mask || policy->sel.dport_mask ? 0 : 2; + priority += policy->sel.proto ? 0 : 1; + return priority; +} + +/** + * Convert the general ipsec mode to the one defined in xfrm.h + */ +static u_int8_t mode2kernel(ipsec_mode_t mode) +{ + switch (mode) + { + case MODE_TRANSPORT: + return XFRM_MODE_TRANSPORT; + case MODE_TUNNEL: + return XFRM_MODE_TUNNEL; + case MODE_BEET: + return XFRM_MODE_BEET; + default: + return mode; + } +} + +/** + * Convert a host_t to a struct xfrm_address + */ +static void host2xfrm(host_t *host, xfrm_address_t *xfrm) +{ + chunk_t chunk = host->get_address(host); + memcpy(xfrm, chunk.ptr, min(chunk.len, sizeof(xfrm_address_t))); +} + +/** + * Convert a struct xfrm_address to a host_t + */ +static host_t* xfrm2host(int family, xfrm_address_t *xfrm, u_int16_t port) +{ + chunk_t chunk; + + switch (family) + { + case AF_INET: + chunk = chunk_create((u_char*)&xfrm->a4, sizeof(xfrm->a4)); + break; + case AF_INET6: + chunk = chunk_create((u_char*)&xfrm->a6, sizeof(xfrm->a6)); + break; + default: + return NULL; + } + return host_create_from_chunk(family, chunk, ntohs(port)); +} + +/** + * Convert a traffic selector address range to subnet and its mask. + */ +static void ts2subnet(traffic_selector_t* ts, + xfrm_address_t *net, u_int8_t *mask) +{ + host_t *net_host; + chunk_t net_chunk; + + ts->to_subnet(ts, &net_host, mask); + net_chunk = net_host->get_address(net_host); + memcpy(net, net_chunk.ptr, net_chunk.len); + net_host->destroy(net_host); +} + +/** + * Convert a traffic selector port range to port/portmask + */ +static void ts2ports(traffic_selector_t* ts, + u_int16_t *port, u_int16_t *mask) +{ + uint16_t from, to, bitmask; + int bit; + + from = ts->get_from_port(ts); + to = ts->get_to_port(ts); + + /* Quick check for a single port */ + if (from == to) + { + *port = htons(from); + *mask = ~0; + } + else + { + /* Compute the port mask for port ranges */ + *mask = 0; + + for (bit = 15; bit >= 0; bit--) + { + bitmask = 1 << bit; + + if ((bitmask & from) != (bitmask & to)) + { + *port = htons(from & *mask); + *mask = htons(*mask); + return; + } + *mask |= bitmask; + } + } + return; +} + +/** + * Convert a pair of traffic_selectors to an xfrm_selector + */ +static struct xfrm_selector ts2selector(traffic_selector_t *src, + traffic_selector_t *dst) +{ + struct xfrm_selector sel; + u_int16_t port; + + memset(&sel, 0, sizeof(sel)); + sel.family = (src->get_type(src) == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6; + /* src or dest proto may be "any" (0), use more restrictive one */ + sel.proto = max(src->get_protocol(src), dst->get_protocol(dst)); + ts2subnet(dst, &sel.daddr, &sel.prefixlen_d); + ts2subnet(src, &sel.saddr, &sel.prefixlen_s); + ts2ports(dst, &sel.dport, &sel.dport_mask); + ts2ports(src, &sel.sport, &sel.sport_mask); + if ((sel.proto == IPPROTO_ICMP || sel.proto == IPPROTO_ICMPV6) && + (sel.dport || sel.sport)) + { + /* the kernel expects the ICMP type and code in the source and + * destination port fields, respectively. */ + port = ntohs(max(sel.dport, sel.sport)); + sel.sport = htons(traffic_selector_icmp_type(port)); + sel.sport_mask = sel.sport ? ~0 : 0; + sel.dport = htons(traffic_selector_icmp_code(port)); + sel.dport_mask = sel.dport ? ~0 : 0; + } + sel.ifindex = 0; + sel.user = 0; + + return sel; +} + +/** + * Convert an xfrm_selector to a src|dst traffic_selector + */ +static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src) +{ + u_char *addr; + u_int8_t prefixlen; + u_int16_t port = 0; + host_t *host = NULL; + + if (src) + { + addr = (u_char*)&sel->saddr; + prefixlen = sel->prefixlen_s; + if (sel->sport_mask) + { + port = ntohs(sel->sport); + } + } + else + { + addr = (u_char*)&sel->daddr; + prefixlen = sel->prefixlen_d; + if (sel->dport_mask) + { + port = ntohs(sel->dport); + } + } + if (sel->proto == IPPROTO_ICMP || sel->proto == IPPROTO_ICMPV6) + { /* convert ICMP[v6] message type and code as supplied by the kernel in + * source and destination ports (both in network order) */ + port = (sel->sport >> 8) | (sel->dport & 0xff00); + port = ntohs(port); + } + /* The Linux 2.6 kernel does not set the selector's family field, + * so as a kludge we additionally test the prefix length. + */ + if (sel->family == AF_INET || sel->prefixlen_s == 32) + { + host = host_create_from_chunk(AF_INET, chunk_create(addr, 4), 0); + } + else if (sel->family == AF_INET6 || sel->prefixlen_s == 128) + { + host = host_create_from_chunk(AF_INET6, chunk_create(addr, 16), 0); + } + + if (host) + { + return traffic_selector_create_from_subnet(host, prefixlen, + sel->proto, port, port ?: 65535); + } + return NULL; +} + +/** + * Process a XFRM_MSG_ACQUIRE from kernel + */ +static void process_acquire(private_kernel_netlink_ipsec_t *this, + struct nlmsghdr *hdr) +{ + struct xfrm_user_acquire *acquire; + struct rtattr *rta; + size_t rtasize; + traffic_selector_t *src_ts, *dst_ts; + u_int32_t reqid = 0; + int proto = 0; + + acquire = NLMSG_DATA(hdr); + rta = XFRM_RTA(hdr, struct xfrm_user_acquire); + rtasize = XFRM_PAYLOAD(hdr, struct xfrm_user_acquire); + + DBG2(DBG_KNL, "received a XFRM_MSG_ACQUIRE"); + + while (RTA_OK(rta, rtasize)) + { + DBG2(DBG_KNL, " %N", xfrm_attr_type_names, rta->rta_type); + + if (rta->rta_type == XFRMA_TMPL) + { + struct xfrm_user_tmpl* tmpl; + tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rta); + reqid = tmpl->reqid; + proto = tmpl->id.proto; + } + rta = RTA_NEXT(rta, rtasize); + } + switch (proto) + { + case 0: + case IPPROTO_ESP: + case IPPROTO_AH: + break; + default: + /* acquire for AH/ESP only, not for IPCOMP */ + return; + } + src_ts = selector2ts(&acquire->sel, TRUE); + dst_ts = selector2ts(&acquire->sel, FALSE); + + charon->kernel->acquire(charon->kernel, reqid, src_ts, dst_ts); +} + +/** + * Process a XFRM_MSG_EXPIRE from kernel + */ +static void process_expire(private_kernel_netlink_ipsec_t *this, + struct nlmsghdr *hdr) +{ + struct xfrm_user_expire *expire; + u_int32_t spi; + u_int8_t protocol; + host_t *dst; + + expire = NLMSG_DATA(hdr); + protocol = expire->state.id.proto; + spi = expire->state.id.spi; + + DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE"); + + if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH) + { + dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0); + if (dst) + { + charon->kernel->expire(charon->kernel, protocol, spi, dst, + expire->hard != 0); + dst->destroy(dst); + } + } +} + +/** + * Process a XFRM_MSG_MIGRATE from kernel + */ +static void process_migrate(private_kernel_netlink_ipsec_t *this, + struct nlmsghdr *hdr) +{ + struct xfrm_userpolicy_id *policy_id; + struct rtattr *rta; + size_t rtasize; + traffic_selector_t *src_ts, *dst_ts; + host_t *local = NULL, *remote = NULL; + host_t *old_src = NULL, *old_dst = NULL; + host_t *new_src = NULL, *new_dst = NULL; + u_int32_t reqid = 0; + policy_dir_t dir; + + policy_id = NLMSG_DATA(hdr); + rta = XFRM_RTA(hdr, struct xfrm_userpolicy_id); + rtasize = XFRM_PAYLOAD(hdr, struct xfrm_userpolicy_id); + + DBG2(DBG_KNL, "received a XFRM_MSG_MIGRATE"); + + src_ts = selector2ts(&policy_id->sel, TRUE); + dst_ts = selector2ts(&policy_id->sel, FALSE); + dir = (policy_dir_t)policy_id->dir; + + DBG2(DBG_KNL, " policy: %R === %R %N", src_ts, dst_ts, policy_dir_names); + + while (RTA_OK(rta, rtasize)) + { + DBG2(DBG_KNL, " %N", xfrm_attr_type_names, rta->rta_type); + if (rta->rta_type == XFRMA_KMADDRESS) + { + struct xfrm_user_kmaddress *kmaddress; + + kmaddress = (struct xfrm_user_kmaddress*)RTA_DATA(rta); + local = xfrm2host(kmaddress->family, &kmaddress->local, 0); + remote = xfrm2host(kmaddress->family, &kmaddress->remote, 0); + DBG2(DBG_KNL, " kmaddress: %H...%H", local, remote); + } + else if (rta->rta_type == XFRMA_MIGRATE) + { + struct xfrm_user_migrate *migrate; + + migrate = (struct xfrm_user_migrate*)RTA_DATA(rta); + old_src = xfrm2host(migrate->old_family, &migrate->old_saddr, 0); + old_dst = xfrm2host(migrate->old_family, &migrate->old_daddr, 0); + new_src = xfrm2host(migrate->new_family, &migrate->new_saddr, 0); + new_dst = xfrm2host(migrate->new_family, &migrate->new_daddr, 0); + reqid = migrate->reqid; + DBG2(DBG_KNL, " migrate %H...%H to %H...%H, reqid {%u}", + old_src, old_dst, new_src, new_dst, reqid); + DESTROY_IF(old_src); + DESTROY_IF(old_dst); + DESTROY_IF(new_src); + DESTROY_IF(new_dst); + } + rta = RTA_NEXT(rta, rtasize); + } + + if (src_ts && dst_ts && local && remote) + { + charon->kernel->migrate(charon->kernel, reqid, src_ts, dst_ts, dir, + local, remote); + } + else + { + DESTROY_IF(src_ts); + DESTROY_IF(dst_ts); + DESTROY_IF(local); + DESTROY_IF(remote); + } +} + +/** + * Process a XFRM_MSG_MAPPING from kernel + */ +static void process_mapping(private_kernel_netlink_ipsec_t *this, + struct nlmsghdr *hdr) +{ + struct xfrm_user_mapping *mapping; + u_int32_t spi; + + mapping = NLMSG_DATA(hdr); + spi = mapping->id.spi; + + DBG2(DBG_KNL, "received a XFRM_MSG_MAPPING"); + + if (mapping->id.proto == IPPROTO_ESP) + { + host_t *dst, *new; + + dst = xfrm2host(mapping->id.family, &mapping->id.daddr, 0); + if (dst) + { + new = xfrm2host(mapping->id.family, &mapping->new_saddr, + mapping->new_sport); + if (new) + { + charon->kernel->mapping(charon->kernel, IPPROTO_ESP, spi, dst, + new); + new->destroy(new); + } + dst->destroy(dst); + } + } +} + +/** + * Receives events from kernel + */ +static bool receive_events(private_kernel_netlink_ipsec_t *this, int fd, + watcher_event_t event) +{ + char response[1024]; + struct nlmsghdr *hdr = (struct nlmsghdr*)response; + struct sockaddr_nl addr; + socklen_t addr_len = sizeof(addr); + int len; + + len = recvfrom(this->socket_xfrm_events, response, sizeof(response), + MSG_DONTWAIT, (struct sockaddr*)&addr, &addr_len); + if (len < 0) + { + switch (errno) + { + case EINTR: + /* interrupted, try again */ + return TRUE; + case EAGAIN: + /* no data ready, select again */ + return TRUE; + default: + DBG1(DBG_KNL, "unable to receive from xfrm event socket"); + sleep(1); + return TRUE; + } + } + + if (addr.nl_pid != 0) + { /* not from kernel. not interested, try another one */ + return TRUE; + } + + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case XFRM_MSG_ACQUIRE: + process_acquire(this, hdr); + break; + case XFRM_MSG_EXPIRE: + process_expire(this, hdr); + break; + case XFRM_MSG_MIGRATE: + process_migrate(this, hdr); + break; + case XFRM_MSG_MAPPING: + process_mapping(this, hdr); + break; + default: + DBG1(DBG_KNL, "received unknown event from xfrm event " + "socket: %d", hdr->nlmsg_type); + break; + } + hdr = NLMSG_NEXT(hdr, len); + } + return TRUE; +} + +METHOD(kernel_ipsec_t, get_features, kernel_feature_t, + private_kernel_netlink_ipsec_t *this) +{ + return KERNEL_ESP_V3_TFC; +} + +/** + * Get an SPI for a specific protocol from the kernel. + */ +static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this, + host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max, + u_int32_t *spi) +{ + netlink_buf_t request; + struct nlmsghdr *hdr, *out; + struct xfrm_userspi_info *userspi; + u_int32_t received_spi = 0; + size_t len; + + memset(&request, 0, sizeof(request)); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST; + hdr->nlmsg_type = XFRM_MSG_ALLOCSPI; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)); + + userspi = NLMSG_DATA(hdr); + host2xfrm(src, &userspi->info.saddr); + host2xfrm(dst, &userspi->info.id.daddr); + userspi->info.id.proto = proto; + userspi->info.mode = XFRM_MODE_TUNNEL; + userspi->info.family = src->get_family(src); + userspi->min = min; + userspi->max = max; + + if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) + { + hdr = out; + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case XFRM_MSG_NEWSA: + { + struct xfrm_usersa_info* usersa = NLMSG_DATA(hdr); + received_spi = usersa->id.spi; + break; + } + case NLMSG_ERROR: + { + struct nlmsgerr *err = NLMSG_DATA(hdr); + DBG1(DBG_KNL, "allocating SPI failed: %s (%d)", + strerror(-err->error), -err->error); + break; + } + default: + hdr = NLMSG_NEXT(hdr, len); + continue; + case NLMSG_DONE: + break; + } + break; + } + free(out); + } + + if (received_spi == 0) + { + return FAILED; + } + + *spi = received_spi; + return SUCCESS; +} + +METHOD(kernel_ipsec_t, get_spi, status_t, + private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, + u_int8_t protocol, u_int32_t *spi) +{ + if (get_spi_internal(this, src, dst, protocol, + 0xc0000000, 0xcFFFFFFF, spi) != SUCCESS) + { + DBG1(DBG_KNL, "unable to get SPI"); + return FAILED; + } + + DBG2(DBG_KNL, "got SPI %.8x", ntohl(*spi)); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, get_cpi, status_t, + private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, + u_int16_t *cpi) +{ + u_int32_t received_spi = 0; + + if (get_spi_internal(this, src, dst, IPPROTO_COMP, + 0x100, 0xEFFF, &received_spi) != SUCCESS) + { + DBG1(DBG_KNL, "unable to get CPI"); + return FAILED; + } + + *cpi = htons((u_int16_t)ntohl(received_spi)); + + DBG2(DBG_KNL, "got CPI %.4x", ntohs(*cpi)); + return SUCCESS; +} + +/** + * Add a XFRM mark to message if required + */ +static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark) +{ + if (mark.value) + { + struct xfrm_mark *xmrk; + + xmrk = netlink_reserve(hdr, buflen, XFRMA_MARK, sizeof(*xmrk)); + if (!xmrk) + { + return FALSE; + } + xmrk->v = mark.value; + xmrk->m = mark.mask; + } + return TRUE; +} + +METHOD(kernel_ipsec_t, add_sa, status_t, + private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark, + u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, + u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, + u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t* src_ts, linked_list_t* dst_ts) +{ + netlink_buf_t request; + char *alg_name; + struct nlmsghdr *hdr; + struct xfrm_usersa_info *sa; + u_int16_t icv_size = 64; + ipsec_mode_t original_mode = mode; + traffic_selector_t *first_src_ts, *first_dst_ts; + status_t status = FAILED; + + /* if IPComp is used, we install an additional IPComp SA. if the cpi is 0 + * we are in the recursive call below */ + if (ipcomp != IPCOMP_NONE && cpi != 0) + { + lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}}; + add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark, + tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, + chunk_empty, mode, ipcomp, 0, 0, initiator, FALSE, FALSE, + inbound, update, src_ts, dst_ts); + ipcomp = IPCOMP_NONE; + /* use transport mode ESP SA, IPComp uses tunnel mode */ + mode = MODE_TRANSPORT; + } + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u} (mark " + "%u/0x%08x)", ntohl(spi), reqid, mark.value, mark.mask); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = update ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); + + sa = NLMSG_DATA(hdr); + host2xfrm(src, &sa->saddr); + host2xfrm(dst, &sa->id.daddr); + sa->id.spi = spi; + sa->id.proto = protocol; + sa->family = src->get_family(src); + sa->mode = mode2kernel(mode); + switch (mode) + { + case MODE_TUNNEL: + sa->flags |= XFRM_STATE_AF_UNSPEC; + break; + case MODE_BEET: + case MODE_TRANSPORT: + if (original_mode == MODE_TUNNEL) + { /* don't install selectors for switched SAs. because only one + * selector can be installed other traffic would get dropped */ + break; + } + if (src_ts->get_first(src_ts, (void**)&first_src_ts) == SUCCESS && + dst_ts->get_first(dst_ts, (void**)&first_dst_ts) == SUCCESS) + { + sa->sel = ts2selector(first_src_ts, first_dst_ts); + if (!this->proto_port_transport) + { + /* don't install proto/port on SA. This would break + * potential secondary SAs for the same address using a + * different prot/port. */ + sa->sel.proto = 0; + sa->sel.dport = sa->sel.dport_mask = 0; + sa->sel.sport = sa->sel.sport_mask = 0; + } + } + break; + default: + break; + } + + sa->reqid = reqid; + sa->lft.soft_byte_limit = XFRM_LIMIT(lifetime->bytes.rekey); + sa->lft.hard_byte_limit = XFRM_LIMIT(lifetime->bytes.life); + sa->lft.soft_packet_limit = XFRM_LIMIT(lifetime->packets.rekey); + sa->lft.hard_packet_limit = XFRM_LIMIT(lifetime->packets.life); + /* we use lifetimes since added, not since used */ + sa->lft.soft_add_expires_seconds = lifetime->time.rekey; + sa->lft.hard_add_expires_seconds = lifetime->time.life; + sa->lft.soft_use_expires_seconds = 0; + sa->lft.hard_use_expires_seconds = 0; + + switch (enc_alg) + { + case ENCR_UNDEFINED: + /* no encryption */ + break; + case ENCR_AES_CCM_ICV16: + case ENCR_AES_GCM_ICV16: + case ENCR_NULL_AUTH_AES_GMAC: + case ENCR_CAMELLIA_CCM_ICV16: + case ENCR_CHACHA20_POLY1305: + icv_size += 32; + /* FALL */ + case ENCR_AES_CCM_ICV12: + case ENCR_AES_GCM_ICV12: + case ENCR_CAMELLIA_CCM_ICV12: + icv_size += 32; + /* FALL */ + case ENCR_AES_CCM_ICV8: + case ENCR_AES_GCM_ICV8: + case ENCR_CAMELLIA_CCM_ICV8: + { + struct xfrm_algo_aead *algo; + + alg_name = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg); + if (alg_name == NULL) + { + DBG1(DBG_KNL, "algorithm %N not supported by kernel!", + encryption_algorithm_names, enc_alg); + goto failed; + } + DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", + encryption_algorithm_names, enc_alg, enc_key.len * 8); + + algo = netlink_reserve(hdr, sizeof(request), XFRMA_ALG_AEAD, + sizeof(*algo) + enc_key.len); + if (!algo) + { + goto failed; + } + algo->alg_key_len = enc_key.len * 8; + algo->alg_icv_len = icv_size; + strncpy(algo->alg_name, alg_name, sizeof(algo->alg_name)); + algo->alg_name[sizeof(algo->alg_name) - 1] = '\0'; + memcpy(algo->alg_key, enc_key.ptr, enc_key.len); + break; + } + default: + { + struct xfrm_algo *algo; + + alg_name = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg); + if (alg_name == NULL) + { + DBG1(DBG_KNL, "algorithm %N not supported by kernel!", + encryption_algorithm_names, enc_alg); + goto failed; + } + DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", + encryption_algorithm_names, enc_alg, enc_key.len * 8); + + algo = netlink_reserve(hdr, sizeof(request), XFRMA_ALG_CRYPT, + sizeof(*algo) + enc_key.len); + if (!algo) + { + goto failed; + } + algo->alg_key_len = enc_key.len * 8; + strncpy(algo->alg_name, alg_name, sizeof(algo->alg_name)); + algo->alg_name[sizeof(algo->alg_name) - 1] = '\0'; + memcpy(algo->alg_key, enc_key.ptr, enc_key.len); + } + } + + if (int_alg != AUTH_UNDEFINED) + { + u_int trunc_len = 0; + + alg_name = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg); + if (alg_name == NULL) + { + DBG1(DBG_KNL, "algorithm %N not supported by kernel!", + integrity_algorithm_names, int_alg); + goto failed; + } + DBG2(DBG_KNL, " using integrity algorithm %N with key size %d", + integrity_algorithm_names, int_alg, int_key.len * 8); + + switch (int_alg) + { + case AUTH_HMAC_MD5_128: + case AUTH_HMAC_SHA2_256_128: + trunc_len = 128; + break; + case AUTH_HMAC_SHA1_160: + trunc_len = 160; + break; + default: + break; + } + + if (trunc_len) + { + struct xfrm_algo_auth* algo; + + /* the kernel uses SHA256 with 96 bit truncation by default, + * use specified truncation size supported by newer kernels. + * also use this for untruncated MD5 and SHA1. */ + algo = netlink_reserve(hdr, sizeof(request), XFRMA_ALG_AUTH_TRUNC, + sizeof(*algo) + int_key.len); + if (!algo) + { + goto failed; + } + algo->alg_key_len = int_key.len * 8; + algo->alg_trunc_len = trunc_len; + strncpy(algo->alg_name, alg_name, sizeof(algo->alg_name)); + algo->alg_name[sizeof(algo->alg_name) - 1] = '\0'; + memcpy(algo->alg_key, int_key.ptr, int_key.len); + } + else + { + struct xfrm_algo* algo; + + algo = netlink_reserve(hdr, sizeof(request), XFRMA_ALG_AUTH, + sizeof(*algo) + int_key.len); + if (!algo) + { + goto failed; + } + algo->alg_key_len = int_key.len * 8; + strncpy(algo->alg_name, alg_name, sizeof(algo->alg_name)); + algo->alg_name[sizeof(algo->alg_name) - 1] = '\0'; + memcpy(algo->alg_key, int_key.ptr, int_key.len); + } + } + + if (ipcomp != IPCOMP_NONE) + { + struct xfrm_algo* algo; + + alg_name = lookup_algorithm(COMPRESSION_ALGORITHM, ipcomp); + if (alg_name == NULL) + { + DBG1(DBG_KNL, "algorithm %N not supported by kernel!", + ipcomp_transform_names, ipcomp); + goto failed; + } + DBG2(DBG_KNL, " using compression algorithm %N", + ipcomp_transform_names, ipcomp); + + algo = netlink_reserve(hdr, sizeof(request), XFRMA_ALG_COMP, + sizeof(*algo)); + if (!algo) + { + goto failed; + } + algo->alg_key_len = 0; + strncpy(algo->alg_name, alg_name, sizeof(algo->alg_name)); + algo->alg_name[sizeof(algo->alg_name) - 1] = '\0'; + } + + if (encap) + { + struct xfrm_encap_tmpl *tmpl; + + tmpl = netlink_reserve(hdr, sizeof(request), XFRMA_ENCAP, sizeof(*tmpl)); + if (!tmpl) + { + goto failed; + } + tmpl->encap_type = UDP_ENCAP_ESPINUDP; + tmpl->encap_sport = htons(src->get_port(src)); + tmpl->encap_dport = htons(dst->get_port(dst)); + memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t)); + /* encap_oa could probably be derived from the + * traffic selectors [rfc4306, p39]. In the netlink kernel + * implementation pluto does the same as we do here but it uses + * encap_oa in the pfkey implementation. + * BUT as /usr/src/linux/net/key/af_key.c indicates the kernel ignores + * it anyway + * -> does that mean that NAT-T encap doesn't work in transport mode? + * No. The reason the kernel ignores NAT-OA is that it recomputes + * (or, rather, just ignores) the checksum. If packets pass the IPsec + * checks it marks them "checksum ok" so OA isn't needed. */ + } + + if (!add_mark(hdr, sizeof(request), mark)) + { + goto failed; + } + + if (tfc && protocol == IPPROTO_ESP && mode == MODE_TUNNEL) + { /* the kernel supports TFC padding only for tunnel mode ESP SAs */ + u_int32_t *tfcpad; + + tfcpad = netlink_reserve(hdr, sizeof(request), XFRMA_TFCPAD, + sizeof(*tfcpad)); + if (!tfcpad) + { + goto failed; + } + *tfcpad = tfc; + } + + if (protocol != IPPROTO_COMP) + { + if (replay_window != 0 && (esn || replay_window > 32)) + { + /* for ESN or larger replay windows we need the new + * XFRMA_REPLAY_ESN_VAL attribute to configure a bitmap */ + struct xfrm_replay_state_esn *replay; + u_int32_t bmp_size; + + bmp_size = round_up(replay_window, sizeof(u_int32_t) * 8) / 8; + replay = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_ESN_VAL, + sizeof(*replay) + bmp_size); + if (!replay) + { + goto failed; + } + /* bmp_len contains number uf __u32's */ + replay->bmp_len = bmp_size / sizeof(u_int32_t); + replay->replay_window = replay_window; + DBG2(DBG_KNL, " using replay window of %u packets", replay_window); + + if (esn) + { + DBG2(DBG_KNL, " using extended sequence numbers (ESN)"); + sa->flags |= XFRM_STATE_ESN; + } + } + else + { + DBG2(DBG_KNL, " using replay window of %u packets", replay_window); + sa->replay_window = replay_window; + } + } + + if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) + { + if (mark.value) + { + DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x " + "(mark %u/0x%08x)", ntohl(spi), mark.value, mark.mask); + } + else + { + DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi)); + } + goto failed; + } + + status = SUCCESS; + +failed: + memwipe(&request, sizeof(request)); + return status; +} + +/** + * Get the ESN replay state (i.e. sequence numbers) of an SA. + * + * Allocates into one the replay state structure we get from the kernel. + */ +static void get_replay_state(private_kernel_netlink_ipsec_t *this, + u_int32_t spi, u_int8_t protocol, + host_t *dst, mark_t mark, + struct xfrm_replay_state_esn **replay_esn, + u_int32_t *replay_esn_len, + struct xfrm_replay_state **replay, + struct xfrm_lifetime_cur **lifetime) +{ + netlink_buf_t request; + struct nlmsghdr *hdr, *out = NULL; + struct xfrm_aevent_id *out_aevent = NULL, *aevent_id; + size_t len; + struct rtattr *rta; + size_t rtasize; + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "querying replay state from SAD entry with SPI %.8x", + ntohl(spi)); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST; + hdr->nlmsg_type = XFRM_MSG_GETAE; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id)); + + aevent_id = NLMSG_DATA(hdr); + aevent_id->flags = XFRM_AE_RVAL; + + host2xfrm(dst, &aevent_id->sa_id.daddr); + aevent_id->sa_id.spi = spi; + aevent_id->sa_id.proto = protocol; + aevent_id->sa_id.family = dst->get_family(dst); + + if (!add_mark(hdr, sizeof(request), mark)) + { + return; + } + + if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) + { + hdr = out; + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case XFRM_MSG_NEWAE: + { + out_aevent = NLMSG_DATA(hdr); + break; + } + case NLMSG_ERROR: + { + struct nlmsgerr *err = NLMSG_DATA(hdr); + DBG1(DBG_KNL, "querying replay state from SAD entry " + "failed: %s (%d)", strerror(-err->error), + -err->error); + break; + } + default: + hdr = NLMSG_NEXT(hdr, len); + continue; + case NLMSG_DONE: + break; + } + break; + } + } + + if (out_aevent) + { + rta = XFRM_RTA(out, struct xfrm_aevent_id); + rtasize = XFRM_PAYLOAD(out, struct xfrm_aevent_id); + while (RTA_OK(rta, rtasize)) + { + if (rta->rta_type == XFRMA_LTIME_VAL && + RTA_PAYLOAD(rta) == sizeof(**lifetime)) + { + free(*lifetime); + *lifetime = malloc(RTA_PAYLOAD(rta)); + memcpy(*lifetime, RTA_DATA(rta), RTA_PAYLOAD(rta)); + } + if (rta->rta_type == XFRMA_REPLAY_VAL && + RTA_PAYLOAD(rta) == sizeof(**replay)) + { + free(*replay); + *replay = malloc(RTA_PAYLOAD(rta)); + memcpy(*replay, RTA_DATA(rta), RTA_PAYLOAD(rta)); + } + if (rta->rta_type == XFRMA_REPLAY_ESN_VAL && + RTA_PAYLOAD(rta) >= sizeof(**replay_esn)) + { + free(*replay_esn); + *replay_esn = malloc(RTA_PAYLOAD(rta)); + *replay_esn_len = RTA_PAYLOAD(rta); + memcpy(*replay_esn, RTA_DATA(rta), RTA_PAYLOAD(rta)); + } + rta = RTA_NEXT(rta, rtasize); + } + } + free(out); +} + +METHOD(kernel_ipsec_t, query_sa, status_t, + private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, mark_t mark, + u_int64_t *bytes, u_int64_t *packets, time_t *time) +{ + netlink_buf_t request; + struct nlmsghdr *out = NULL, *hdr; + struct xfrm_usersa_id *sa_id; + struct xfrm_usersa_info *sa = NULL; + status_t status = FAILED; + size_t len; + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "querying SAD entry with SPI %.8x (mark %u/0x%08x)", + ntohl(spi), mark.value, mark.mask); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST; + hdr->nlmsg_type = XFRM_MSG_GETSA; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); + + sa_id = NLMSG_DATA(hdr); + host2xfrm(dst, &sa_id->daddr); + sa_id->spi = spi; + sa_id->proto = protocol; + sa_id->family = dst->get_family(dst); + + if (!add_mark(hdr, sizeof(request), mark)) + { + return FAILED; + } + + if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) + { + hdr = out; + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case XFRM_MSG_NEWSA: + { + sa = NLMSG_DATA(hdr); + break; + } + case NLMSG_ERROR: + { + struct nlmsgerr *err = NLMSG_DATA(hdr); + + if (mark.value) + { + DBG1(DBG_KNL, "querying SAD entry with SPI %.8x " + "(mark %u/0x%08x) failed: %s (%d)", + ntohl(spi), mark.value, mark.mask, + strerror(-err->error), -err->error); + } + else + { + DBG1(DBG_KNL, "querying SAD entry with SPI %.8x " + "failed: %s (%d)", ntohl(spi), + strerror(-err->error), -err->error); + } + break; + } + default: + hdr = NLMSG_NEXT(hdr, len); + continue; + case NLMSG_DONE: + break; + } + break; + } + } + + if (sa == NULL) + { + DBG2(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); + } + else + { + if (bytes) + { + *bytes = sa->curlft.bytes; + } + if (packets) + { + *packets = sa->curlft.packets; + } + if (time) + { /* curlft contains an "use" time, but that contains a timestamp + * of the first use, not the last. Last use time must be queried + * on the policy on Linux */ + *time = 0; + } + status = SUCCESS; + } + memwipe(out, len); + free(out); + return status; +} + +METHOD(kernel_ipsec_t, del_sa, status_t, + private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark) +{ + netlink_buf_t request; + struct nlmsghdr *hdr; + struct xfrm_usersa_id *sa_id; + + /* if IPComp was used, we first delete the additional IPComp SA */ + if (cpi) + { + del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0, mark); + } + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x (mark %u/0x%08x)", + ntohl(spi), mark.value, mark.mask); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = XFRM_MSG_DELSA; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); + + sa_id = NLMSG_DATA(hdr); + host2xfrm(dst, &sa_id->daddr); + sa_id->spi = spi; + sa_id->proto = protocol; + sa_id->family = dst->get_family(dst); + + if (!add_mark(hdr, sizeof(request), mark)) + { + return FAILED; + } + + switch (this->socket_xfrm->send_ack(this->socket_xfrm, hdr)) + { + case SUCCESS: + DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x (mark %u/0x%08x)", + ntohl(spi), mark.value, mark.mask); + return SUCCESS; + case NOT_FOUND: + return NOT_FOUND; + default: + if (mark.value) + { + DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x " + "(mark %u/0x%08x)", ntohl(spi), mark.value, mark.mask); + } + else + { + DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", + ntohl(spi)); + } + return FAILED; + } +} + +METHOD(kernel_ipsec_t, update_sa, status_t, + private_kernel_netlink_ipsec_t *this, u_int32_t spi, u_int8_t protocol, + u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst, + bool old_encap, bool new_encap, mark_t mark) +{ + netlink_buf_t request; + struct nlmsghdr *hdr, *out = NULL; + struct xfrm_usersa_id *sa_id; + struct xfrm_usersa_info *out_sa = NULL, *sa; + size_t len; + struct rtattr *rta; + size_t rtasize; + struct xfrm_encap_tmpl* tmpl = NULL; + struct xfrm_replay_state *replay = NULL; + struct xfrm_replay_state_esn *replay_esn = NULL; + struct xfrm_lifetime_cur *lifetime = NULL; + u_int32_t replay_esn_len = 0; + status_t status = FAILED; + + /* if IPComp is used, we first update the IPComp SA */ + if (cpi) + { + update_sa(this, htonl(ntohs(cpi)), IPPROTO_COMP, 0, + src, dst, new_src, new_dst, FALSE, FALSE, mark); + } + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "querying SAD entry with SPI %.8x for update", ntohl(spi)); + + /* query the existing SA first */ + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST; + hdr->nlmsg_type = XFRM_MSG_GETSA; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)); + + sa_id = NLMSG_DATA(hdr); + host2xfrm(dst, &sa_id->daddr); + sa_id->spi = spi; + sa_id->proto = protocol; + sa_id->family = dst->get_family(dst); + + if (!add_mark(hdr, sizeof(request), mark)) + { + return FAILED; + } + + if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) + { + hdr = out; + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case XFRM_MSG_NEWSA: + { + out_sa = NLMSG_DATA(hdr); + break; + } + case NLMSG_ERROR: + { + struct nlmsgerr *err = NLMSG_DATA(hdr); + DBG1(DBG_KNL, "querying SAD entry failed: %s (%d)", + strerror(-err->error), -err->error); + break; + } + default: + hdr = NLMSG_NEXT(hdr, len); + continue; + case NLMSG_DONE: + break; + } + break; + } + } + if (out_sa == NULL) + { + DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi)); + goto failed; + } + + get_replay_state(this, spi, protocol, dst, mark, &replay_esn, + &replay_esn_len, &replay, &lifetime); + + /* delete the old SA (without affecting the IPComp SA) */ + if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS) + { + DBG1(DBG_KNL, "unable to delete old SAD entry with SPI %.8x", + ntohl(spi)); + goto failed; + } + + DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H", + ntohl(spi), src, dst, new_src, new_dst); + /* copy over the SA from out to request */ + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = XFRM_MSG_NEWSA; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); + sa = NLMSG_DATA(hdr); + memcpy(sa, NLMSG_DATA(out), sizeof(struct xfrm_usersa_info)); + sa->family = new_dst->get_family(new_dst); + + if (!src->ip_equals(src, new_src)) + { + host2xfrm(new_src, &sa->saddr); + } + if (!dst->ip_equals(dst, new_dst)) + { + host2xfrm(new_dst, &sa->id.daddr); + } + + rta = XFRM_RTA(out, struct xfrm_usersa_info); + rtasize = XFRM_PAYLOAD(out, struct xfrm_usersa_info); + while (RTA_OK(rta, rtasize)) + { + /* copy all attributes, but not XFRMA_ENCAP if we are disabling it */ + if (rta->rta_type != XFRMA_ENCAP || new_encap) + { + if (rta->rta_type == XFRMA_ENCAP) + { /* update encap tmpl */ + tmpl = RTA_DATA(rta); + tmpl->encap_sport = ntohs(new_src->get_port(new_src)); + tmpl->encap_dport = ntohs(new_dst->get_port(new_dst)); + } + netlink_add_attribute(hdr, rta->rta_type, + chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), + sizeof(request)); + } + rta = RTA_NEXT(rta, rtasize); + } + + if (tmpl == NULL && new_encap) + { /* add tmpl if we are enabling it */ + tmpl = netlink_reserve(hdr, sizeof(request), XFRMA_ENCAP, sizeof(*tmpl)); + if (!tmpl) + { + goto failed; + } + tmpl->encap_type = UDP_ENCAP_ESPINUDP; + tmpl->encap_sport = ntohs(new_src->get_port(new_src)); + tmpl->encap_dport = ntohs(new_dst->get_port(new_dst)); + memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t)); + } + + if (replay_esn) + { + struct xfrm_replay_state_esn *state; + + state = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_ESN_VAL, + replay_esn_len); + if (!state) + { + goto failed; + } + memcpy(state, replay_esn, replay_esn_len); + } + else if (replay) + { + struct xfrm_replay_state *state; + + state = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_VAL, + sizeof(*state)); + if (!state) + { + goto failed; + } + memcpy(state, replay, sizeof(*state)); + } + else + { + DBG1(DBG_KNL, "unable to copy replay state from old SAD entry with " + "SPI %.8x", ntohl(spi)); + } + if (lifetime) + { + struct xfrm_lifetime_cur *state; + + state = netlink_reserve(hdr, sizeof(request), XFRMA_LTIME_VAL, + sizeof(*state)); + if (!state) + { + goto failed; + } + memcpy(state, lifetime, sizeof(*state)); + } + else + { + DBG1(DBG_KNL, "unable to copy usage stats from old SAD entry with " + "SPI %.8x", ntohl(spi)); + } + + if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) + { + DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi)); + goto failed; + } + + status = SUCCESS; +failed: + free(replay); + free(replay_esn); + free(lifetime); + memwipe(out, len); + memwipe(&request, sizeof(request)); + free(out); + + return status; +} + +METHOD(kernel_ipsec_t, flush_sas, status_t, + private_kernel_netlink_ipsec_t *this) +{ + netlink_buf_t request; + struct nlmsghdr *hdr; + struct xfrm_usersa_flush *flush; + struct { + u_int8_t proto; + char *name; + } protos[] = { + { IPPROTO_AH, "AH" }, + { IPPROTO_ESP, "ESP" }, + { IPPROTO_COMP, "IPComp" }, + }; + int i; + + memset(&request, 0, sizeof(request)); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = XFRM_MSG_FLUSHSA; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)); + + flush = NLMSG_DATA(hdr); + + for (i = 0; i < countof(protos); i++) + { + DBG2(DBG_KNL, "flushing all %s SAD entries", protos[i].name); + + flush->proto = protos[i].proto; + + if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) + { + DBG1(DBG_KNL, "unable to flush %s SAD entries", protos[i].name); + return FAILED; + } + } + return SUCCESS; +} + +/** + * Add or update a policy in the kernel. + * + * Note: The mutex has to be locked when entering this function + * and is unlocked here in any case. + */ +static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, + policy_entry_t *policy, policy_sa_t *mapping, bool update) +{ + netlink_buf_t request; + policy_entry_t clone; + ipsec_sa_t *ipsec = mapping->sa; + struct xfrm_userpolicy_info *policy_info; + struct nlmsghdr *hdr; + status_t status; + int i; + + /* clone the policy so we are able to check it out again later */ + memcpy(&clone, policy, sizeof(policy_entry_t)); + + memset(&request, 0, sizeof(request)); + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = update ? XFRM_MSG_UPDPOLICY : XFRM_MSG_NEWPOLICY; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)); + + policy_info = NLMSG_DATA(hdr); + policy_info->sel = policy->sel; + policy_info->dir = policy->direction; + + /* calculate priority based on selector size, small size = high prio */ + policy_info->priority = mapping->priority; + policy_info->action = mapping->type != POLICY_DROP ? XFRM_POLICY_ALLOW + : XFRM_POLICY_BLOCK; + policy_info->share = XFRM_SHARE_ANY; + + /* policies don't expire */ + policy_info->lft.soft_byte_limit = XFRM_INF; + policy_info->lft.soft_packet_limit = XFRM_INF; + policy_info->lft.hard_byte_limit = XFRM_INF; + policy_info->lft.hard_packet_limit = XFRM_INF; + policy_info->lft.soft_add_expires_seconds = 0; + policy_info->lft.hard_add_expires_seconds = 0; + policy_info->lft.soft_use_expires_seconds = 0; + policy_info->lft.hard_use_expires_seconds = 0; + + if (mapping->type == POLICY_IPSEC) + { + struct xfrm_user_tmpl *tmpl; + struct { + u_int8_t proto; + bool use; + } protos[] = { + { IPPROTO_COMP, ipsec->cfg.ipcomp.transform != IPCOMP_NONE }, + { IPPROTO_ESP, ipsec->cfg.esp.use }, + { IPPROTO_AH, ipsec->cfg.ah.use }, + }; + ipsec_mode_t proto_mode = ipsec->cfg.mode; + int count = 0; + + for (i = 0; i < countof(protos); i++) + { + if (protos[i].use) + { + count++; + } + } + tmpl = netlink_reserve(hdr, sizeof(request), XFRMA_TMPL, + count * sizeof(*tmpl)); + if (!tmpl) + { + this->mutex->unlock(this->mutex); + return FAILED; + } + + for (i = 0; i < countof(protos); i++) + { + if (!protos[i].use) + { + continue; + } + tmpl->reqid = ipsec->cfg.reqid; + tmpl->id.proto = protos[i].proto; + tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0; + tmpl->mode = mode2kernel(proto_mode); + tmpl->optional = protos[i].proto == IPPROTO_COMP && + policy->direction != POLICY_OUT; + tmpl->family = ipsec->src->get_family(ipsec->src); + + if (proto_mode == MODE_TUNNEL || proto_mode == MODE_BEET) + { /* only for tunnel mode */ + host2xfrm(ipsec->src, &tmpl->saddr); + host2xfrm(ipsec->dst, &tmpl->id.daddr); + } + + tmpl++; + + /* use transport mode for other SAs */ + proto_mode = MODE_TRANSPORT; + } + } + + if (!add_mark(hdr, sizeof(request), ipsec->mark)) + { + this->mutex->unlock(this->mutex); + return FAILED; + } + this->mutex->unlock(this->mutex); + + status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr); + if (status == ALREADY_DONE && !update) + { + DBG1(DBG_KNL, "policy already exists, try to update it"); + hdr->nlmsg_type = XFRM_MSG_UPDPOLICY; + status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr); + } + if (status != SUCCESS) + { + return FAILED; + } + + /* find the policy again */ + this->mutex->lock(this->mutex); + policy = this->policies->get(this->policies, &clone); + if (!policy || + policy->used_by->find_first(policy->used_by, + NULL, (void**)&mapping) != SUCCESS) + { /* policy or mapping is already gone, ignore */ + this->mutex->unlock(this->mutex); + return SUCCESS; + } + + /* install a route, if: + * - this is a forward policy (to just get one for each child) + * - we are in tunnel/BEET mode or install a bypass policy + * - routing is not disabled via strongswan.conf + */ + if (policy->direction == POLICY_FWD && this->install_routes && + (mapping->type != POLICY_IPSEC || ipsec->cfg.mode != MODE_TRANSPORT)) + { + policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)mapping; + route_entry_t *route; + host_t *iface; + + INIT(route, + .prefixlen = policy->sel.prefixlen_s, + ); + + if (charon->kernel->get_address_by_ts(charon->kernel, fwd->dst_ts, + &route->src_ip, NULL) == SUCCESS) + { + /* get the nexthop to src (src as we are in POLICY_FWD) */ + if (!ipsec->src->is_anyaddr(ipsec->src)) + { + route->gateway = charon->kernel->get_nexthop(charon->kernel, + ipsec->src, -1, ipsec->dst); + } + else + { /* for shunt policies */ + iface = xfrm2host(policy->sel.family, &policy->sel.saddr, 0); + route->gateway = charon->kernel->get_nexthop(charon->kernel, + iface, policy->sel.prefixlen_s, + route->src_ip); + iface->destroy(iface); + } + route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16); + memcpy(route->dst_net.ptr, &policy->sel.saddr, route->dst_net.len); + + /* get the interface to install the route for. If we have a local + * address, use it. Otherwise (for shunt policies) use the + * routes source address. */ + iface = ipsec->dst; + if (iface->is_anyaddr(iface)) + { + iface = route->src_ip; + } + /* install route via outgoing interface */ + if (!charon->kernel->get_interface(charon->kernel, iface, + &route->if_name)) + { + this->mutex->unlock(this->mutex); + route_entry_destroy(route); + return SUCCESS; + } + + if (policy->route) + { + route_entry_t *old = policy->route; + if (route_entry_equals(old, route)) + { + this->mutex->unlock(this->mutex); + route_entry_destroy(route); + return SUCCESS; + } + /* uninstall previously installed route */ + if (charon->kernel->del_route(charon->kernel, old->dst_net, + old->prefixlen, old->gateway, + old->src_ip, old->if_name) != SUCCESS) + { + DBG1(DBG_KNL, "error uninstalling route installed with " + "policy %R === %R %N", fwd->src_ts, + fwd->dst_ts, policy_dir_names, + policy->direction); + } + route_entry_destroy(old); + policy->route = NULL; + } + + DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s", + fwd->src_ts, route->gateway, route->src_ip, route->if_name); + switch (charon->kernel->add_route(charon->kernel, route->dst_net, + route->prefixlen, route->gateway, + route->src_ip, route->if_name)) + { + default: + DBG1(DBG_KNL, "unable to install source route for %H", + route->src_ip); + /* FALL */ + case ALREADY_DONE: + /* route exists, do not uninstall */ + route_entry_destroy(route); + break; + case SUCCESS: + /* cache the installed route */ + policy->route = route; + break; + } + } + else + { + free(route); + } + } + this->mutex->unlock(this->mutex); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, add_policy, status_t, + private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, + mark_t mark, policy_priority_t priority) +{ + policy_entry_t *policy, *current; + policy_sa_t *assigned_sa, *current_sa; + enumerator_t *enumerator; + bool found = FALSE, update = TRUE; + + /* create a policy */ + INIT(policy, + .sel = ts2selector(src_ts, dst_ts), + .mark = mark.value & mark.mask, + .direction = direction, + .reqid = sa->reqid, + ); + + /* find the policy, which matches EXACTLY */ + this->mutex->lock(this->mutex); + current = this->policies->get(this->policies, policy); + if (current) + { + if (current->reqid && sa->reqid && current->reqid != sa->reqid) + { + DBG1(DBG_CFG, "unable to install policy %R === %R %N (mark " + "%u/0x%08x) for reqid %u, the same policy for reqid %u exists", + src_ts, dst_ts, policy_dir_names, direction, + mark.value, mark.mask, sa->reqid, current->reqid); + policy_entry_destroy(this, policy); + this->mutex->unlock(this->mutex); + return INVALID_STATE; + } + /* use existing policy */ + DBG2(DBG_KNL, "policy %R === %R %N (mark %u/0x%08x) " + "already exists, increasing refcount", + src_ts, dst_ts, policy_dir_names, direction, + mark.value, mark.mask); + policy_entry_destroy(this, policy); + policy = current; + found = TRUE; + } + else + { /* use the new one, if we have no such policy */ + policy->used_by = linked_list_create(); + this->policies->put(this->policies, policy, policy); + } + + /* cache the assigned IPsec SA */ + assigned_sa = policy_sa_create(this, direction, type, src, dst, src_ts, + dst_ts, mark, sa); + assigned_sa->priority = get_priority(policy, priority); + + /* insert the SA according to its priority */ + enumerator = policy->used_by->create_enumerator(policy->used_by); + while (enumerator->enumerate(enumerator, (void**)¤t_sa)) + { + if (current_sa->priority >= assigned_sa->priority) + { + break; + } + update = FALSE; + } + policy->used_by->insert_before(policy->used_by, enumerator, + assigned_sa); + enumerator->destroy(enumerator); + + if (!update) + { /* we don't update the policy if the priority is lower than that of + * the currently installed one */ + this->mutex->unlock(this->mutex); + return SUCCESS; + } + + if (this->policy_update) + { + found = TRUE; + } + + DBG2(DBG_KNL, "%s policy %R === %R %N (mark %u/0x%08x)", + found ? "updating" : "adding", src_ts, dst_ts, + policy_dir_names, direction, mark.value, mark.mask); + + if (add_policy_internal(this, policy, assigned_sa, found) != SUCCESS) + { + DBG1(DBG_KNL, "unable to %s policy %R === %R %N", + found ? "update" : "add", src_ts, dst_ts, + policy_dir_names, direction); + return FAILED; + } + return SUCCESS; +} + +METHOD(kernel_ipsec_t, query_policy, status_t, + private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, + time_t *use_time) +{ + netlink_buf_t request; + struct nlmsghdr *out = NULL, *hdr; + struct xfrm_userpolicy_id *policy_id; + struct xfrm_userpolicy_info *policy = NULL; + size_t len; + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "querying policy %R === %R %N (mark %u/0x%08x)", + src_ts, dst_ts, policy_dir_names, direction, + mark.value, mark.mask); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST; + hdr->nlmsg_type = XFRM_MSG_GETPOLICY; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)); + + policy_id = NLMSG_DATA(hdr); + policy_id->sel = ts2selector(src_ts, dst_ts); + policy_id->dir = direction; + + if (!add_mark(hdr, sizeof(request), mark)) + { + return FAILED; + } + + if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS) + { + hdr = out; + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case XFRM_MSG_NEWPOLICY: + { + policy = NLMSG_DATA(hdr); + break; + } + case NLMSG_ERROR: + { + struct nlmsgerr *err = NLMSG_DATA(hdr); + DBG1(DBG_KNL, "querying policy failed: %s (%d)", + strerror(-err->error), -err->error); + break; + } + default: + hdr = NLMSG_NEXT(hdr, len); + continue; + case NLMSG_DONE: + break; + } + break; + } + } + + if (policy == NULL) + { + DBG2(DBG_KNL, "unable to query policy %R === %R %N", src_ts, dst_ts, + policy_dir_names, direction); + free(out); + return FAILED; + } + + if (policy->curlft.use_time) + { + /* we need the monotonic time, but the kernel returns system time. */ + *use_time = time_monotonic(NULL) - (time(NULL) - policy->curlft.use_time); + } + else + { + *use_time = 0; + } + + free(out); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, del_policy, status_t, + private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, + mark_t mark, policy_priority_t prio) +{ + policy_entry_t *current, policy; + enumerator_t *enumerator; + policy_sa_t *mapping; + netlink_buf_t request; + struct nlmsghdr *hdr; + struct xfrm_userpolicy_id *policy_id; + bool is_installed = TRUE; + u_int32_t priority; + ipsec_sa_t assigned_sa = { + .src = src, + .dst = dst, + .mark = mark, + .cfg = *sa, + }; + + DBG2(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%08x)", + src_ts, dst_ts, policy_dir_names, direction, + mark.value, mark.mask); + + /* create a policy */ + memset(&policy, 0, sizeof(policy_entry_t)); + policy.sel = ts2selector(src_ts, dst_ts); + policy.mark = mark.value & mark.mask; + policy.direction = direction; + + /* find the policy */ + this->mutex->lock(this->mutex); + current = this->policies->get(this->policies, &policy); + if (!current) + { + if (mark.value) + { + DBG1(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%08x) " + "failed, not found", src_ts, dst_ts, policy_dir_names, + direction, mark.value, mark.mask); + } + else + { + DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", + src_ts, dst_ts, policy_dir_names, direction); + } + this->mutex->unlock(this->mutex); + return NOT_FOUND; + } + + /* remove mapping to SA by reqid and priority */ + priority = get_priority(current, prio); + enumerator = current->used_by->create_enumerator(current->used_by); + while (enumerator->enumerate(enumerator, (void**)&mapping)) + { + if (priority == mapping->priority && type == mapping->type && + ipsec_sa_equals(mapping->sa, &assigned_sa)) + { + current->used_by->remove_at(current->used_by, enumerator); + policy_sa_destroy(mapping, &direction, this); + break; + } + is_installed = FALSE; + } + enumerator->destroy(enumerator); + + if (current->used_by->get_count(current->used_by) > 0) + { /* policy is used by more SAs, keep in kernel */ + DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed"); + if (!is_installed) + { /* no need to update as the policy was not installed for this SA */ + this->mutex->unlock(this->mutex); + return SUCCESS; + } + + DBG2(DBG_KNL, "updating policy %R === %R %N (mark %u/0x%08x)", + src_ts, dst_ts, policy_dir_names, direction, + mark.value, mark.mask); + + current->used_by->get_first(current->used_by, (void**)&mapping); + if (add_policy_internal(this, current, mapping, TRUE) != SUCCESS) + { + DBG1(DBG_KNL, "unable to update policy %R === %R %N", + src_ts, dst_ts, policy_dir_names, direction); + return FAILED; + } + return SUCCESS; + } + + memset(&request, 0, sizeof(request)); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = XFRM_MSG_DELPOLICY; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)); + + policy_id = NLMSG_DATA(hdr); + policy_id->sel = current->sel; + policy_id->dir = direction; + + if (!add_mark(hdr, sizeof(request), mark)) + { + this->mutex->unlock(this->mutex); + return FAILED; + } + + if (current->route) + { + route_entry_t *route = current->route; + if (charon->kernel->del_route(charon->kernel, route->dst_net, + route->prefixlen, route->gateway, + route->src_ip, route->if_name) != SUCCESS) + { + DBG1(DBG_KNL, "error uninstalling route installed with " + "policy %R === %R %N", src_ts, dst_ts, + policy_dir_names, direction); + } + } + + this->policies->remove(this->policies, current); + policy_entry_destroy(this, current); + this->mutex->unlock(this->mutex); + + if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) + { + if (mark.value) + { + DBG1(DBG_KNL, "unable to delete policy %R === %R %N " + "(mark %u/0x%08x)", src_ts, dst_ts, policy_dir_names, + direction, mark.value, mark.mask); + } + else + { + DBG1(DBG_KNL, "unable to delete policy %R === %R %N", + src_ts, dst_ts, policy_dir_names, direction); + } + return FAILED; + } + return SUCCESS; +} + +METHOD(kernel_ipsec_t, flush_policies, status_t, + private_kernel_netlink_ipsec_t *this) +{ + netlink_buf_t request; + struct nlmsghdr *hdr; + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "flushing all policies from SPD"); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = XFRM_MSG_FLUSHPOLICY; + hdr->nlmsg_len = NLMSG_LENGTH(0); /* no data associated */ + + /* by adding an rtattr of type XFRMA_POLICY_TYPE we could restrict this + * to main or sub policies (default is main) */ + + if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) + { + DBG1(DBG_KNL, "unable to flush SPD entries"); + return FAILED; + } + return SUCCESS; +} + +/** + * Bypass socket using a per-socket policy + */ +static bool add_socket_bypass(private_kernel_netlink_ipsec_t *this, + int fd, int family) +{ + struct xfrm_userpolicy_info policy; + u_int sol, ipsec_policy; + + switch (family) + { + case AF_INET: + sol = SOL_IP; + ipsec_policy = IP_XFRM_POLICY; + break; + case AF_INET6: + sol = SOL_IPV6; + ipsec_policy = IPV6_XFRM_POLICY; + break; + default: + return FALSE; + } + + memset(&policy, 0, sizeof(policy)); + policy.action = XFRM_POLICY_ALLOW; + policy.sel.family = family; + + policy.dir = XFRM_POLICY_OUT; + if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) + { + DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s", + strerror(errno)); + return FALSE; + } + policy.dir = XFRM_POLICY_IN; + if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) + { + DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s", + strerror(errno)); + return FALSE; + } + return TRUE; +} + +/** + * Port based IKE bypass policy + */ +typedef struct { + /** address family */ + int family; + /** layer 4 protocol */ + int proto; + /** port number, network order */ + u_int16_t port; +} bypass_t; + +/** + * Add or remove a bypass policy from/to kernel + */ +static bool manage_bypass(private_kernel_netlink_ipsec_t *this, + int type, policy_dir_t dir, bypass_t *bypass) +{ + netlink_buf_t request; + struct xfrm_selector *sel; + struct nlmsghdr *hdr; + + memset(&request, 0, sizeof(request)); + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = type; + + if (type == XFRM_MSG_NEWPOLICY) + { + struct xfrm_userpolicy_info *policy; + + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)); + + policy = NLMSG_DATA(hdr); + policy->dir = dir; + policy->priority = 32; + policy->action = XFRM_POLICY_ALLOW; + policy->share = XFRM_SHARE_ANY; + + policy->lft.soft_byte_limit = XFRM_INF; + policy->lft.soft_packet_limit = XFRM_INF; + policy->lft.hard_byte_limit = XFRM_INF; + policy->lft.hard_packet_limit = XFRM_INF; + + sel = &policy->sel; + } + else /* XFRM_MSG_DELPOLICY */ + { + struct xfrm_userpolicy_id *policy; + + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)); + + policy = NLMSG_DATA(hdr); + policy->dir = dir; + + sel = &policy->sel; + } + + sel->family = bypass->family; + sel->proto = bypass->proto; + if (dir == POLICY_IN) + { + sel->dport = bypass->port; + sel->dport_mask = 0xffff; + } + else + { + sel->sport = bypass->port; + sel->sport_mask = 0xffff; + } + return this->socket_xfrm->send_ack(this->socket_xfrm, hdr) == SUCCESS; +} + +/** + * Bypass socket using a port-based bypass policy + */ +static bool add_port_bypass(private_kernel_netlink_ipsec_t *this, + int fd, int family) +{ + union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; + } saddr; + socklen_t len; + bypass_t bypass = { + .family = family, + }; + + len = sizeof(saddr); + if (getsockname(fd, &saddr.sa, &len) != 0) + { + return FALSE; + } +#ifdef SO_PROTOCOL /* since 2.6.32 */ + len = sizeof(bypass.proto); + if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &bypass.proto, &len) != 0) +#endif + { /* assume UDP if SO_PROTOCOL not supported */ + bypass.proto = IPPROTO_UDP; + } + switch (family) + { + case AF_INET: + bypass.port = saddr.in.sin_port; + break; + case AF_INET6: + bypass.port = saddr.in6.sin6_port; + break; + default: + return FALSE; + } + + if (!manage_bypass(this, XFRM_MSG_NEWPOLICY, POLICY_IN, &bypass)) + { + return FALSE; + } + if (!manage_bypass(this, XFRM_MSG_NEWPOLICY, POLICY_OUT, &bypass)) + { + manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_IN, &bypass); + return FALSE; + } + array_insert(this->bypass, ARRAY_TAIL, &bypass); + + return TRUE; +} + +/** + * Remove installed port based bypass policy + */ +static void remove_port_bypass(bypass_t *bypass, int idx, + private_kernel_netlink_ipsec_t *this) +{ + manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_OUT, bypass); + manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_IN, bypass); +} + +METHOD(kernel_ipsec_t, bypass_socket, bool, + private_kernel_netlink_ipsec_t *this, int fd, int family) +{ + if (lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.port_bypass", FALSE, lib->ns)) + { + return add_port_bypass(this, fd, family); + } + return add_socket_bypass(this, fd, family); +} + +METHOD(kernel_ipsec_t, enable_udp_decap, bool, + private_kernel_netlink_ipsec_t *this, int fd, int family, u_int16_t port) +{ + int type = UDP_ENCAP_ESPINUDP; + + if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) + { + DBG1(DBG_KNL, "unable to set UDP_ENCAP: %s", strerror(errno)); + return FALSE; + } + return TRUE; +} + +METHOD(kernel_ipsec_t, destroy, void, + private_kernel_netlink_ipsec_t *this) +{ + enumerator_t *enumerator; + policy_entry_t *policy; + + array_destroy_function(this->bypass, + (array_callback_t)remove_port_bypass, this); + if (this->socket_xfrm_events > 0) + { + lib->watcher->remove(lib->watcher, this->socket_xfrm_events); + close(this->socket_xfrm_events); + } + DESTROY_IF(this->socket_xfrm); + enumerator = this->policies->create_enumerator(this->policies); + while (enumerator->enumerate(enumerator, &policy, &policy)) + { + policy_entry_destroy(this, policy); + } + enumerator->destroy(enumerator); + this->policies->destroy(this->policies); + this->sas->destroy(this->sas); + this->mutex->destroy(this->mutex); + free(this); +} + +/* + * Described in header. + */ +kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() +{ + private_kernel_netlink_ipsec_t *this; + bool register_for_events = TRUE; + FILE *f; + + INIT(this, + .public = { + .interface = { + .get_features = _get_features, + .get_spi = _get_spi, + .get_cpi = _get_cpi, + .add_sa = _add_sa, + .update_sa = _update_sa, + .query_sa = _query_sa, + .del_sa = _del_sa, + .flush_sas = _flush_sas, + .add_policy = _add_policy, + .query_policy = _query_policy, + .del_policy = _del_policy, + .flush_policies = _flush_policies, + .bypass_socket = _bypass_socket, + .enable_udp_decap = _enable_udp_decap, + .destroy = _destroy, + }, + }, + .policies = hashtable_create((hashtable_hash_t)policy_hash, + (hashtable_equals_t)policy_equals, 32), + .sas = hashtable_create((hashtable_hash_t)ipsec_sa_hash, + (hashtable_equals_t)ipsec_sa_equals, 32), + .bypass = array_create(sizeof(bypass_t), 0), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .policy_update = lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.policy_update", FALSE, lib->ns), + .install_routes = lib->settings->get_bool(lib->settings, + "%s.install_routes", TRUE, lib->ns), + .proto_port_transport = lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.set_proto_port_transport_sa", + FALSE, lib->ns), + ); + + if (streq(lib->ns, "starter")) + { /* starter has no threads, so we do not register for kernel events */ + register_for_events = FALSE; + } + + f = fopen("/proc/sys/net/core/xfrm_acq_expires", "w"); + if (f) + { + fprintf(f, "%u", lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.xfrm_acq_expires", + DEFAULT_ACQUIRE_LIFETIME, lib->ns)); + fclose(f); + } + + this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names, + lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.parallel_xfrm", FALSE, lib->ns)); + if (!this->socket_xfrm) + { + destroy(this); + return NULL; + } + + if (register_for_events) + { + struct sockaddr_nl addr; + + memset(&addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + + /* create and bind XFRM socket for ACQUIRE, EXPIRE, MIGRATE & MAPPING */ + this->socket_xfrm_events = socket(AF_NETLINK, SOCK_RAW, NETLINK_XFRM); + if (this->socket_xfrm_events <= 0) + { + DBG1(DBG_KNL, "unable to create XFRM event socket"); + destroy(this); + return NULL; + } + addr.nl_groups = XFRMNLGRP(ACQUIRE) | XFRMNLGRP(EXPIRE) | + XFRMNLGRP(MIGRATE) | XFRMNLGRP(MAPPING); + if (bind(this->socket_xfrm_events, (struct sockaddr*)&addr, sizeof(addr))) + { + DBG1(DBG_KNL, "unable to bind XFRM event socket"); + destroy(this); + return NULL; + } + lib->watcher->add(lib->watcher, this->socket_xfrm_events, WATCHER_READ, + (watcher_cb_t)receive_events, this); + } + + return &this->public; +} diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h new file mode 100644 index 000000000..3a45cce06 --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_netlink_ipsec_i kernel_netlink_ipsec + * @{ @ingroup kernel_netlink + */ + +#ifndef KERNEL_NETLINK_IPSEC_H_ +#define KERNEL_NETLINK_IPSEC_H_ + +#include + +typedef struct kernel_netlink_ipsec_t kernel_netlink_ipsec_t; + +/** + * Implementation of the kernel ipsec interface using Netlink. + */ +struct kernel_netlink_ipsec_t { + + /** + * Implements kernel_ipsec_t interface + */ + kernel_ipsec_t interface; +}; + +/** + * Create a netlink kernel ipsec interface instance. + * + * @return kernel_netlink_ipsec_t instance + */ +kernel_netlink_ipsec_t *kernel_netlink_ipsec_create(); + +#endif /** KERNEL_NETLINK_IPSEC_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c new file mode 100644 index 000000000..f4394a14f --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -0,0 +1,2686 @@ +/* + * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2005-2008 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/* + * Copyright (C) 2010 secunet Security Networks AG + * Copyright (C) 2010 Thomas Egerer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LINUX_FIB_RULES_H +#include +#endif + +#include "kernel_netlink_net.h" +#include "kernel_netlink_shared.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** delay before firing roam events (ms) */ +#define ROAM_DELAY 100 + +/** delay before reinstalling routes (ms) */ +#define ROUTE_DELAY 100 + +/** maximum recursion when searching for addresses in get_route() */ +#define MAX_ROUTE_RECURSION 2 + +#ifndef ROUTING_TABLE +#define ROUTING_TABLE 0 +#endif + +#ifndef ROUTING_TABLE_PRIO +#define ROUTING_TABLE_PRIO 0 +#endif + +ENUM(rt_msg_names, RTM_NEWLINK, RTM_GETRULE, + "RTM_NEWLINK", + "RTM_DELLINK", + "RTM_GETLINK", + "RTM_SETLINK", + "RTM_NEWADDR", + "RTM_DELADDR", + "RTM_GETADDR", + "31", + "RTM_NEWROUTE", + "RTM_DELROUTE", + "RTM_GETROUTE", + "35", + "RTM_NEWNEIGH", + "RTM_DELNEIGH", + "RTM_GETNEIGH", + "RTM_NEWRULE", + "RTM_DELRULE", + "RTM_GETRULE", +); + +typedef struct addr_entry_t addr_entry_t; + +/** + * IP address in an iface_entry_t + */ +struct addr_entry_t { + + /** the ip address */ + host_t *ip; + + /** address flags */ + u_char flags; + + /** scope of the address */ + u_char scope; + + /** number of times this IP is used, if virtual (i.e. managed by us) */ + u_int refcount; + + /** TRUE once it is installed, if virtual */ + bool installed; +}; + +/** + * destroy a addr_entry_t object + */ +static void addr_entry_destroy(addr_entry_t *this) +{ + this->ip->destroy(this->ip); + free(this); +} + +typedef struct iface_entry_t iface_entry_t; + +/** + * A network interface on this system, containing addr_entry_t's + */ +struct iface_entry_t { + + /** interface index */ + int ifindex; + + /** name of the interface */ + char ifname[IFNAMSIZ]; + + /** interface flags, as in netdevice(7) SIOCGIFFLAGS */ + u_int flags; + + /** list of addresses as host_t */ + linked_list_t *addrs; + + /** TRUE if usable by config */ + bool usable; +}; + +/** + * destroy an interface entry + */ +static void iface_entry_destroy(iface_entry_t *this) +{ + this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy); + free(this); +} + +/** + * find an interface entry by index + */ +static bool iface_entry_by_index(iface_entry_t *this, int *ifindex) +{ + return this->ifindex == *ifindex; +} + +/** + * find an interface entry by name + */ +static bool iface_entry_by_name(iface_entry_t *this, char *ifname) +{ + return streq(this->ifname, ifname); +} + +/** + * check if an interface is up + */ +static inline bool iface_entry_up(iface_entry_t *iface) +{ + return (iface->flags & IFF_UP) == IFF_UP; +} + +/** + * check if an interface is up and usable + */ +static inline bool iface_entry_up_and_usable(iface_entry_t *iface) +{ + return iface->usable && iface_entry_up(iface); +} + +typedef struct addr_map_entry_t addr_map_entry_t; + +/** + * Entry that maps an IP address to an interface entry + */ +struct addr_map_entry_t { + /** The IP address */ + host_t *ip; + + /** The address entry for this IP address */ + addr_entry_t *addr; + + /** The interface this address is installed on */ + iface_entry_t *iface; +}; + +/** + * Hash a addr_map_entry_t object, all entries with the same IP address + * are stored in the same bucket + */ +static u_int addr_map_entry_hash(addr_map_entry_t *this) +{ + return chunk_hash(this->ip->get_address(this->ip)); +} + +/** + * Compare two addr_map_entry_t objects, two entries are equal if they are + * installed on the same interface + */ +static bool addr_map_entry_equals(addr_map_entry_t *a, addr_map_entry_t *b) +{ + return a->iface->ifindex == b->iface->ifindex && + a->ip->ip_equals(a->ip, b->ip); +} + +/** + * Used with get_match this finds an address entry if it is installed on + * an up and usable interface + */ +static bool addr_map_entry_match_up_and_usable(addr_map_entry_t *a, + addr_map_entry_t *b) +{ + return iface_entry_up_and_usable(b->iface) && + a->ip->ip_equals(a->ip, b->ip); +} + +/** + * Used with get_match this finds an address entry if it is installed on + * any active local interface + */ +static bool addr_map_entry_match_up(addr_map_entry_t *a, addr_map_entry_t *b) +{ + return iface_entry_up(b->iface) && a->ip->ip_equals(a->ip, b->ip); +} + +/** + * Used with get_match this finds an address entry if it is installed on + * any local interface + */ +static bool addr_map_entry_match(addr_map_entry_t *a, addr_map_entry_t *b) +{ + return a->ip->ip_equals(a->ip, b->ip); +} + +typedef struct route_entry_t route_entry_t; + +/** + * Installed routing entry + */ +struct route_entry_t { + /** Name of the interface the route is bound to */ + char *if_name; + + /** Source ip of the route */ + host_t *src_ip; + + /** Gateway for this route */ + host_t *gateway; + + /** Destination net */ + chunk_t dst_net; + + /** Destination net prefixlen */ + u_int8_t prefixlen; +}; + +/** + * Clone a route_entry_t object. + */ +static route_entry_t *route_entry_clone(route_entry_t *this) +{ + route_entry_t *route; + + INIT(route, + .if_name = strdup(this->if_name), + .src_ip = this->src_ip->clone(this->src_ip), + .gateway = this->gateway ? this->gateway->clone(this->gateway) : NULL, + .dst_net = chunk_clone(this->dst_net), + .prefixlen = this->prefixlen, + ); + return route; +} + +/** + * Destroy a route_entry_t object + */ +static void route_entry_destroy(route_entry_t *this) +{ + free(this->if_name); + DESTROY_IF(this->src_ip); + DESTROY_IF(this->gateway); + chunk_free(&this->dst_net); + free(this); +} + +/** + * Hash a route_entry_t object + */ +static u_int route_entry_hash(route_entry_t *this) +{ + return chunk_hash_inc(chunk_from_thing(this->prefixlen), + chunk_hash(this->dst_net)); +} + +/** + * Compare two route_entry_t objects + */ +static bool route_entry_equals(route_entry_t *a, route_entry_t *b) +{ + if (a->if_name && b->if_name && streq(a->if_name, b->if_name) && + a->src_ip->ip_equals(a->src_ip, b->src_ip) && + chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen) + { + return (!a->gateway && !b->gateway) || (a->gateway && b->gateway && + a->gateway->ip_equals(a->gateway, b->gateway)); + } + return FALSE; +} + +typedef struct net_change_t net_change_t; + +/** + * Queued network changes + */ +struct net_change_t { + /** Name of the interface that got activated (or an IP appeared on) */ + char *if_name; +}; + +/** + * Destroy a net_change_t object + */ +static void net_change_destroy(net_change_t *this) +{ + free(this->if_name); + free(this); +} + +/** + * Hash a net_change_t object + */ +static u_int net_change_hash(net_change_t *this) +{ + return chunk_hash(chunk_create(this->if_name, strlen(this->if_name))); +} + +/** + * Compare two net_change_t objects + */ +static bool net_change_equals(net_change_t *a, net_change_t *b) +{ + return streq(a->if_name, b->if_name); +} + +typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t; + +/** + * Private variables and functions of kernel_netlink_net class. + */ +struct private_kernel_netlink_net_t { + /** + * Public part of the kernel_netlink_net_t object. + */ + kernel_netlink_net_t public; + + /** + * lock to access various lists and maps + */ + rwlock_t *lock; + + /** + * condition variable to signal virtual IP add/removal + */ + rwlock_condvar_t *condvar; + + /** + * Cached list of interfaces and its addresses (iface_entry_t) + */ + linked_list_t *ifaces; + + /** + * Map for IP addresses to iface_entry_t objects (addr_map_entry_t) + */ + hashtable_t *addrs; + + /** + * Map for virtual IP addresses to iface_entry_t objects (addr_map_entry_t) + */ + hashtable_t *vips; + + /** + * netlink rt socket (routing) + */ + netlink_socket_t *socket; + + /** + * Netlink rt socket to receive address change events + */ + int socket_events; + + /** + * earliest time of the next roam event + */ + timeval_t next_roam; + + /** + * roam event due to address change + */ + bool roam_address; + + /** + * lock to check and update roam event time + */ + spinlock_t *roam_lock; + + /** + * routing table to install routes + */ + int routing_table; + + /** + * priority of used routing table + */ + int routing_table_prio; + + /** + * installed routes + */ + hashtable_t *routes; + + /** + * mutex for routes + */ + mutex_t *routes_lock; + + /** + * interface changes which may trigger route reinstallation + */ + hashtable_t *net_changes; + + /** + * mutex for route reinstallation triggers + */ + mutex_t *net_changes_lock; + + /** + * time of last route reinstallation + */ + timeval_t last_route_reinstall; + + /** + * whether to react to RTM_NEWROUTE or RTM_DELROUTE events + */ + bool process_route; + + /** + * whether to trigger roam events + */ + bool roam_events; + + /** + * whether to actually install virtual IPs + */ + bool install_virtual_ip; + + /** + * the name of the interface virtual IP addresses are installed on + */ + char *install_virtual_ip_on; + + /** + * whether preferred source addresses can be specified for IPv6 routes + */ + bool rta_prefsrc_for_ipv6; + + /** + * whether marks can be used in route lookups + */ + bool rta_mark; + + /** + * the mark excluded from the routing rule used for virtual IPs + */ + mark_t routing_mark; + + /** + * whether to prefer temporary IPv6 addresses over public ones + */ + bool prefer_temporary_addrs; + + /** + * list with routing tables to be excluded from route lookup + */ + linked_list_t *rt_exclude; + + /** + * MTU to set on installed routes + */ + u_int32_t mtu; + + /** + * MSS to set on installed routes + */ + u_int32_t mss; +}; + +/** + * Forward declaration + */ +static status_t manage_srcroute(private_kernel_netlink_net_t *this, + int nlmsg_type, int flags, chunk_t dst_net, + u_int8_t prefixlen, host_t *gateway, + host_t *src_ip, char *if_name); + +/** + * Clear the queued network changes. + */ +static void net_changes_clear(private_kernel_netlink_net_t *this) +{ + enumerator_t *enumerator; + net_change_t *change; + + enumerator = this->net_changes->create_enumerator(this->net_changes); + while (enumerator->enumerate(enumerator, NULL, (void**)&change)) + { + this->net_changes->remove_at(this->net_changes, enumerator); + net_change_destroy(change); + } + enumerator->destroy(enumerator); +} + +/** + * Act upon queued network changes. + */ +static job_requeue_t reinstall_routes(private_kernel_netlink_net_t *this) +{ + enumerator_t *enumerator; + route_entry_t *route; + + this->net_changes_lock->lock(this->net_changes_lock); + this->routes_lock->lock(this->routes_lock); + + enumerator = this->routes->create_enumerator(this->routes); + while (enumerator->enumerate(enumerator, NULL, (void**)&route)) + { + net_change_t *change, lookup = { + .if_name = route->if_name, + }; + /* check if a change for the outgoing interface is queued */ + change = this->net_changes->get(this->net_changes, &lookup); + if (!change) + { /* in case src_ip is not on the outgoing interface */ + if (this->public.interface.get_interface(&this->public.interface, + route->src_ip, &lookup.if_name)) + { + if (!streq(lookup.if_name, route->if_name)) + { + change = this->net_changes->get(this->net_changes, &lookup); + } + free(lookup.if_name); + } + } + if (change) + { + manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, + route->dst_net, route->prefixlen, route->gateway, + route->src_ip, route->if_name); + } + } + enumerator->destroy(enumerator); + this->routes_lock->unlock(this->routes_lock); + + net_changes_clear(this); + this->net_changes_lock->unlock(this->net_changes_lock); + return JOB_REQUEUE_NONE; +} + +/** + * Queue route reinstallation caused by network changes for a given interface. + * + * The route reinstallation is delayed for a while and only done once for + * several calls during this delay, in order to avoid doing it too often. + * The interface name is freed. + */ +static void queue_route_reinstall(private_kernel_netlink_net_t *this, + char *if_name) +{ + net_change_t *update, *found; + timeval_t now; + job_t *job; + + INIT(update, + .if_name = if_name + ); + + this->net_changes_lock->lock(this->net_changes_lock); + found = this->net_changes->put(this->net_changes, update, update); + if (found) + { + net_change_destroy(found); + } + time_monotonic(&now); + if (timercmp(&now, &this->last_route_reinstall, >)) + { + timeval_add_ms(&now, ROUTE_DELAY); + this->last_route_reinstall = now; + + job = (job_t*)callback_job_create((callback_job_cb_t)reinstall_routes, + this, NULL, NULL); + lib->scheduler->schedule_job_ms(lib->scheduler, job, ROUTE_DELAY); + } + this->net_changes_lock->unlock(this->net_changes_lock); +} + +/** + * check if the given IP is known as virtual IP and currently installed + * + * this function will also return TRUE if the virtual IP entry disappeared. + * in that case the returned entry will be NULL. + * + * this->lock must be held when calling this function + */ +static bool is_vip_installed_or_gone(private_kernel_netlink_net_t *this, + host_t *ip, addr_map_entry_t **entry) +{ + addr_map_entry_t lookup = { + .ip = ip, + }; + + *entry = this->vips->get_match(this->vips, &lookup, + (void*)addr_map_entry_match); + if (*entry == NULL) + { /* the virtual IP disappeared */ + return TRUE; + } + return (*entry)->addr->installed; +} + +/** + * check if the given IP is known as virtual IP + * + * this->lock must be held when calling this function + */ +static bool is_known_vip(private_kernel_netlink_net_t *this, host_t *ip) +{ + addr_map_entry_t lookup = { + .ip = ip, + }; + + return this->vips->get_match(this->vips, &lookup, + (void*)addr_map_entry_match) != NULL; +} + +/** + * Add an address map entry + */ +static void addr_map_entry_add(hashtable_t *map, addr_entry_t *addr, + iface_entry_t *iface) +{ + addr_map_entry_t *entry; + + INIT(entry, + .ip = addr->ip, + .addr = addr, + .iface = iface, + ); + entry = map->put(map, entry, entry); + free(entry); +} + +/** + * Remove an address map entry + */ +static void addr_map_entry_remove(hashtable_t *map, addr_entry_t *addr, + iface_entry_t *iface) +{ + addr_map_entry_t *entry, lookup = { + .ip = addr->ip, + .addr = addr, + .iface = iface, + }; + + entry = map->remove(map, &lookup); + free(entry); +} + +/** + * Determine the type or scope of the given unicast IP address. This is not + * the same thing returned in rtm_scope/ifa_scope. + * + * We use return values as defined in RFC 6724 (referring to RFC 4291). + */ +static u_char get_scope(host_t *ip) +{ + chunk_t addr; + + addr = ip->get_address(ip); + switch (addr.len) + { + case 4: + /* we use the mapping defined in RFC 6724, 3.2 */ + if (addr.ptr[0] == 127) + { /* link-local, same as the IPv6 loopback address */ + return 2; + } + if (addr.ptr[0] == 169 && addr.ptr[1] == 254) + { /* link-local */ + return 2; + } + break; + case 16: + if (IN6_IS_ADDR_LOOPBACK((struct in6_addr*)addr.ptr)) + { /* link-local, according to RFC 4291, 2.5.3 */ + return 2; + } + if (IN6_IS_ADDR_LINKLOCAL((struct in6_addr*)addr.ptr)) + { + return 2; + } + if (IN6_IS_ADDR_SITELOCAL((struct in6_addr*)addr.ptr)) + { /* deprecated, according to RFC 4291, 2.5.7 */ + return 5; + } + break; + default: + break; + } + /* global */ + return 14; +} + +/** + * Returns the length of the common prefix in bits up to the length of a's + * prefix, defined by RFC 6724 as the portion of the address not including the + * interface ID, which is 64-bit for most unicast addresses (see RFC 4291). + */ +static u_char common_prefix(host_t *a, host_t *b) +{ + chunk_t aa, ba; + u_char byte, bits = 0, match; + + aa = a->get_address(a); + ba = b->get_address(b); + for (byte = 0; byte < 8; byte++) + { + if (aa.ptr[byte] != ba.ptr[byte]) + { + match = aa.ptr[byte] ^ ba.ptr[byte]; + for (bits = 8; match; match >>= 1) + { + bits--; + } + break; + } + } + return byte * 8 + bits; +} + +/** + * Compare two IP addresses and return TRUE if the second address is the better + * choice of the two to reach the destination. + * For IPv6 we approximately follow RFC 6724. + */ +static bool is_address_better(private_kernel_netlink_net_t *this, + addr_entry_t *a, addr_entry_t *b, host_t *d) +{ + u_char sa, sb, sd, pa, pb; + + /* rule 2: prefer appropriate scope */ + if (d) + { + sa = get_scope(a->ip); + sb = get_scope(b->ip); + sd = get_scope(d); + if (sa < sb) + { + return sa < sd; + } + else if (sb < sa) + { + return sb >= sd; + } + } + if (a->ip->get_family(a->ip) == AF_INET) + { /* stop here for IPv4, default to addresses found earlier */ + return FALSE; + } + /* rule 3: avoid deprecated addresses (RFC 4862) */ + if ((a->flags & IFA_F_DEPRECATED) != (b->flags & IFA_F_DEPRECATED)) + { + return a->flags & IFA_F_DEPRECATED; + } + /* rule 4 is not applicable as we don't know if an address is a home or + * care-of addresses. + * rule 5 does not apply as we only compare addresses from one interface + * rule 6 requires a policy table (optionally configurable) to match + * configurable labels + */ + /* rule 7: prefer temporary addresses (WE REVERSE THIS BY DEFAULT!) */ + if ((a->flags & IFA_F_TEMPORARY) != (b->flags & IFA_F_TEMPORARY)) + { + if (this->prefer_temporary_addrs) + { + return b->flags & IFA_F_TEMPORARY; + } + return a->flags & IFA_F_TEMPORARY; + } + /* rule 8: use longest matching prefix */ + if (d) + { + pa = common_prefix(a->ip, d); + pb = common_prefix(b->ip, d); + if (pa != pb) + { + return pb > pa; + } + } + /* default to addresses found earlier */ + return FALSE; +} + +/** + * Get a non-virtual IP address on the given interface. + * + * If a candidate address is given, we first search for that address and if not + * found return the address as above. + * Returned host is a clone, has to be freed by caller. + * + * this->lock must be held when calling this function. + */ +static host_t *get_interface_address(private_kernel_netlink_net_t *this, + int ifindex, int family, host_t *dest, + host_t *candidate) +{ + iface_entry_t *iface; + enumerator_t *addrs; + addr_entry_t *addr, *best = NULL; + + if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, + (void**)&iface, &ifindex) == SUCCESS) + { + if (iface->usable) + { /* only use interfaces not excluded by config */ + addrs = iface->addrs->create_enumerator(iface->addrs); + while (addrs->enumerate(addrs, &addr)) + { + if (addr->refcount || + addr->ip->get_family(addr->ip) != family) + { /* ignore virtual IP addresses and ensure family matches */ + continue; + } + if (candidate && candidate->ip_equals(candidate, addr->ip)) + { /* stop if we find the candidate */ + best = addr; + break; + } + else if (!best || is_address_better(this, best, addr, dest)) + { + best = addr; + } + } + addrs->destroy(addrs); + } + } + return best ? best->ip->clone(best->ip) : NULL; +} + +/** + * callback function that raises the delayed roam event + */ +static job_requeue_t roam_event(private_kernel_netlink_net_t *this) +{ + bool address; + + this->roam_lock->lock(this->roam_lock); + address = this->roam_address; + this->roam_address = FALSE; + this->roam_lock->unlock(this->roam_lock); + charon->kernel->roam(charon->kernel, address); + return JOB_REQUEUE_NONE; +} + +/** + * fire a roaming event. we delay it for a bit and fire only one event + * for multiple calls. otherwise we would create too many events. + */ +static void fire_roam_event(private_kernel_netlink_net_t *this, bool address) +{ + timeval_t now; + job_t *job; + + if (!this->roam_events) + { + return; + } + + time_monotonic(&now); + this->roam_lock->lock(this->roam_lock); + this->roam_address |= address; + if (!timercmp(&now, &this->next_roam, >)) + { + this->roam_lock->unlock(this->roam_lock); + return; + } + timeval_add_ms(&now, ROAM_DELAY); + this->next_roam = now; + this->roam_lock->unlock(this->roam_lock); + + job = (job_t*)callback_job_create((callback_job_cb_t)roam_event, + this, NULL, NULL); + lib->scheduler->schedule_job_ms(lib->scheduler, job, ROAM_DELAY); +} + +/** + * check if an interface with a given index is up and usable + * + * this->lock must be locked when calling this function + */ +static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this, + int index) +{ + iface_entry_t *iface; + + if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, + (void**)&iface, &index) == SUCCESS) + { + return iface_entry_up_and_usable(iface); + } + return FALSE; +} + +/** + * unregister the current addr_entry_t from the hashtable it is stored in + * + * this->lock must be locked when calling this function + */ +static void addr_entry_unregister(addr_entry_t *addr, iface_entry_t *iface, + private_kernel_netlink_net_t *this) +{ + if (addr->refcount) + { + addr_map_entry_remove(this->vips, addr, iface); + this->condvar->broadcast(this->condvar); + return; + } + addr_map_entry_remove(this->addrs, addr, iface); +} + +/** + * process RTM_NEWLINK/RTM_DELLINK from kernel + */ +static void process_link(private_kernel_netlink_net_t *this, + struct nlmsghdr *hdr, bool event) +{ + struct ifinfomsg* msg = NLMSG_DATA(hdr); + struct rtattr *rta = IFLA_RTA(msg); + size_t rtasize = IFLA_PAYLOAD (hdr); + enumerator_t *enumerator; + iface_entry_t *current, *entry = NULL; + char *name = NULL; + bool update = FALSE, update_routes = FALSE; + + while (RTA_OK(rta, rtasize)) + { + switch (rta->rta_type) + { + case IFLA_IFNAME: + name = RTA_DATA(rta); + break; + } + rta = RTA_NEXT(rta, rtasize); + } + if (!name) + { + name = "(unknown)"; + } + + this->lock->write_lock(this->lock); + switch (hdr->nlmsg_type) + { + case RTM_NEWLINK: + { + if (this->ifaces->find_first(this->ifaces, + (void*)iface_entry_by_index, (void**)&entry, + &msg->ifi_index) != SUCCESS) + { + INIT(entry, + .ifindex = msg->ifi_index, + .addrs = linked_list_create(), + .usable = charon->kernel->is_interface_usable( + charon->kernel, name), + ); + this->ifaces->insert_last(this->ifaces, entry); + } + strncpy(entry->ifname, name, IFNAMSIZ); + entry->ifname[IFNAMSIZ-1] = '\0'; + if (event && entry->usable) + { + if (!(entry->flags & IFF_UP) && (msg->ifi_flags & IFF_UP)) + { + update = update_routes = TRUE; + DBG1(DBG_KNL, "interface %s activated", name); + } + if ((entry->flags & IFF_UP) && !(msg->ifi_flags & IFF_UP)) + { + update = TRUE; + DBG1(DBG_KNL, "interface %s deactivated", name); + } + } + entry->flags = msg->ifi_flags; + break; + } + case RTM_DELLINK: + { + enumerator = this->ifaces->create_enumerator(this->ifaces); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (current->ifindex == msg->ifi_index) + { + if (event && current->usable) + { + update = TRUE; + DBG1(DBG_KNL, "interface %s deleted", current->ifname); + } + /* TODO: move virtual IPs installed on this interface to + * another interface? */ + this->ifaces->remove_at(this->ifaces, enumerator); + current->addrs->invoke_function(current->addrs, + (void*)addr_entry_unregister, current, this); + iface_entry_destroy(current); + break; + } + } + enumerator->destroy(enumerator); + break; + } + } + this->lock->unlock(this->lock); + + if (update_routes && event) + { + queue_route_reinstall(this, strdup(name)); + } + + if (update && event) + { + fire_roam_event(this, TRUE); + } +} + +/** + * process RTM_NEWADDR/RTM_DELADDR from kernel + */ +static void process_addr(private_kernel_netlink_net_t *this, + struct nlmsghdr *hdr, bool event) +{ + struct ifaddrmsg* msg = NLMSG_DATA(hdr); + struct rtattr *rta = IFA_RTA(msg); + size_t rtasize = IFA_PAYLOAD (hdr); + host_t *host = NULL; + iface_entry_t *iface; + chunk_t local = chunk_empty, address = chunk_empty; + char *route_ifname = NULL; + bool update = FALSE, found = FALSE, changed = FALSE; + + while (RTA_OK(rta, rtasize)) + { + switch (rta->rta_type) + { + case IFA_LOCAL: + local.ptr = RTA_DATA(rta); + local.len = RTA_PAYLOAD(rta); + break; + case IFA_ADDRESS: + address.ptr = RTA_DATA(rta); + address.len = RTA_PAYLOAD(rta); + break; + } + rta = RTA_NEXT(rta, rtasize); + } + + /* For PPP interfaces, we need the IFA_LOCAL address, + * IFA_ADDRESS is the peers address. But IFA_LOCAL is + * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */ + if (local.ptr) + { + host = host_create_from_chunk(msg->ifa_family, local, 0); + } + else if (address.ptr) + { + host = host_create_from_chunk(msg->ifa_family, address, 0); + } + + if (host == NULL) + { /* bad family? */ + return; + } + + this->lock->write_lock(this->lock); + if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, + (void**)&iface, &msg->ifa_index) == SUCCESS) + { + addr_map_entry_t *entry, lookup = { + .ip = host, + .iface = iface, + }; + addr_entry_t *addr; + + entry = this->vips->get(this->vips, &lookup); + if (entry) + { + if (hdr->nlmsg_type == RTM_NEWADDR) + { /* mark as installed and signal waiting threads */ + entry->addr->installed = TRUE; + } + else + { /* the address was already marked as uninstalled */ + addr = entry->addr; + iface->addrs->remove(iface->addrs, addr, NULL); + addr_map_entry_remove(this->vips, addr, iface); + addr_entry_destroy(addr); + } + /* no roam events etc. for virtual IPs */ + this->condvar->broadcast(this->condvar); + this->lock->unlock(this->lock); + host->destroy(host); + return; + } + entry = this->addrs->get(this->addrs, &lookup); + if (entry) + { + if (hdr->nlmsg_type == RTM_DELADDR) + { + found = TRUE; + addr = entry->addr; + iface->addrs->remove(iface->addrs, addr, NULL); + if (iface->usable) + { + changed = TRUE; + DBG1(DBG_KNL, "%H disappeared from %s", host, + iface->ifname); + } + addr_map_entry_remove(this->addrs, addr, iface); + addr_entry_destroy(addr); + } + } + else + { + if (hdr->nlmsg_type == RTM_NEWADDR) + { + found = TRUE; + changed = TRUE; + route_ifname = strdup(iface->ifname); + INIT(addr, + .ip = host->clone(host), + .flags = msg->ifa_flags, + .scope = msg->ifa_scope, + ); + iface->addrs->insert_last(iface->addrs, addr); + addr_map_entry_add(this->addrs, addr, iface); + if (event && iface->usable) + { + DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname); + } + } + } + if (found && (iface->flags & IFF_UP)) + { + update = TRUE; + } + if (!iface->usable) + { /* ignore events for interfaces excluded by config */ + update = changed = FALSE; + } + } + this->lock->unlock(this->lock); + + if (update && event && route_ifname) + { + queue_route_reinstall(this, route_ifname); + } + else + { + free(route_ifname); + } + host->destroy(host); + + /* send an update to all IKE_SAs */ + if (update && event && changed) + { + fire_roam_event(this, TRUE); + } +} + +/** + * process RTM_NEWROUTE and RTM_DELROUTE from kernel + */ +static void process_route(private_kernel_netlink_net_t *this, struct nlmsghdr *hdr) +{ + struct rtmsg* msg = NLMSG_DATA(hdr); + struct rtattr *rta = RTM_RTA(msg); + size_t rtasize = RTM_PAYLOAD(hdr); + u_int32_t rta_oif = 0; + host_t *host = NULL; + + /* ignore routes added by us or in the local routing table (local addrs) */ + if (msg->rtm_table && (msg->rtm_table == this->routing_table || + msg->rtm_table == RT_TABLE_LOCAL)) + { + return; + } + else if (msg->rtm_flags & RTM_F_CLONED) + { /* ignore cached routes, seem to be created a lot for IPv6 */ + return; + } + + while (RTA_OK(rta, rtasize)) + { + switch (rta->rta_type) + { + case RTA_PREFSRC: + DESTROY_IF(host); + host = host_create_from_chunk(msg->rtm_family, + chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), 0); + break; + case RTA_OIF: + if (RTA_PAYLOAD(rta) == sizeof(rta_oif)) + { + rta_oif = *(u_int32_t*)RTA_DATA(rta); + } + break; + } + rta = RTA_NEXT(rta, rtasize); + } + this->lock->read_lock(this->lock); + if (rta_oif && !is_interface_up_and_usable(this, rta_oif)) + { /* ignore route changes for interfaces that are ignored or down */ + this->lock->unlock(this->lock); + DESTROY_IF(host); + return; + } + if (!host && rta_oif) + { + host = get_interface_address(this, rta_oif, msg->rtm_family, + NULL, NULL); + } + if (!host || is_known_vip(this, host)) + { /* ignore routes added for virtual IPs */ + this->lock->unlock(this->lock); + DESTROY_IF(host); + return; + } + this->lock->unlock(this->lock); + fire_roam_event(this, FALSE); + host->destroy(host); +} + +/** + * Receives events from kernel + */ +static bool receive_events(private_kernel_netlink_net_t *this, int fd, + watcher_event_t event) +{ + char response[1536]; + struct nlmsghdr *hdr = (struct nlmsghdr*)response; + struct sockaddr_nl addr; + socklen_t addr_len = sizeof(addr); + int len; + + len = recvfrom(this->socket_events, response, sizeof(response), + MSG_DONTWAIT, (struct sockaddr*)&addr, &addr_len); + if (len < 0) + { + switch (errno) + { + case EINTR: + /* interrupted, try again */ + return TRUE; + case EAGAIN: + /* no data ready, select again */ + return TRUE; + default: + DBG1(DBG_KNL, "unable to receive from rt event socket"); + sleep(1); + return TRUE; + } + } + + if (addr.nl_pid != 0) + { /* not from kernel. not interested, try another one */ + return TRUE; + } + + while (NLMSG_OK(hdr, len)) + { + /* looks good so far, dispatch netlink message */ + switch (hdr->nlmsg_type) + { + case RTM_NEWADDR: + case RTM_DELADDR: + process_addr(this, hdr, TRUE); + break; + case RTM_NEWLINK: + case RTM_DELLINK: + process_link(this, hdr, TRUE); + break; + case RTM_NEWROUTE: + case RTM_DELROUTE: + if (this->process_route) + { + process_route(this, hdr); + } + break; + default: + break; + } + hdr = NLMSG_NEXT(hdr, len); + } + return TRUE; +} + +/** enumerator over addresses */ +typedef struct { + private_kernel_netlink_net_t* this; + /** which addresses to enumerate */ + kernel_address_type_t which; +} address_enumerator_t; + +/** + * cleanup function for address enumerator + */ +static void address_enumerator_destroy(address_enumerator_t *data) +{ + data->this->lock->unlock(data->this->lock); + free(data); +} + +/** + * filter for addresses + */ +static bool filter_addresses(address_enumerator_t *data, + addr_entry_t** in, host_t** out) +{ + if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->refcount) + { /* skip virtual interfaces added by us */ + return FALSE; + } + if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->refcount) + { /* address is regular, but not requested */ + return FALSE; + } + if ((*in)->scope >= RT_SCOPE_LINK) + { /* skip addresses with a unusable scope */ + return FALSE; + } + *out = (*in)->ip; + return TRUE; +} + +/** + * enumerator constructor for interfaces + */ +static enumerator_t *create_iface_enumerator(iface_entry_t *iface, + address_enumerator_t *data) +{ + return enumerator_create_filter( + iface->addrs->create_enumerator(iface->addrs), + (void*)filter_addresses, data, NULL); +} + +/** + * filter for interfaces + */ +static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, + iface_entry_t** out) +{ + if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable) + { /* skip interfaces excluded by config */ + return FALSE; + } + if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK)) + { /* ignore loopback devices */ + return FALSE; + } + if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP)) + { /* skip interfaces not up */ + return FALSE; + } + *out = *in; + return TRUE; +} + +METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, + private_kernel_netlink_net_t *this, kernel_address_type_t which) +{ + address_enumerator_t *data; + + INIT(data, + .this = this, + .which = which, + ); + + this->lock->read_lock(this->lock); + return enumerator_create_nested( + enumerator_create_filter( + this->ifaces->create_enumerator(this->ifaces), + (void*)filter_interfaces, data, NULL), + (void*)create_iface_enumerator, data, + (void*)address_enumerator_destroy); +} + +METHOD(kernel_net_t, get_interface_name, bool, + private_kernel_netlink_net_t *this, host_t* ip, char **name) +{ + addr_map_entry_t *entry, lookup = { + .ip = ip, + }; + + if (ip->is_anyaddr(ip)) + { + return FALSE; + } + this->lock->read_lock(this->lock); + /* first try to find it on an up and usable interface */ + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match_up_and_usable); + if (entry) + { + if (name) + { + *name = strdup(entry->iface->ifname); + DBG2(DBG_KNL, "%H is on interface %s", ip, *name); + } + this->lock->unlock(this->lock); + return TRUE; + } + /* in a second step, consider virtual IPs installed by us */ + entry = this->vips->get_match(this->vips, &lookup, + (void*)addr_map_entry_match_up_and_usable); + if (entry) + { + if (name) + { + *name = strdup(entry->iface->ifname); + DBG2(DBG_KNL, "virtual IP %H is on interface %s", ip, *name); + } + this->lock->unlock(this->lock); + return TRUE; + } + /* maybe it is installed on an ignored interface */ + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match_up); + if (!entry) + { + DBG2(DBG_KNL, "%H is not a local address or the interface is down", ip); + } + this->lock->unlock(this->lock); + return FALSE; +} + +/** + * get the index of an interface by name + */ +static int get_interface_index(private_kernel_netlink_net_t *this, char* name) +{ + iface_entry_t *iface; + int ifindex = 0; + + DBG2(DBG_KNL, "getting iface index for %s", name); + + this->lock->read_lock(this->lock); + if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, + (void**)&iface, name) == SUCCESS) + { + ifindex = iface->ifindex; + } + this->lock->unlock(this->lock); + + if (ifindex == 0) + { + DBG1(DBG_KNL, "unable to get interface index for %s", name); + } + return ifindex; +} + +/** + * check if an address or net (addr with prefix net bits) is in + * subnet (net with net_len net bits) + */ +static bool addr_in_subnet(chunk_t addr, int prefix, chunk_t net, int net_len) +{ + static const u_char mask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; + int byte = 0; + + if (net_len == 0) + { /* any address matches a /0 network */ + return TRUE; + } + if (addr.len != net.len || net_len > 8 * net.len || prefix < net_len) + { + return FALSE; + } + /* scan through all bytes in network order */ + while (net_len > 0) + { + if (net_len < 8) + { + return (mask[net_len] & addr.ptr[byte]) == (mask[net_len] & net.ptr[byte]); + } + else + { + if (addr.ptr[byte] != net.ptr[byte]) + { + return FALSE; + } + byte++; + net_len -= 8; + } + } + return TRUE; +} + +/** + * Store information about a route retrieved via RTNETLINK + */ +typedef struct { + chunk_t gtw; + chunk_t src; + chunk_t dst; + host_t *src_host; + u_int8_t dst_len; + u_int32_t table; + u_int32_t oif; + u_int32_t priority; +} rt_entry_t; + +/** + * Free a route entry + */ +static void rt_entry_destroy(rt_entry_t *this) +{ + DESTROY_IF(this->src_host); + free(this); +} + +/** + * Check if the route received with RTM_NEWROUTE is usable based on its type. + */ +static bool route_usable(struct nlmsghdr *hdr) +{ + struct rtmsg *msg; + + msg = NLMSG_DATA(hdr); + switch (msg->rtm_type) + { + case RTN_BLACKHOLE: + case RTN_UNREACHABLE: + case RTN_PROHIBIT: + case RTN_THROW: + return FALSE; + default: + return TRUE; + } +} + +/** + * Parse route received with RTM_NEWROUTE. The given rt_entry_t object will be + * reused if not NULL. + * + * Returned chunks point to internal data of the Netlink message. + */ +static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route) +{ + struct rtattr *rta; + struct rtmsg *msg; + size_t rtasize; + + msg = NLMSG_DATA(hdr); + rta = RTM_RTA(msg); + rtasize = RTM_PAYLOAD(hdr); + + if (route) + { + route->gtw = chunk_empty; + route->src = chunk_empty; + route->dst = chunk_empty; + route->dst_len = msg->rtm_dst_len; + route->table = msg->rtm_table; + route->oif = 0; + route->priority = 0; + } + else + { + INIT(route, + .dst_len = msg->rtm_dst_len, + .table = msg->rtm_table, + ); + } + + while (RTA_OK(rta, rtasize)) + { + switch (rta->rta_type) + { + case RTA_PREFSRC: + route->src = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)); + break; + case RTA_GATEWAY: + route->gtw = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)); + break; + case RTA_DST: + route->dst = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)); + break; + case RTA_OIF: + if (RTA_PAYLOAD(rta) == sizeof(route->oif)) + { + route->oif = *(u_int32_t*)RTA_DATA(rta); + } + break; + case RTA_PRIORITY: + if (RTA_PAYLOAD(rta) == sizeof(route->priority)) + { + route->priority = *(u_int32_t*)RTA_DATA(rta); + } + break; +#ifdef HAVE_RTA_TABLE + case RTA_TABLE: + if (RTA_PAYLOAD(rta) == sizeof(route->table)) + { + route->table = *(u_int32_t*)RTA_DATA(rta); + } + break; +#endif /* HAVE_RTA_TABLE*/ + } + rta = RTA_NEXT(rta, rtasize); + } + return route; +} + +/** + * Get a route: If "nexthop", the nexthop is returned. source addr otherwise. + */ +static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, + int prefix, bool nexthop, host_t *candidate, + u_int recursion) +{ + netlink_buf_t request; + struct nlmsghdr *hdr, *out, *current; + struct rtmsg *msg; + chunk_t chunk; + size_t len; + linked_list_t *routes; + rt_entry_t *route = NULL, *best = NULL; + enumerator_t *enumerator; + host_t *addr = NULL; + bool match_net; + int family; + + if (recursion > MAX_ROUTE_RECURSION) + { + return NULL; + } + chunk = dest->get_address(dest); + len = chunk.len * 8; + prefix = prefix < 0 ? len : min(prefix, len); + match_net = prefix != len; + + memset(&request, 0, sizeof(request)); + + family = dest->get_family(dest); + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST; + hdr->nlmsg_type = RTM_GETROUTE; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + + msg = NLMSG_DATA(hdr); + msg->rtm_family = family; + if (!match_net && this->rta_mark && this->routing_mark.value) + { + /* if our routing rule excludes packets with a certain mark we can + * get the preferred route without having to dump all routes */ + chunk = chunk_from_thing(this->routing_mark.value); + netlink_add_attribute(hdr, RTA_MARK, chunk, sizeof(request)); + } + else if (family == AF_INET || this->rta_prefsrc_for_ipv6 || + this->routing_table || match_net) + { /* kernels prior to 3.0 do not support RTA_PREFSRC for IPv6 routes. + * as we want to ignore routes with virtual IPs we cannot use DUMP + * if these routes are not installed in a separate table */ + hdr->nlmsg_flags |= NLM_F_DUMP; + } + if (candidate) + { + chunk = candidate->get_address(candidate); + netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request)); + } + /* we use this below to match against the routes */ + chunk = dest->get_address(dest); + if (!match_net) + { + netlink_add_attribute(hdr, RTA_DST, chunk, sizeof(request)); + } + + if (this->socket->send(this->socket, hdr, &out, &len) != SUCCESS) + { + DBG2(DBG_KNL, "getting %s to reach %H/%d failed", + nexthop ? "nexthop" : "address", dest, prefix); + return NULL; + } + routes = linked_list_create(); + this->lock->read_lock(this->lock); + + for (current = out; NLMSG_OK(current, len); + current = NLMSG_NEXT(current, len)) + { + switch (current->nlmsg_type) + { + case NLMSG_DONE: + break; + case RTM_NEWROUTE: + { + rt_entry_t *other; + uintptr_t table; + + if (!route_usable(current)) + { + continue; + } + route = parse_route(current, route); + + table = (uintptr_t)route->table; + if (this->rt_exclude->find_first(this->rt_exclude, NULL, + (void**)&table) == SUCCESS) + { /* route is from an excluded routing table */ + continue; + } + if (this->routing_table != 0 && + route->table == this->routing_table) + { /* route is from our own ipsec routing table */ + continue; + } + if (route->oif && !is_interface_up_and_usable(this, route->oif)) + { /* interface is down */ + continue; + } + if (!addr_in_subnet(chunk, prefix, route->dst, route->dst_len)) + { /* route destination does not contain dest */ + continue; + } + if (route->src.ptr) + { /* verify source address, if any */ + host_t *src = host_create_from_chunk(msg->rtm_family, + route->src, 0); + if (src && is_known_vip(this, src)) + { /* ignore routes installed by us */ + src->destroy(src); + continue; + } + route->src_host = src; + } + /* insert route, sorted by priority and network prefix */ + enumerator = routes->create_enumerator(routes); + while (enumerator->enumerate(enumerator, &other)) + { + if (route->priority < other->priority) + { + break; + } + if (route->priority == other->priority && + route->dst_len > other->dst_len) + { + break; + } + } + routes->insert_before(routes, enumerator, route); + enumerator->destroy(enumerator); + route = NULL; + continue; + } + default: + continue; + } + break; + } + if (route) + { + rt_entry_destroy(route); + } + + /* now we have a list of routes matching dest, sorted by net prefix. + * we will look for source addresses for these routes and select the one + * with the preferred source address, if possible */ + enumerator = routes->create_enumerator(routes); + while (enumerator->enumerate(enumerator, &route)) + { + if (route->src_host) + { /* got a source address with the route, if no preferred source + * is given or it matches we are done, as this is the best route */ + if (!candidate || candidate->ip_equals(candidate, route->src_host)) + { + best = route; + break; + } + else if (route->oif) + { /* no match yet, maybe it is assigned to the same interface */ + host_t *src = get_interface_address(this, route->oif, + msg->rtm_family, dest, candidate); + if (src && src->ip_equals(src, candidate)) + { + route->src_host->destroy(route->src_host); + route->src_host = src; + best = route; + break; + } + DESTROY_IF(src); + } + /* no luck yet with the source address. if this is the best (first) + * route we store it as fallback in case we don't find a route with + * the preferred source */ + best = best ?: route; + continue; + } + if (route->oif) + { /* no src, but an interface - get address from it */ + route->src_host = get_interface_address(this, route->oif, + msg->rtm_family, dest, candidate); + if (route->src_host) + { /* we handle this address the same as the one above */ + if (!candidate || + candidate->ip_equals(candidate, route->src_host)) + { + best = route; + break; + } + best = best ?: route; + continue; + } + } + if (route->gtw.ptr) + { /* no src, no iface, but a gateway - lookup src to reach gtw */ + host_t *gtw; + + gtw = host_create_from_chunk(msg->rtm_family, route->gtw, 0); + if (gtw && !gtw->ip_equals(gtw, dest)) + { + route->src_host = get_route(this, gtw, -1, FALSE, candidate, + recursion + 1); + } + DESTROY_IF(gtw); + if (route->src_host) + { /* more of the same */ + if (!candidate || + candidate->ip_equals(candidate, route->src_host)) + { + best = route; + break; + } + best = best ?: route; + } + } + } + enumerator->destroy(enumerator); + + if (nexthop) + { /* nexthop lookup, return gateway if any */ + if (best || routes->get_first(routes, (void**)&best) == SUCCESS) + { + addr = host_create_from_chunk(msg->rtm_family, best->gtw, 0); + } + if (!addr && !match_net) + { /* fallback to destination address */ + addr = dest->clone(dest); + } + } + else + { + if (best) + { + addr = best->src_host->clone(best->src_host); + } + } + this->lock->unlock(this->lock); + routes->destroy_function(routes, (void*)rt_entry_destroy); + free(out); + + if (addr) + { + DBG2(DBG_KNL, "using %H as %s to reach %H/%d", addr, + nexthop ? "nexthop" : "address", dest, prefix); + } + else if (!recursion) + { + DBG2(DBG_KNL, "no %s found to reach %H/%d", + nexthop ? "nexthop" : "address", dest, prefix); + } + return addr; +} + +METHOD(kernel_net_t, get_source_addr, host_t*, + private_kernel_netlink_net_t *this, host_t *dest, host_t *src) +{ + return get_route(this, dest, -1, FALSE, src, 0); +} + +METHOD(kernel_net_t, get_nexthop, host_t*, + private_kernel_netlink_net_t *this, host_t *dest, int prefix, host_t *src) +{ + return get_route(this, dest, prefix, TRUE, src, 0); +} + +/** + * Manages the creation and deletion of ip addresses on an interface. + * By setting the appropriate nlmsg_type, the ip will be set or unset. + */ +static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type, + int flags, int if_index, host_t *ip, int prefix) +{ + netlink_buf_t request; + struct nlmsghdr *hdr; + struct ifaddrmsg *msg; + chunk_t chunk; + + memset(&request, 0, sizeof(request)); + + chunk = ip->get_address(ip); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags; + hdr->nlmsg_type = nlmsg_type; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + + msg = NLMSG_DATA(hdr); + msg->ifa_family = ip->get_family(ip); + msg->ifa_flags = 0; + msg->ifa_prefixlen = prefix < 0 ? chunk.len * 8 : prefix; + msg->ifa_scope = RT_SCOPE_UNIVERSE; + msg->ifa_index = if_index; + + netlink_add_attribute(hdr, IFA_LOCAL, chunk, sizeof(request)); + + if (ip->get_family(ip) == AF_INET6 && this->rta_prefsrc_for_ipv6) + { /* if source routes are possible we let the virtual IP get deprecated + * immediately (but mark it as valid forever) so it gets only used if + * forced by our route, and not by the default IPv6 address selection */ + struct ifa_cacheinfo cache = { + .ifa_valid = 0xFFFFFFFF, + .ifa_prefered = 0, + }; + netlink_add_attribute(hdr, IFA_CACHEINFO, chunk_from_thing(cache), + sizeof(request)); + } + return this->socket->send_ack(this->socket, hdr); +} + +METHOD(kernel_net_t, add_ip, status_t, + private_kernel_netlink_net_t *this, host_t *virtual_ip, int prefix, + char *iface_name) +{ + addr_map_entry_t *entry, lookup = { + .ip = virtual_ip, + }; + iface_entry_t *iface = NULL; + + if (!this->install_virtual_ip) + { /* disabled by config */ + return SUCCESS; + } + + this->lock->write_lock(this->lock); + /* the virtual IP might actually be installed as regular IP, in which case + * we don't track it as virtual IP */ + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match); + if (!entry) + { /* otherwise it might already be installed as virtual IP */ + entry = this->vips->get_match(this->vips, &lookup, + (void*)addr_map_entry_match); + if (entry) + { /* the vip we found can be in one of three states: 1) installed and + * ready, 2) just added by another thread, but not yet confirmed to + * be installed by the kernel, 3) just deleted, but not yet gone. + * Then while we wait below, several things could happen (as we + * release the lock). For instance, the interface could disappear, + * or the IP is finally deleted, and it reappears on a different + * interface. All these cases are handled by the call below. */ + while (!is_vip_installed_or_gone(this, virtual_ip, &entry)) + { + this->condvar->wait(this->condvar, this->lock); + } + if (entry) + { + entry->addr->refcount++; + } + } + } + if (entry) + { + DBG2(DBG_KNL, "virtual IP %H is already installed on %s", virtual_ip, + entry->iface->ifname); + this->lock->unlock(this->lock); + return SUCCESS; + } + /* try to find the target interface, either by config or via src ip */ + if (!this->install_virtual_ip_on || + this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, + (void**)&iface, this->install_virtual_ip_on) != SUCCESS) + { + if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, + (void**)&iface, iface_name) != SUCCESS) + { /* if we don't find the requested interface we just use the first */ + this->ifaces->get_first(this->ifaces, (void**)&iface); + } + } + if (iface) + { + addr_entry_t *addr; + char *ifname; + int ifi; + + INIT(addr, + .ip = virtual_ip->clone(virtual_ip), + .refcount = 1, + .scope = RT_SCOPE_UNIVERSE, + ); + iface->addrs->insert_last(iface->addrs, addr); + addr_map_entry_add(this->vips, addr, iface); + ifi = iface->ifindex; + this->lock->unlock(this->lock); + if (manage_ipaddr(this, RTM_NEWADDR, NLM_F_CREATE | NLM_F_EXCL, + ifi, virtual_ip, prefix) == SUCCESS) + { + this->lock->write_lock(this->lock); + while (!is_vip_installed_or_gone(this, virtual_ip, &entry)) + { /* wait until address appears */ + this->condvar->wait(this->condvar, this->lock); + } + if (entry) + { /* we fail if the interface got deleted in the meantime */ + ifname = strdup(entry->iface->ifname); + this->lock->unlock(this->lock); + DBG2(DBG_KNL, "virtual IP %H installed on %s", + virtual_ip, ifname); + /* during IKEv1 reauthentication, children get moved from + * old the new SA before the virtual IP is available. This + * kills the route for our virtual IP, reinstall. */ + queue_route_reinstall(this, ifname); + return SUCCESS; + } + this->lock->unlock(this->lock); + } + DBG1(DBG_KNL, "adding virtual IP %H failed", virtual_ip); + return FAILED; + } + this->lock->unlock(this->lock); + DBG1(DBG_KNL, "no interface available, unable to install virtual IP %H", + virtual_ip); + return FAILED; +} + +METHOD(kernel_net_t, del_ip, status_t, + private_kernel_netlink_net_t *this, host_t *virtual_ip, int prefix, + bool wait) +{ + addr_map_entry_t *entry, lookup = { + .ip = virtual_ip, + }; + + if (!this->install_virtual_ip) + { /* disabled by config */ + return SUCCESS; + } + + DBG2(DBG_KNL, "deleting virtual IP %H", virtual_ip); + + this->lock->write_lock(this->lock); + entry = this->vips->get_match(this->vips, &lookup, + (void*)addr_map_entry_match); + if (!entry) + { /* we didn't install this IP as virtual IP */ + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match); + if (entry) + { + DBG2(DBG_KNL, "not deleting existing IP %H on %s", virtual_ip, + entry->iface->ifname); + this->lock->unlock(this->lock); + return SUCCESS; + } + DBG2(DBG_KNL, "virtual IP %H not cached, unable to delete", virtual_ip); + this->lock->unlock(this->lock); + return FAILED; + } + if (entry->addr->refcount == 1) + { + status_t status; + int ifi; + + /* we set this flag so that threads calling add_ip will block and wait + * until the entry is gone, also so we can wait below */ + entry->addr->installed = FALSE; + ifi = entry->iface->ifindex; + this->lock->unlock(this->lock); + status = manage_ipaddr(this, RTM_DELADDR, 0, ifi, virtual_ip, prefix); + if (status == SUCCESS && wait) + { /* wait until the address is really gone */ + this->lock->write_lock(this->lock); + while (is_known_vip(this, virtual_ip)) + { + this->condvar->wait(this->condvar, this->lock); + } + this->lock->unlock(this->lock); + } + return status; + } + else + { + entry->addr->refcount--; + } + DBG2(DBG_KNL, "virtual IP %H used by other SAs, not deleting", + virtual_ip); + this->lock->unlock(this->lock); + return SUCCESS; +} + +/** + * Manages source routes in the routing table. + * By setting the appropriate nlmsg_type, the route gets added or removed. + */ +static status_t manage_srcroute(private_kernel_netlink_net_t *this, + int nlmsg_type, int flags, chunk_t dst_net, + u_int8_t prefixlen, host_t *gateway, + host_t *src_ip, char *if_name) +{ + netlink_buf_t request; + struct nlmsghdr *hdr; + struct rtmsg *msg; + struct rtattr *rta; + int ifindex; + chunk_t chunk; + + /* if route is 0.0.0.0/0, we can't install it, as it would + * overwrite the default route. Instead, we add two routes: + * 0.0.0.0/1 and 128.0.0.0/1 */ + if (this->routing_table == 0 && prefixlen == 0) + { + chunk_t half_net; + u_int8_t half_prefixlen; + status_t status; + + half_net = chunk_alloca(dst_net.len); + memset(half_net.ptr, 0, half_net.len); + half_prefixlen = 1; + + status = manage_srcroute(this, nlmsg_type, flags, half_net, half_prefixlen, + gateway, src_ip, if_name); + half_net.ptr[0] |= 0x80; + status = manage_srcroute(this, nlmsg_type, flags, half_net, half_prefixlen, + gateway, src_ip, if_name); + return status; + } + + memset(&request, 0, sizeof(request)); + + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags; + hdr->nlmsg_type = nlmsg_type; + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + + msg = NLMSG_DATA(hdr); + msg->rtm_family = src_ip->get_family(src_ip); + msg->rtm_dst_len = prefixlen; + msg->rtm_table = this->routing_table; + msg->rtm_protocol = RTPROT_STATIC; + msg->rtm_type = RTN_UNICAST; + msg->rtm_scope = RT_SCOPE_UNIVERSE; + + netlink_add_attribute(hdr, RTA_DST, dst_net, sizeof(request)); + chunk = src_ip->get_address(src_ip); + netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request)); + if (gateway && gateway->get_family(gateway) == src_ip->get_family(src_ip)) + { + chunk = gateway->get_address(gateway); + netlink_add_attribute(hdr, RTA_GATEWAY, chunk, sizeof(request)); + } + ifindex = get_interface_index(this, if_name); + chunk.ptr = (char*)&ifindex; + chunk.len = sizeof(ifindex); + netlink_add_attribute(hdr, RTA_OIF, chunk, sizeof(request)); + + if (this->mtu || this->mss) + { + chunk = chunk_alloca(RTA_LENGTH((sizeof(struct rtattr) + + sizeof(u_int32_t)) * 2)); + chunk.len = 0; + rta = (struct rtattr*)chunk.ptr; + if (this->mtu) + { + rta->rta_type = RTAX_MTU; + rta->rta_len = RTA_LENGTH(sizeof(u_int32_t)); + memcpy(RTA_DATA(rta), &this->mtu, sizeof(u_int32_t)); + chunk.len = rta->rta_len; + } + if (this->mss) + { + rta = (struct rtattr*)(chunk.ptr + RTA_ALIGN(chunk.len)); + rta->rta_type = RTAX_ADVMSS; + rta->rta_len = RTA_LENGTH(sizeof(u_int32_t)); + memcpy(RTA_DATA(rta), &this->mss, sizeof(u_int32_t)); + chunk.len = RTA_ALIGN(chunk.len) + rta->rta_len; + } + netlink_add_attribute(hdr, RTA_METRICS, chunk, sizeof(request)); + } + + return this->socket->send_ack(this->socket, hdr); +} + +METHOD(kernel_net_t, add_route, status_t, + private_kernel_netlink_net_t *this, chunk_t dst_net, u_int8_t prefixlen, + host_t *gateway, host_t *src_ip, char *if_name) +{ + status_t status; + route_entry_t *found, route = { + .dst_net = dst_net, + .prefixlen = prefixlen, + .gateway = gateway, + .src_ip = src_ip, + .if_name = if_name, + }; + + this->routes_lock->lock(this->routes_lock); + found = this->routes->get(this->routes, &route); + if (found) + { + this->routes_lock->unlock(this->routes_lock); + return ALREADY_DONE; + } + status = manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, + dst_net, prefixlen, gateway, src_ip, if_name); + if (status == SUCCESS) + { + found = route_entry_clone(&route); + this->routes->put(this->routes, found, found); + } + this->routes_lock->unlock(this->routes_lock); + return status; +} + +METHOD(kernel_net_t, del_route, status_t, + private_kernel_netlink_net_t *this, chunk_t dst_net, u_int8_t prefixlen, + host_t *gateway, host_t *src_ip, char *if_name) +{ + status_t status; + route_entry_t *found, route = { + .dst_net = dst_net, + .prefixlen = prefixlen, + .gateway = gateway, + .src_ip = src_ip, + .if_name = if_name, + }; + + this->routes_lock->lock(this->routes_lock); + found = this->routes->get(this->routes, &route); + if (!found) + { + this->routes_lock->unlock(this->routes_lock); + return NOT_FOUND; + } + this->routes->remove(this->routes, found); + route_entry_destroy(found); + status = manage_srcroute(this, RTM_DELROUTE, 0, dst_net, prefixlen, + gateway, src_ip, if_name); + this->routes_lock->unlock(this->routes_lock); + return status; +} + +/** + * Initialize a list of local addresses. + */ +static status_t init_address_list(private_kernel_netlink_net_t *this) +{ + netlink_buf_t request; + struct nlmsghdr *out, *current, *in; + struct rtgenmsg *msg; + size_t len; + enumerator_t *ifaces, *addrs; + iface_entry_t *iface; + addr_entry_t *addr; + + DBG2(DBG_KNL, "known interfaces and IP addresses:"); + + memset(&request, 0, sizeof(request)); + + in = &request.hdr; + in->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); + in->nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT; + msg = NLMSG_DATA(in); + msg->rtgen_family = AF_UNSPEC; + + /* get all links */ + in->nlmsg_type = RTM_GETLINK; + if (this->socket->send(this->socket, in, &out, &len) != SUCCESS) + { + return FAILED; + } + current = out; + while (NLMSG_OK(current, len)) + { + switch (current->nlmsg_type) + { + case NLMSG_DONE: + break; + case RTM_NEWLINK: + process_link(this, current, FALSE); + /* fall through */ + default: + current = NLMSG_NEXT(current, len); + continue; + } + break; + } + free(out); + + /* get all interface addresses */ + in->nlmsg_type = RTM_GETADDR; + if (this->socket->send(this->socket, in, &out, &len) != SUCCESS) + { + return FAILED; + } + current = out; + while (NLMSG_OK(current, len)) + { + switch (current->nlmsg_type) + { + case NLMSG_DONE: + break; + case RTM_NEWADDR: + process_addr(this, current, FALSE); + /* fall through */ + default: + current = NLMSG_NEXT(current, len); + continue; + } + break; + } + free(out); + + this->lock->read_lock(this->lock); + ifaces = this->ifaces->create_enumerator(this->ifaces); + while (ifaces->enumerate(ifaces, &iface)) + { + if (iface_entry_up_and_usable(iface)) + { + DBG2(DBG_KNL, " %s", iface->ifname); + addrs = iface->addrs->create_enumerator(iface->addrs); + while (addrs->enumerate(addrs, (void**)&addr)) + { + DBG2(DBG_KNL, " %H", addr->ip); + } + addrs->destroy(addrs); + } + } + ifaces->destroy(ifaces); + this->lock->unlock(this->lock); + return SUCCESS; +} + +/** + * create or delete a rule to use our routing table + */ +static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type, + int family, u_int32_t table, u_int32_t prio) +{ + netlink_buf_t request; + struct nlmsghdr *hdr; + struct rtmsg *msg; + chunk_t chunk; + char *fwmark; + + memset(&request, 0, sizeof(request)); + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = nlmsg_type; + if (nlmsg_type == RTM_NEWRULE) + { + hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; + } + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + + msg = NLMSG_DATA(hdr); + msg->rtm_table = table; + msg->rtm_family = family; + msg->rtm_protocol = RTPROT_BOOT; + msg->rtm_scope = RT_SCOPE_UNIVERSE; + msg->rtm_type = RTN_UNICAST; + + chunk = chunk_from_thing(prio); + netlink_add_attribute(hdr, RTA_PRIORITY, chunk, sizeof(request)); + + fwmark = lib->settings->get_str(lib->settings, + "%s.plugins.kernel-netlink.fwmark", NULL, lib->ns); + if (fwmark) + { +#ifdef HAVE_LINUX_FIB_RULES_H + mark_t mark; + + if (fwmark[0] == '!') + { + msg->rtm_flags |= FIB_RULE_INVERT; + fwmark++; + } + if (mark_from_string(fwmark, &mark)) + { + chunk = chunk_from_thing(mark.value); + netlink_add_attribute(hdr, FRA_FWMARK, chunk, sizeof(request)); + chunk = chunk_from_thing(mark.mask); + netlink_add_attribute(hdr, FRA_FWMASK, chunk, sizeof(request)); + if (msg->rtm_flags & FIB_RULE_INVERT) + { + this->routing_mark = mark; + } + } +#else + DBG1(DBG_KNL, "setting firewall mark on routing rule is not supported"); +#endif + } + return this->socket->send_ack(this->socket, hdr); +} + +/** + * check for kernel features (currently only via version number) + */ +static void check_kernel_features(private_kernel_netlink_net_t *this) +{ + struct utsname utsname; + int a, b, c; + + if (uname(&utsname) == 0) + { + switch(sscanf(utsname.release, "%d.%d.%d", &a, &b, &c)) + { + case 3: + if (a == 2) + { + if (b == 6 && c >= 36) + { + this->rta_mark = TRUE; + } + DBG2(DBG_KNL, "detected Linux %d.%d.%d, no support for " + "RTA_PREFSRC for IPv6 routes", a, b, c); + break; + } + /* fall-through */ + case 2: + /* only 3.x+ uses two part version numbers */ + this->rta_prefsrc_for_ipv6 = TRUE; + this->rta_mark = TRUE; + break; + default: + break; + } + } +} + +/** + * Destroy an address to iface map + */ +static void addr_map_destroy(hashtable_t *map) +{ + enumerator_t *enumerator; + addr_map_entry_t *addr; + + enumerator = map->create_enumerator(map); + while (enumerator->enumerate(enumerator, NULL, (void**)&addr)) + { + free(addr); + } + enumerator->destroy(enumerator); + map->destroy(map); +} + +METHOD(kernel_net_t, destroy, void, + private_kernel_netlink_net_t *this) +{ + enumerator_t *enumerator; + route_entry_t *route; + + if (this->routing_table) + { + manage_rule(this, RTM_DELRULE, AF_INET, this->routing_table, + this->routing_table_prio); + manage_rule(this, RTM_DELRULE, AF_INET6, this->routing_table, + this->routing_table_prio); + } + if (this->socket_events > 0) + { + lib->watcher->remove(lib->watcher, this->socket_events); + close(this->socket_events); + } + enumerator = this->routes->create_enumerator(this->routes); + while (enumerator->enumerate(enumerator, NULL, (void**)&route)) + { + manage_srcroute(this, RTM_DELROUTE, 0, route->dst_net, route->prefixlen, + route->gateway, route->src_ip, route->if_name); + route_entry_destroy(route); + } + enumerator->destroy(enumerator); + this->routes->destroy(this->routes); + this->routes_lock->destroy(this->routes_lock); + DESTROY_IF(this->socket); + + net_changes_clear(this); + this->net_changes->destroy(this->net_changes); + this->net_changes_lock->destroy(this->net_changes_lock); + + addr_map_destroy(this->addrs); + addr_map_destroy(this->vips); + + this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy); + this->rt_exclude->destroy(this->rt_exclude); + this->roam_lock->destroy(this->roam_lock); + this->condvar->destroy(this->condvar); + this->lock->destroy(this->lock); + free(this); +} + +/* + * Described in header. + */ +kernel_netlink_net_t *kernel_netlink_net_create() +{ + private_kernel_netlink_net_t *this; + enumerator_t *enumerator; + bool register_for_events = TRUE; + char *exclude; + + INIT(this, + .public = { + .interface = { + .get_interface = _get_interface_name, + .create_address_enumerator = _create_address_enumerator, + .get_source_addr = _get_source_addr, + .get_nexthop = _get_nexthop, + .add_ip = _add_ip, + .del_ip = _del_ip, + .add_route = _add_route, + .del_route = _del_route, + .destroy = _destroy, + }, + }, + .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names, + lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.parallel_route", FALSE, lib->ns)), + .rt_exclude = linked_list_create(), + .routes = hashtable_create((hashtable_hash_t)route_entry_hash, + (hashtable_equals_t)route_entry_equals, 16), + .net_changes = hashtable_create( + (hashtable_hash_t)net_change_hash, + (hashtable_equals_t)net_change_equals, 16), + .addrs = hashtable_create( + (hashtable_hash_t)addr_map_entry_hash, + (hashtable_equals_t)addr_map_entry_equals, 16), + .vips = hashtable_create((hashtable_hash_t)addr_map_entry_hash, + (hashtable_equals_t)addr_map_entry_equals, 16), + .routes_lock = mutex_create(MUTEX_TYPE_DEFAULT), + .net_changes_lock = mutex_create(MUTEX_TYPE_DEFAULT), + .ifaces = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .condvar = rwlock_condvar_create(), + .roam_lock = spinlock_create(), + .routing_table = lib->settings->get_int(lib->settings, + "%s.routing_table", ROUTING_TABLE, lib->ns), + .routing_table_prio = lib->settings->get_int(lib->settings, + "%s.routing_table_prio", ROUTING_TABLE_PRIO, lib->ns), + .process_route = lib->settings->get_bool(lib->settings, + "%s.process_route", TRUE, lib->ns), + .install_virtual_ip = lib->settings->get_bool(lib->settings, + "%s.install_virtual_ip", TRUE, lib->ns), + .install_virtual_ip_on = lib->settings->get_str(lib->settings, + "%s.install_virtual_ip_on", NULL, lib->ns), + .prefer_temporary_addrs = lib->settings->get_bool(lib->settings, + "%s.prefer_temporary_addrs", FALSE, lib->ns), + .roam_events = lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.roam_events", TRUE, lib->ns), + .mtu = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.mtu", 0, lib->ns), + .mss = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.mss", 0, lib->ns), + ); + timerclear(&this->last_route_reinstall); + timerclear(&this->next_roam); + + check_kernel_features(this); + + if (streq(lib->ns, "starter")) + { /* starter has no threads, so we do not register for kernel events */ + register_for_events = FALSE; + } + + exclude = lib->settings->get_str(lib->settings, + "%s.ignore_routing_tables", NULL, lib->ns); + if (exclude) + { + char *token; + uintptr_t table; + + enumerator = enumerator_create_token(exclude, " ", " "); + while (enumerator->enumerate(enumerator, &token)) + { + errno = 0; + table = strtoul(token, NULL, 10); + + if (errno == 0) + { + this->rt_exclude->insert_last(this->rt_exclude, (void*)table); + } + } + enumerator->destroy(enumerator); + } + + if (register_for_events) + { + struct sockaddr_nl addr; + + memset(&addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + + /* create and bind RT socket for events (address/interface/route changes) */ + this->socket_events = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (this->socket_events < 0) + { + DBG1(DBG_KNL, "unable to create RT event socket"); + destroy(this); + return NULL; + } + addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | + RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK; + if (bind(this->socket_events, (struct sockaddr*)&addr, sizeof(addr))) + { + DBG1(DBG_KNL, "unable to bind RT event socket"); + destroy(this); + return NULL; + } + + lib->watcher->add(lib->watcher, this->socket_events, WATCHER_READ, + (watcher_cb_t)receive_events, this); + } + + if (init_address_list(this) != SUCCESS) + { + DBG1(DBG_KNL, "unable to get interface list"); + destroy(this); + return NULL; + } + + if (this->routing_table) + { + if (manage_rule(this, RTM_NEWRULE, AF_INET, this->routing_table, + this->routing_table_prio) != SUCCESS) + { + DBG1(DBG_KNL, "unable to create IPv4 routing table rule"); + } + if (manage_rule(this, RTM_NEWRULE, AF_INET6, this->routing_table, + this->routing_table_prio) != SUCCESS) + { + DBG1(DBG_KNL, "unable to create IPv6 routing table rule"); + } + } + + return &this->public; +} diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h new file mode 100644 index 000000000..ff9831d3c --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_netlink_net_i kernel_netlink_net + * @{ @ingroup kernel_netlink + */ + +#ifndef KERNEL_NETLINK_NET_H_ +#define KERNEL_NETLINK_NET_H_ + +#include + +typedef struct kernel_netlink_net_t kernel_netlink_net_t; + +/** + * Implementation of the kernel network interface using Netlink. + */ +struct kernel_netlink_net_t { + + /** + * Implements kernel_net_t interface + */ + kernel_net_t interface; +}; + +/** + * Create a netlink kernel network interface instance. + * + * @return kernel_netlink_net_t instance + */ +kernel_netlink_net_t *kernel_netlink_net_create(); + +#endif /** KERNEL_NETLINK_NET_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c new file mode 100644 index 000000000..8bafc3c55 --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + + +#include "kernel_netlink_plugin.h" + +#include "kernel_netlink_ipsec.h" +#include "kernel_netlink_net.h" + +typedef struct private_kernel_netlink_plugin_t private_kernel_netlink_plugin_t; + +/** + * private data of kernel netlink plugin + */ +struct private_kernel_netlink_plugin_t { + /** + * implements plugin interface + */ + kernel_netlink_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_kernel_netlink_plugin_t *this) +{ + return "kernel-netlink"; +} + +METHOD(plugin_t, get_features, int, + private_kernel_netlink_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(kernel_ipsec_register, kernel_netlink_ipsec_create), + PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"), + PLUGIN_CALLBACK(kernel_net_register, kernel_netlink_net_create), + PLUGIN_PROVIDE(CUSTOM, "kernel-net"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_kernel_netlink_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *kernel_netlink_plugin_create() +{ + private_kernel_netlink_plugin_t *this; + + if (!lib->caps->keep(lib->caps, CAP_NET_ADMIN)) + { /* required to bind/use XFRM sockets / create/modify routing tables, but + * not if only the read-only parts of kernel-netlink-net are used, so + * we don't fail here */ + DBG1(DBG_KNL, "kernel-netlink plugin might require CAP_NET_ADMIN " + "capability"); + } + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h new file mode 100644 index 000000000..74c9ae24f --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_netlink kernel_netlink + * @ingroup cplugins + * + * @defgroup kernel_netlink_plugin kernel_netlink_plugin + * @{ @ingroup kernel_netlink + */ + +#ifndef KERNEL_NETLINK_PLUGIN_H_ +#define KERNEL_NETLINK_PLUGIN_H_ + +#include + +typedef struct kernel_netlink_plugin_t kernel_netlink_plugin_t; + +/** + * netlink kernel interface plugin + */ +struct kernel_netlink_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** KERNEL_NETLINK_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c new file mode 100644 index 000000000..f7ce992a3 --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c @@ -0,0 +1,655 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * 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 +#include +#include +#include + +#include "kernel_netlink_shared.h" + +#include +#include +#include +#include +#include + +typedef struct private_netlink_socket_t private_netlink_socket_t; + +/** + * Private variables and functions of netlink_socket_t class. + */ +struct private_netlink_socket_t { + + /** + * public part of the netlink_socket_t object. + */ + netlink_socket_t public; + + /** + * mutex to lock access entries + */ + mutex_t *mutex; + + /** + * Netlink request entries currently active, uintptr_t seq => entry_t + */ + hashtable_t *entries; + + /** + * Current sequence number for Netlink requests + */ + refcount_t seq; + + /** + * netlink socket + */ + int socket; + + /** + * Netlink protocol + */ + int protocol; + + /** + * Enum names for Netlink messages + */ + enum_name_t *names; + + /** + * Timeout for Netlink replies, in ms + */ + u_int timeout; + + /** + * Number of times to repeat timed out queries + */ + u_int retries; + + /** + * Buffer size for received Netlink messages + */ + u_int buflen; + + /** + * Use parallel netlink queries + */ + bool parallel; + + /** + * Ignore errors potentially resulting from a retransmission + */ + bool ignore_retransmit_errors; +}; + +/** + * #definable hook to simulate request message loss + */ +#ifdef NETLINK_MSG_LOSS_HOOK +bool NETLINK_MSG_LOSS_HOOK(struct nlmsghdr *msg); +#define msg_loss_hook(msg) NETLINK_MSG_LOSS_HOOK(msg) +#else +#define msg_loss_hook(msg) FALSE +#endif + +/** + * Request entry the answer for a waiting thread is collected in + */ +typedef struct { + /** Condition variable thread is waiting */ + condvar_t *condvar; + /** Array of hdrs in a multi-message response, as struct nlmsghdr* */ + array_t *hdrs; + /** All response messages received? */ + bool complete; +} entry_t; + +/** + * Clean up a thread waiting entry + */ +static void destroy_entry(entry_t *entry) +{ + entry->condvar->destroy(entry->condvar); + array_destroy_function(entry->hdrs, (void*)free, NULL); + free(entry); +} + +/** + * Write a Netlink message to socket + */ +static bool write_msg(private_netlink_socket_t *this, struct nlmsghdr *msg) +{ + struct sockaddr_nl addr = { + .nl_family = AF_NETLINK, + }; + int len; + + if (msg_loss_hook(msg)) + { + return TRUE; + } + + while (TRUE) + { + len = sendto(this->socket, msg, msg->nlmsg_len, 0, + (struct sockaddr*)&addr, sizeof(addr)); + if (len != msg->nlmsg_len) + { + if (errno == EINTR) + { + continue; + } + DBG1(DBG_KNL, "netlink write error: %s", strerror(errno)); + return FALSE; + } + return TRUE; + } +} + +/** + * Read a single Netlink message from socket, return 0 on error, -1 on timeout + */ +static ssize_t read_msg(private_netlink_socket_t *this, + char *buf, size_t buflen, bool block) +{ + ssize_t len; + + if (block) + { + fd_set set; + timeval_t tv = {}; + + FD_ZERO(&set); + FD_SET(this->socket, &set); + timeval_add_ms(&tv, this->timeout); + + if (select(this->socket + 1, &set, NULL, NULL, + this->timeout ? &tv : NULL) <= 0) + { + return -1; + } + } + len = recv(this->socket, buf, buflen, MSG_TRUNC|(block ? 0 : MSG_DONTWAIT)); + if (len > buflen) + { + DBG1(DBG_KNL, "netlink response exceeds buffer size"); + return 0; + } + if (len < 0) + { + if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) + { + DBG1(DBG_KNL, "netlink read error: %s", strerror(errno)); + } + return 0; + } + return len; +} + +/** + * Queue received response message + */ +static bool queue(private_netlink_socket_t *this, struct nlmsghdr *buf) +{ + struct nlmsghdr *hdr; + entry_t *entry; + uintptr_t seq; + + seq = (uintptr_t)buf->nlmsg_seq; + + this->mutex->lock(this->mutex); + entry = this->entries->get(this->entries, (void*)seq); + if (entry) + { + hdr = malloc(buf->nlmsg_len); + memcpy(hdr, buf, buf->nlmsg_len); + array_insert(entry->hdrs, ARRAY_TAIL, hdr); + if (hdr->nlmsg_type == NLMSG_DONE || !(hdr->nlmsg_flags & NLM_F_MULTI)) + { + entry->complete = TRUE; + entry->condvar->signal(entry->condvar); + } + } + else + { + DBG1(DBG_KNL, "received unknown netlink seq %u, ignored", seq); + } + this->mutex->unlock(this->mutex); + + return entry != NULL; +} + +/** + * Read and queue response message, optionally blocking, returns TRUE on timeout + */ +static bool read_and_queue(private_netlink_socket_t *this, bool block) +{ + struct nlmsghdr *hdr; + char buf[this->buflen]; + ssize_t len; + + len = read_msg(this, buf, sizeof(buf), block); + if (len == -1) + { + return TRUE; + } + if (len) + { + hdr = (struct nlmsghdr*)buf; + while (NLMSG_OK(hdr, len)) + { + if (!queue(this, hdr)) + { + break; + } + hdr = NLMSG_NEXT(hdr, len); + } + } + return FALSE; +} + +CALLBACK(watch, bool, + private_netlink_socket_t *this, int fd, watcher_event_t event) +{ + if (event == WATCHER_READ) + { + read_and_queue(this, FALSE); + } + return TRUE; +} + +/** + * Send a netlink request, try once + */ +static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in, + uintptr_t seq, struct nlmsghdr **out, size_t *out_len) +{ + struct nlmsghdr *hdr; + chunk_t result = {}; + entry_t *entry; + + in->nlmsg_seq = seq; + in->nlmsg_pid = getpid(); + + if (this->names) + { + DBG3(DBG_KNL, "sending %N %u: %b", this->names, in->nlmsg_type, + (u_int)seq, in, in->nlmsg_len); + } + + this->mutex->lock(this->mutex); + if (!write_msg(this, in)) + { + this->mutex->unlock(this->mutex); + return FAILED; + } + + INIT(entry, + .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), + .hdrs = array_create(0, 0), + ); + this->entries->put(this->entries, (void*)seq, entry); + + while (!entry->complete) + { + if (this->parallel && + lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING) + { + if (this->timeout) + { + if (entry->condvar->timed_wait(entry->condvar, this->mutex, + this->timeout)) + { + break; + } + } + else + { + entry->condvar->wait(entry->condvar, this->mutex); + } + } + else + { /* During (de-)initialization, no watcher thread is active. + * collect responses ourselves. */ + if (read_and_queue(this, TRUE)) + { + break; + } + } + } + this->entries->remove(this->entries, (void*)seq); + + this->mutex->unlock(this->mutex); + + if (!entry->complete) + { /* timeout */ + destroy_entry(entry); + return OUT_OF_RES; + } + + while (array_remove(entry->hdrs, ARRAY_HEAD, &hdr)) + { + if (this->names) + { + DBG3(DBG_KNL, "received %N %u: %b", this->names, hdr->nlmsg_type, + hdr->nlmsg_seq, hdr, hdr->nlmsg_len); + } + result = chunk_cat("mm", result, + chunk_create((char*)hdr, hdr->nlmsg_len)); + } + destroy_entry(entry); + + *out_len = result.len; + *out = (struct nlmsghdr*)result.ptr; + + return SUCCESS; +} + +/** + * Ignore errors for message types that might have completed previously + */ +static void ignore_retransmit_error(private_netlink_socket_t *this, + struct nlmsgerr *err, int type) +{ + switch (err->error) + { + case -EEXIST: + switch (this->protocol) + { + case NETLINK_XFRM: + switch (type) + { + case XFRM_MSG_NEWPOLICY: + case XFRM_MSG_NEWSA: + err->error = 0; + break; + } + break; + case NETLINK_ROUTE: + switch (type) + { + case RTM_NEWADDR: + case RTM_NEWLINK: + case RTM_NEWNEIGH: + case RTM_NEWROUTE: + case RTM_NEWRULE: + err->error = 0; + break; + } + break; + } + break; + case -ENOENT: + switch (this->protocol) + { + case NETLINK_XFRM: + switch (type) + { + case XFRM_MSG_DELPOLICY: + case XFRM_MSG_DELSA: + err->error = 0; + break; + } + break; + case NETLINK_ROUTE: + switch (type) + { + case RTM_DELADDR: + case RTM_DELLINK: + case RTM_DELNEIGH: + case RTM_DELROUTE: + case RTM_DELRULE: + err->error = 0; + break; + } + break; + } + break; + } +} + +METHOD(netlink_socket_t, netlink_send, status_t, + private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out, + size_t *out_len) +{ + uintptr_t seq; + u_int try; + + seq = ref_get(&this->seq); + + for (try = 0; try <= this->retries; ++try) + { + struct nlmsghdr *hdr; + status_t status; + size_t len; + + if (try > 0) + { + DBG1(DBG_KNL, "retransmitting Netlink request (%u/%u)", + try, this->retries); + } + status = send_once(this, in, seq, &hdr, &len); + switch (status) + { + case SUCCESS: + break; + case OUT_OF_RES: + continue; + default: + return status; + } + if (hdr->nlmsg_type == NLMSG_ERROR) + { + struct nlmsgerr* err; + + err = NLMSG_DATA(hdr); + if (err->error == -EBUSY) + { + free(hdr); + try--; + continue; + } + if (this->ignore_retransmit_errors && try > 0) + { + ignore_retransmit_error(this, err, in->nlmsg_type); + } + } + *out = hdr; + *out_len = len; + return SUCCESS; + } + DBG1(DBG_KNL, "Netlink request timed out after %u retransmits", + this->retries); + return OUT_OF_RES; +} + +METHOD(netlink_socket_t, netlink_send_ack, status_t, + private_netlink_socket_t *this, struct nlmsghdr *in) +{ + struct nlmsghdr *out, *hdr; + size_t len; + + if (netlink_send(this, in, &out, &len) != SUCCESS) + { + return FAILED; + } + hdr = out; + while (NLMSG_OK(hdr, len)) + { + switch (hdr->nlmsg_type) + { + case NLMSG_ERROR: + { + struct nlmsgerr* err = NLMSG_DATA(hdr); + + if (err->error) + { + if (-err->error == EEXIST) + { /* do not report existing routes */ + free(out); + return ALREADY_DONE; + } + if (-err->error == ESRCH) + { /* do not report missing entries */ + free(out); + return NOT_FOUND; + } + DBG1(DBG_KNL, "received netlink error: %s (%d)", + strerror(-err->error), -err->error); + free(out); + return FAILED; + } + free(out); + return SUCCESS; + } + default: + hdr = NLMSG_NEXT(hdr, len); + continue; + case NLMSG_DONE: + break; + } + break; + } + DBG1(DBG_KNL, "netlink request not acknowledged"); + free(out); + return FAILED; +} + +METHOD(netlink_socket_t, destroy, void, + private_netlink_socket_t *this) +{ + if (this->socket != -1) + { + if (this->parallel) + { + lib->watcher->remove(lib->watcher, this->socket); + } + close(this->socket); + } + this->entries->destroy(this->entries); + this->mutex->destroy(this->mutex); + free(this); +} + +/** + * Described in header. + */ +netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names, + bool parallel) +{ + private_netlink_socket_t *this; + struct sockaddr_nl addr = { + .nl_family = AF_NETLINK, + }; + + INIT(this, + .public = { + .send = _netlink_send, + .send_ack = _netlink_send_ack, + .destroy = _destroy, + }, + .seq = 200, + .mutex = mutex_create(MUTEX_TYPE_RECURSIVE), + .socket = socket(AF_NETLINK, SOCK_RAW, protocol), + .entries = hashtable_create(hashtable_hash_ptr, hashtable_equals_ptr, 4), + .protocol = protocol, + .names = names, + .buflen = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.buflen", 0, lib->ns), + .timeout = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.timeout", 0, lib->ns), + .retries = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.retries", 0, lib->ns), + .ignore_retransmit_errors = lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.ignore_retransmit_errors", + FALSE, lib->ns), + .parallel = parallel, + ); + + if (!this->buflen) + { + long pagesize = sysconf(_SC_PAGESIZE); + if (pagesize == -1) + { + pagesize = 4096; + } + /* base this on NLMSG_GOODSIZE */ + this->buflen = min(pagesize, 8192); + } + if (this->socket == -1) + { + DBG1(DBG_KNL, "unable to create netlink socket"); + destroy(this); + return NULL; + } + if (bind(this->socket, (struct sockaddr*)&addr, sizeof(addr))) + { + DBG1(DBG_KNL, "unable to bind netlink socket"); + destroy(this); + return NULL; + } + if (this->parallel) + { + lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch, this); + } + + return &this->public; +} + +/** + * Described in header. + */ +void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data, + size_t buflen) +{ + struct rtattr *rta; + + if (NLMSG_ALIGN(hdr->nlmsg_len) + RTA_LENGTH(data.len) > buflen) + { + DBG1(DBG_KNL, "unable to add attribute, buffer too small"); + return; + } + + rta = (struct rtattr*)(((char*)hdr) + NLMSG_ALIGN(hdr->nlmsg_len)); + rta->rta_type = rta_type; + rta->rta_len = RTA_LENGTH(data.len); + memcpy(RTA_DATA(rta), data.ptr, data.len); + hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + rta->rta_len; +} + +/** + * Described in header. + */ +void* netlink_reserve(struct nlmsghdr *hdr, int buflen, int type, int len) +{ + struct rtattr *rta; + + if (NLMSG_ALIGN(hdr->nlmsg_len) + RTA_LENGTH(len) > buflen) + { + DBG1(DBG_KNL, "unable to add attribute, buffer too small"); + return NULL; + } + + rta = ((void*)hdr) + NLMSG_ALIGN(hdr->nlmsg_len); + rta->rta_type = type; + rta->rta_len = RTA_LENGTH(len); + hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + rta->rta_len; + + return RTA_DATA(rta); +} diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h new file mode 100644 index 000000000..b034326d7 --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef KERNEL_NETLINK_SHARED_H_ +#define KERNEL_NETLINK_SHARED_H_ + +#include + +#include + +/** + * Default buffer size. + * + * 1024 byte is currently sufficient for all operations. + */ +#ifndef KERNEL_NETLINK_BUFSIZE +#define KERNEL_NETLINK_BUFSIZE 1024 +#endif + +/** + * General purpose netlink buffer. + * + * Some platforms require an enforced aligment to four bytes (e.g. ARM). + */ +typedef union { + struct nlmsghdr hdr; + u_char bytes[KERNEL_NETLINK_BUFSIZE]; +} netlink_buf_t __attribute__((aligned(RTA_ALIGNTO))); + +typedef struct netlink_socket_t netlink_socket_t; + +/** + * Wrapper around a netlink socket. + */ +struct netlink_socket_t { + + /** + * Send a netlink message and wait for a reply. + * + * @param in netlink message to send + * @param out received netlink message + * @param out_len length of the received message + */ + status_t (*send)(netlink_socket_t *this, struct nlmsghdr *in, + struct nlmsghdr **out, size_t *out_len); + + /** + * Send a netlink message and wait for its acknowledge. + * + * @param in netlink message to send + */ + status_t (*send_ack)(netlink_socket_t *this, struct nlmsghdr *in); + + /** + * Destroy the socket. + */ + void (*destroy)(netlink_socket_t *this); +}; + +/** + * Create a netlink_socket_t object. + * + * @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE) + * @param names optional enum names for Netlink messages + * @param parallel support parallel queries on this Netlink socket + */ +netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names, + bool parallel); + +/** + * Creates an rtattr and adds it to the given netlink message. + * + * @param hdr netlink message + * @param rta_type type of the rtattr + * @param data data to add to the rtattr + * @param buflen length of the netlink message buffer + */ +void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data, + size_t buflen); + +/** + * Reserve space in a netlink message for given size and type, returning buffer. + * + * @param hdr netlink message + * @param buflen size of full netlink buffer + * @param type RTA type + * @param len length of RTA data + * @return buffer to len bytes of attribute data, NULL on error + */ +void* netlink_reserve(struct nlmsghdr *hdr, int buflen, int type, int len); + +#endif /* KERNEL_NETLINK_SHARED_H_ */ diff --git a/src/libcharon/plugins/kernel_netlink/suites/test_socket.c b/src/libcharon/plugins/kernel_netlink/suites/test_socket.c new file mode 100644 index 000000000..3e8facd0a --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/suites/test_socket.c @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * 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 "../kernel_netlink_shared.h" + +/** + * Netlink message drop configuration + */ +static int drop_interval = 0; + +/** + * Netlink message drop hook + */ +bool netlink_msg_loss(struct nlmsghdr *hdr) +{ + static refcount_t i; + + if (drop_interval) + { + return ref_get(&i) % drop_interval == drop_interval - 1; + } + return FALSE; +} + +START_TEST(test_echo) +{ + netlink_socket_t *s; + struct nlmsghdr *out; + struct rtmsg *msg; + char dst[] = { + 127,0,0,1 + }; + size_t len; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)), + .nlmsg_flags = NLM_F_REQUEST, + .nlmsg_type = RTM_GETROUTE, + }, + }; + + msg = NLMSG_DATA(&request.hdr); + msg->rtm_family = AF_INET; + netlink_add_attribute(&request.hdr, RTA_DST, + chunk_from_thing(dst), sizeof(request)); + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE); + free(out); + s->destroy(s); +} +END_TEST + +START_TEST(test_echo_dump) +{ + netlink_socket_t *s; + struct nlmsghdr *out, *current; + struct rtgenmsg *msg; + size_t len; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT, + .nlmsg_type = RTM_GETLINK, + }, + }; + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + msg = NLMSG_DATA(&request.hdr); + msg->rtgen_family = AF_UNSPEC; + + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + current = out; + while (TRUE) + { + ck_assert(NLMSG_OK(current, len)); + if (current->nlmsg_type == NLMSG_DONE) + { + break; + } + ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK); + current = NLMSG_NEXT(current, len); + } + free(out); + s->destroy(s); +} +END_TEST + +CALLBACK(stress, void*, + netlink_socket_t *s) +{ + struct nlmsghdr *out; + struct rtmsg *msg; + char dst[] = { + 127,0,0,1 + }; + size_t len; + int i; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)), + .nlmsg_flags = NLM_F_REQUEST, + .nlmsg_type = RTM_GETROUTE, + }, + }; + + for (i = 0; i < 10; i++) + { + msg = NLMSG_DATA(&request.hdr); + msg->rtm_family = AF_INET; + netlink_add_attribute(&request.hdr, RTA_DST, + chunk_from_thing(dst), sizeof(request)); + + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE); + free(out); + } + return NULL; +} + +CALLBACK(stress_dump, void*, + netlink_socket_t *s) +{ + struct nlmsghdr *out, *current; + struct rtgenmsg *msg; + size_t len; + int i; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT, + .nlmsg_type = RTM_GETLINK, + }, + }; + + msg = NLMSG_DATA(&request.hdr); + msg->rtgen_family = AF_UNSPEC; + + for (i = 0; i < 10; i++) + { + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + current = out; + while (TRUE) + { + ck_assert(NLMSG_OK(current, len)); + if (current->nlmsg_type == NLMSG_DONE) + { + break; + } + ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK); + current = NLMSG_NEXT(current, len); + } + free(out); + } + return NULL; +} + +START_TEST(test_stress) +{ + thread_t *threads[10]; + netlink_socket_t *s; + int i; + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + for (i = 0; i < countof(threads); i++) + { + threads[i] = thread_create(stress, s); + } + for (i = 0; i < countof(threads); i++) + { + threads[i]->join(threads[i]); + } + s->destroy(s); +} +END_TEST + +START_TEST(test_stress_dump) +{ + thread_t *threads[10]; + netlink_socket_t *s; + int i; + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + for (i = 0; i < countof(threads); i++) + { + threads[i] = thread_create(stress_dump, s); + } + for (i = 0; i < countof(threads); i++) + { + threads[i]->join(threads[i]); + } + s->destroy(s); +} +END_TEST + +START_TEST(test_retransmit_success) +{ + netlink_socket_t *s; + struct nlmsghdr *out; + struct rtgenmsg *msg; + size_t len; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT, + .nlmsg_type = RTM_GETLINK, + }, + }; + + drop_interval = 2; + + lib->settings->set_int(lib->settings, + "%s.plugins.kernel-netlink.timeout", 100, lib->ns); + lib->settings->set_int(lib->settings, + "%s.plugins.kernel-netlink.retries", 1, lib->ns); + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + msg = NLMSG_DATA(&request.hdr); + msg->rtgen_family = AF_UNSPEC; + + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + free(out); + s->destroy(s); + + drop_interval = 0; +} +END_TEST + +START_TEST(test_retransmit_fail) +{ + netlink_socket_t *s; + struct nlmsghdr *out; + struct rtgenmsg *msg; + size_t len; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT, + .nlmsg_type = RTM_GETLINK, + }, + }; + + drop_interval = 1; + + lib->settings->set_int(lib->settings, + "%s.plugins.kernel-netlink.timeout", 50, lib->ns); + lib->settings->set_int(lib->settings, + "%s.plugins.kernel-netlink.retries", 3, lib->ns); + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + msg = NLMSG_DATA(&request.hdr); + msg->rtgen_family = AF_UNSPEC; + + ck_assert(s->send(s, &request.hdr, &out, &len) == OUT_OF_RES); + s->destroy(s); + + drop_interval = 0; +} +END_TEST + +Suite *socket_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("netlink socket"); + + tc = tcase_create("echo"); + tcase_add_loop_test(tc, test_echo, 0, 2); + tcase_add_loop_test(tc, test_echo_dump, 0, 2); + suite_add_tcase(s, tc); + + tc = tcase_create("stress"); + tcase_add_loop_test(tc, test_stress, 0, 2); + tcase_add_loop_test(tc, test_stress_dump, 0, 2); + suite_add_tcase(s, tc); + + tc = tcase_create("retransmit"); + tcase_add_loop_test(tc, test_retransmit_success, 0, 2); + tcase_add_loop_test(tc, test_retransmit_fail, 0, 2); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libcharon/plugins/kernel_netlink/tests.c b/src/libcharon/plugins/kernel_netlink/tests.c new file mode 100644 index 000000000..a1799ea70 --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/tests.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * 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 + +/* declare test suite constructors */ +#define TEST_SUITE(x) test_suite_t* x(); +#include "tests.h" +#undef TEST_SUITE + +static test_configuration_t tests[] = { +#define TEST_SUITE(x) \ + { .suite = x, }, +#include "tests.h" + { .suite = NULL, } +}; + +static bool test_runner_init(bool init) +{ + if (init) + { + lib->processor->set_threads(lib->processor, 8); + } + else + { + lib->processor->set_threads(lib->processor, 0); + lib->processor->cancel(lib->processor); + } + return TRUE; +} + +int main(int argc, char *argv[]) +{ + return test_runner_run("kernel-netlink", tests, test_runner_init); +} diff --git a/src/libcharon/plugins/kernel_netlink/tests.h b/src/libcharon/plugins/kernel_netlink/tests.h new file mode 100644 index 000000000..2b6715a78 --- /dev/null +++ b/src/libcharon/plugins/kernel_netlink/tests.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * 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. + */ + +TEST_SUITE(socket_suite_create) diff --git a/src/libcharon/plugins/kernel_pfkey/Makefile.am b/src/libcharon/plugins/kernel_pfkey/Makefile.am new file mode 100644 index 000000000..8fdca93a5 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfkey/Makefile.am @@ -0,0 +1,19 @@ +AM_CPPFLAGS = \ + -I${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-kernel-pfkey.la +else +plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la +endif + +libstrongswan_kernel_pfkey_la_SOURCES = \ + kernel_pfkey_plugin.h kernel_pfkey_plugin.c \ + kernel_pfkey_ipsec.h kernel_pfkey_ipsec.c + +libstrongswan_kernel_pfkey_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/kernel_pfkey/Makefile.in b/src/libcharon/plugins/kernel_pfkey/Makefile.in new file mode 100644 index 000000000..f2876a272 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfkey/Makefile.in @@ -0,0 +1,782 @@ +# 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/kernel_pfkey +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_kernel_pfkey_la_LIBADD = +am_libstrongswan_kernel_pfkey_la_OBJECTS = kernel_pfkey_plugin.lo \ + kernel_pfkey_ipsec.lo +libstrongswan_kernel_pfkey_la_OBJECTS = \ + $(am_libstrongswan_kernel_pfkey_la_OBJECTS) +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_kernel_pfkey_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_kernel_pfkey_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_kernel_pfkey_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_kernel_pfkey_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_kernel_pfkey_la_SOURCES) +DIST_SOURCES = $(libstrongswan_kernel_pfkey_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@ +EASY_INSTALL = @EASY_INSTALL@ +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@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +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@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +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_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ +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${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-pfkey.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la +libstrongswan_kernel_pfkey_la_SOURCES = \ + kernel_pfkey_plugin.h kernel_pfkey_plugin.c \ + kernel_pfkey_ipsec.h kernel_pfkey_ipsec.c + +libstrongswan_kernel_pfkey_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/kernel_pfkey/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfkey/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-kernel-pfkey.la: $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_DEPENDENCIES) $(EXTRA_libstrongswan_kernel_pfkey_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_kernel_pfkey_la_LINK) $(am_libstrongswan_kernel_pfkey_la_rpath) $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfkey_ipsec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfkey_plugin.Plo@am__quote@ + +.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/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c new file mode 100644 index 000000000..d505f1c33 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -0,0 +1,3094 @@ +/* + * Copyright (C) 2008-2015 Tobias Brunner + * Copyright (C) 2008 Andreas Steffen + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +/* + * Copyright (C) 2014 Nanoteq Pty Ltd + * + * 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 + +#ifdef __FreeBSD__ +#include /* for LONG_MAX */ +#endif + +#ifdef HAVE_NET_PFKEYV2_H +#include +#else +#include +#endif + +#ifdef SADB_X_EXT_NAT_T_TYPE +#define HAVE_NATT +#endif + +#ifdef HAVE_NETIPSEC_IPSEC_H +#include +#elif defined(HAVE_NETINET6_IPSEC_H) +#include +#else +#include +#endif + +#ifdef HAVE_NATT +#ifdef HAVE_LINUX_UDP_H +#include +#else +#include +#endif /*HAVE_LINUX_UDP_H*/ +#endif /*HAVE_NATT*/ + +#include +#include +#include +#ifdef __APPLE__ +#include +#endif + +#include "kernel_pfkey_ipsec.h" + +#include +#include +#include +#include +#include +#include + +/** non linux specific */ +#ifndef IPPROTO_COMP +#ifdef IPPROTO_IPCOMP +#define IPPROTO_COMP IPPROTO_IPCOMP +#endif +#endif + +#ifndef SADB_X_AALG_SHA2_256HMAC +#define SADB_X_AALG_SHA2_256HMAC SADB_X_AALG_SHA2_256 +#define SADB_X_AALG_SHA2_384HMAC SADB_X_AALG_SHA2_384 +#define SADB_X_AALG_SHA2_512HMAC SADB_X_AALG_SHA2_512 +#endif + +#ifndef SADB_X_EALG_AESCBC +#define SADB_X_EALG_AESCBC SADB_X_EALG_AES +#endif + +#ifndef SADB_X_EALG_CASTCBC +#define SADB_X_EALG_CASTCBC SADB_X_EALG_CAST128CBC +#endif + +#if !defined(SADB_X_EALG_AES_GCM_ICV8) && defined(SADB_X_EALG_AESGCM8) +#define SADB_X_EALG_AES_GCM_ICV8 SADB_X_EALG_AESGCM8 +#define SADB_X_EALG_AES_GCM_ICV12 SADB_X_EALG_AESGCM12 +#define SADB_X_EALG_AES_GCM_ICV16 SADB_X_EALG_AESGCM16 +#endif + +#ifndef SOL_IP +#define SOL_IP IPPROTO_IP +#define SOL_IPV6 IPPROTO_IPV6 +#endif + +/** from linux/in.h */ +#ifndef IP_IPSEC_POLICY +#define IP_IPSEC_POLICY 16 +#endif + +/** missing on uclibc */ +#ifndef IPV6_IPSEC_POLICY +#define IPV6_IPSEC_POLICY 34 +#endif + +/* from linux/udp.h */ +#ifndef UDP_ENCAP +#define UDP_ENCAP 100 +#endif + +#ifndef UDP_ENCAP_ESPINUDP +#define UDP_ENCAP_ESPINUDP 2 +#endif + +/* this is not defined on some platforms */ +#ifndef SOL_UDP +#define SOL_UDP IPPROTO_UDP +#endif + +/** base priority for installed policies */ +#define PRIO_BASE 384 + +#ifdef __APPLE__ +/** from xnu/bsd/net/pfkeyv2.h */ +#define SADB_X_EXT_NATT 0x002 + struct sadb_sa_2 { + struct sadb_sa sa; + u_int16_t sadb_sa_natt_port; + u_int16_t sadb_reserved0; + u_int32_t sadb_reserved1; + }; +#endif + +/** buffer size for PF_KEY messages */ +#define PFKEY_BUFFER_SIZE 4096 + +/** PF_KEY messages are 64 bit aligned */ +#define PFKEY_ALIGNMENT 8 +/** aligns len to 64 bits */ +#define PFKEY_ALIGN(len) (((len) + PFKEY_ALIGNMENT - 1) & ~(PFKEY_ALIGNMENT - 1)) +/** calculates the properly padded length in 64 bit chunks */ +#define PFKEY_LEN(len) ((PFKEY_ALIGN(len) / PFKEY_ALIGNMENT)) +/** calculates user mode length i.e. in bytes */ +#define PFKEY_USER_LEN(len) ((len) * PFKEY_ALIGNMENT) + +/** given a PF_KEY message header and an extension this updates the length in the header */ +#define PFKEY_EXT_ADD(msg, ext) ((msg)->sadb_msg_len += ((struct sadb_ext*)ext)->sadb_ext_len) +/** given a PF_KEY message header this returns a pointer to the next extension */ +#define PFKEY_EXT_ADD_NEXT(msg) ((struct sadb_ext*)(((char*)(msg)) + PFKEY_USER_LEN((msg)->sadb_msg_len))) +/** copy an extension and append it to a PF_KEY message */ +#define PFKEY_EXT_COPY(msg, ext) (PFKEY_EXT_ADD(msg, memcpy(PFKEY_EXT_ADD_NEXT(msg), ext, PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len)))) +/** given a PF_KEY extension this returns a pointer to the next extension */ +#define PFKEY_EXT_NEXT(ext) ((struct sadb_ext*)(((char*)(ext)) + PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len))) +/** given a PF_KEY extension this returns a pointer to the next extension also updates len (len in 64 bit words) */ +#define PFKEY_EXT_NEXT_LEN(ext,len) ((len) -= (ext)->sadb_ext_len, PFKEY_EXT_NEXT(ext)) +/** true if ext has a valid length and len is large enough to contain ext (assuming len in 64 bit words) */ +#define PFKEY_EXT_OK(ext,len) ((len) >= PFKEY_LEN(sizeof(struct sadb_ext)) && \ + (ext)->sadb_ext_len >= PFKEY_LEN(sizeof(struct sadb_ext)) && \ + (ext)->sadb_ext_len <= (len)) + +typedef struct private_kernel_pfkey_ipsec_t private_kernel_pfkey_ipsec_t; + +/** + * Private variables and functions of kernel_pfkey class. + */ +struct private_kernel_pfkey_ipsec_t +{ + /** + * Public part of the kernel_pfkey_t object. + */ + kernel_pfkey_ipsec_t public; + + /** + * mutex to lock access to various lists + */ + mutex_t *mutex; + + /** + * List of installed policies (policy_entry_t) + */ + linked_list_t *policies; + + /** + * List of exclude routes (exclude_route_t) + */ + linked_list_t *excludes; + + /** + * Hash table of IPsec SAs using policies (ipsec_sa_t) + */ + hashtable_t *sas; + + /** + * whether to install routes along policies + */ + bool install_routes; + + /** + * mutex to lock access to the PF_KEY socket + */ + mutex_t *mutex_pfkey; + + /** + * PF_KEY socket to communicate with the kernel + */ + int socket; + + /** + * PF_KEY socket to receive acquire and expire events + */ + int socket_events; + + /** + * sequence number for messages sent to the kernel + */ + int seq; +}; + +typedef struct exclude_route_t exclude_route_t; + +/** + * Exclude route definition + */ +struct exclude_route_t { + /** destination address of exclude */ + host_t *dst; + /** source address for route */ + host_t *src; + /** nexthop exclude has been installed */ + host_t *gtw; + /** references to this route */ + int refs; +}; + +/** + * clean up a route exclude entry + */ +static void exclude_route_destroy(exclude_route_t *this) +{ + this->dst->destroy(this->dst); + this->src->destroy(this->src); + this->gtw->destroy(this->gtw); + free(this); +} + +typedef struct route_entry_t route_entry_t; + +/** + * installed routing entry + */ +struct route_entry_t { + /** name of the interface the route is bound to */ + char *if_name; + + /** source ip of the route */ + host_t *src_ip; + + /** gateway for this route */ + host_t *gateway; + + /** destination net */ + chunk_t dst_net; + + /** destination net prefixlen */ + u_int8_t prefixlen; + + /** reference to exclude route, if any */ + exclude_route_t *exclude; +}; + +/** + * destroy an route_entry_t object + */ +static void route_entry_destroy(route_entry_t *this) +{ + free(this->if_name); + DESTROY_IF(this->src_ip); + DESTROY_IF(this->gateway); + chunk_free(&this->dst_net); + free(this); +} + +/** + * compare two route_entry_t objects + */ +static bool route_entry_equals(route_entry_t *a, route_entry_t *b) +{ + return a->if_name && b->if_name && streq(a->if_name, b->if_name) && + a->src_ip->ip_equals(a->src_ip, b->src_ip) && + a->gateway && b->gateway && + a->gateway->ip_equals(a->gateway, b->gateway) && + chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen; +} + +typedef struct ipsec_sa_t ipsec_sa_t; + +/** + * IPsec SA assigned to a policy. + */ +struct ipsec_sa_t { + /** Source address of this SA */ + host_t *src; + + /** Destination address of this SA */ + host_t *dst; + + /** Description of this SA */ + ipsec_sa_cfg_t cfg; + + /** Reference count for this SA */ + refcount_t refcount; +}; + +/** + * Hash function for ipsec_sa_t objects + */ +static u_int ipsec_sa_hash(ipsec_sa_t *sa) +{ + return chunk_hash_inc(sa->src->get_address(sa->src), + chunk_hash_inc(sa->dst->get_address(sa->dst), + chunk_hash(chunk_from_thing(sa->cfg)))); +} + +/** + * Equality function for ipsec_sa_t objects + */ +static bool ipsec_sa_equals(ipsec_sa_t *sa, ipsec_sa_t *other_sa) +{ + return sa->src->ip_equals(sa->src, other_sa->src) && + sa->dst->ip_equals(sa->dst, other_sa->dst) && + memeq(&sa->cfg, &other_sa->cfg, sizeof(ipsec_sa_cfg_t)); +} + +/** + * Allocate or reference an IPsec SA object + */ +static ipsec_sa_t *ipsec_sa_create(private_kernel_pfkey_ipsec_t *this, + host_t *src, host_t *dst, + ipsec_sa_cfg_t *cfg) +{ + ipsec_sa_t *sa, *found; + INIT(sa, + .src = src, + .dst = dst, + .cfg = *cfg, + ); + found = this->sas->get(this->sas, sa); + if (!found) + { + sa->src = src->clone(src); + sa->dst = dst->clone(dst); + this->sas->put(this->sas, sa, sa); + } + else + { + free(sa); + sa = found; + } + ref_get(&sa->refcount); + return sa; +} + +/** + * Release and destroy an IPsec SA object + */ +static void ipsec_sa_destroy(private_kernel_pfkey_ipsec_t *this, + ipsec_sa_t *sa) +{ + if (ref_put(&sa->refcount)) + { + this->sas->remove(this->sas, sa); + DESTROY_IF(sa->src); + DESTROY_IF(sa->dst); + free(sa); + } +} + +typedef struct policy_sa_t policy_sa_t; +typedef struct policy_sa_in_t policy_sa_in_t; + +/** + * Mapping between a policy and an IPsec SA. + */ +struct policy_sa_t { + /** Priority assigned to the policy when installed with this SA */ + u_int32_t priority; + + /** Type of the policy */ + policy_type_t type; + + /** Assigned SA */ + ipsec_sa_t *sa; +}; + +/** + * For input policies we also cache the traffic selectors in order to install + * the route. + */ +struct policy_sa_in_t { + /** Generic interface */ + policy_sa_t generic; + + /** Source traffic selector of this policy */ + traffic_selector_t *src_ts; + + /** Destination traffic selector of this policy */ + traffic_selector_t *dst_ts; +}; + +/** + * Create a policy_sa(_in)_t object + */ +static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this, + policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, ipsec_sa_cfg_t *cfg) +{ + policy_sa_t *policy; + + if (dir == POLICY_IN) + { + policy_sa_in_t *in; + INIT(in, + .src_ts = src_ts->clone(src_ts), + .dst_ts = dst_ts->clone(dst_ts), + ); + policy = &in->generic; + } + else + { + INIT(policy, .priority = 0); + } + policy->type = type; + policy->sa = ipsec_sa_create(this, src, dst, cfg); + return policy; +} + +/** + * Destroy a policy_sa(_in)_t object + */ +static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, + private_kernel_pfkey_ipsec_t *this) +{ + if (*dir == POLICY_IN) + { + policy_sa_in_t *in = (policy_sa_in_t*)policy; + in->src_ts->destroy(in->src_ts); + in->dst_ts->destroy(in->dst_ts); + } + ipsec_sa_destroy(this, policy->sa); + free(policy); +} + +typedef struct policy_entry_t policy_entry_t; + +/** + * installed kernel policy. + */ +struct policy_entry_t { + /** Index assigned by the kernel */ + u_int32_t index; + + /** Direction of this policy: in, out, forward */ + u_int8_t direction; + + /** Parameters of installed policy */ + struct { + /** Subnet and port */ + host_t *net; + /** Subnet mask */ + u_int8_t mask; + /** Protocol */ + u_int8_t proto; + } src, dst; + + /** Associated route installed for this policy */ + route_entry_t *route; + + /** List of SAs this policy is used by, ordered by priority */ + linked_list_t *used_by; +}; + +/** + * Create a policy_entry_t object + */ +static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, + policy_dir_t dir) +{ + policy_entry_t *policy; + INIT(policy, + .direction = dir, + ); + u_int16_t port; + u_int8_t proto; + + src_ts->to_subnet(src_ts, &policy->src.net, &policy->src.mask); + dst_ts->to_subnet(dst_ts, &policy->dst.net, &policy->dst.mask); + + /* src or dest proto may be "any" (0), use more restrictive one */ + proto = max(src_ts->get_protocol(src_ts), dst_ts->get_protocol(dst_ts)); + /* map the ports to ICMP type/code how the Linux kernel expects them, that + * is, type in src, code in dst */ + if (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6) + { + port = max(policy->src.net->get_port(policy->src.net), + policy->dst.net->get_port(policy->dst.net)); + policy->src.net->set_port(policy->src.net, + traffic_selector_icmp_type(port)); + policy->dst.net->set_port(policy->dst.net, + traffic_selector_icmp_code(port)); + } + else if (!proto) + { + proto = IPSEC_PROTO_ANY; + } + policy->src.proto = policy->dst.proto = proto; + + return policy; +} + +/** + * Destroy a policy_entry_t object + */ +static void policy_entry_destroy(policy_entry_t *policy, + private_kernel_pfkey_ipsec_t *this) +{ + if (policy->route) + { + route_entry_destroy(policy->route); + } + if (policy->used_by) + { + policy->used_by->invoke_function(policy->used_by, + (linked_list_invoke_t)policy_sa_destroy, + &policy->direction, this); + policy->used_by->destroy(policy->used_by); + } + DESTROY_IF(policy->src.net); + DESTROY_IF(policy->dst.net); + free(policy); +} + +/** + * compares two policy_entry_t + */ +static inline bool policy_entry_equals(policy_entry_t *current, + policy_entry_t *policy) +{ + return current->direction == policy->direction && + current->src.proto == policy->src.proto && + current->dst.proto == policy->dst.proto && + current->src.mask == policy->src.mask && + current->dst.mask == policy->dst.mask && + current->src.net->equals(current->src.net, policy->src.net) && + current->dst.net->equals(current->dst.net, policy->dst.net); +} + +/** + * compare the given kernel index with that of a policy + */ +static inline bool policy_entry_match_byindex(policy_entry_t *current, + u_int32_t *index) +{ + return current->index == *index; +} + +/** + * Calculate the priority of a policy + */ +static inline u_int32_t get_priority(policy_entry_t *policy, + policy_priority_t prio) +{ + u_int32_t priority = PRIO_BASE; + switch (prio) + { + case POLICY_PRIORITY_FALLBACK: + priority <<= 1; + /* fall-through */ + case POLICY_PRIORITY_ROUTED: + priority <<= 1; + /* fall-through */ + case POLICY_PRIORITY_DEFAULT: + priority <<= 1; + /* fall-trough */ + case POLICY_PRIORITY_PASS: + break; + } + /* calculate priority based on selector size, small size = high prio */ + priority -= policy->src.mask; + priority -= policy->dst.mask; + priority <<= 2; /* make some room for the two flags */ + priority += policy->src.net->get_port(policy->src.net) || + policy->dst.net->get_port(policy->dst.net) ? + 0 : 2; + priority += policy->src.proto != IPSEC_PROTO_ANY ? 0 : 1; + return priority; +} + +typedef struct pfkey_msg_t pfkey_msg_t; + +struct pfkey_msg_t +{ + /** + * PF_KEY message base + */ + struct sadb_msg *msg; + + /** + * PF_KEY message extensions + */ + union { + struct sadb_ext *ext[SADB_EXT_MAX + 1]; + struct { + struct sadb_ext *reserved; /* SADB_EXT_RESERVED */ + struct sadb_sa *sa; /* SADB_EXT_SA */ + struct sadb_lifetime *lft_current; /* SADB_EXT_LIFETIME_CURRENT */ + struct sadb_lifetime *lft_hard; /* SADB_EXT_LIFETIME_HARD */ + struct sadb_lifetime *lft_soft; /* SADB_EXT_LIFETIME_SOFT */ + struct sadb_address *src; /* SADB_EXT_ADDRESS_SRC */ + struct sadb_address *dst; /* SADB_EXT_ADDRESS_DST */ + struct sadb_address *proxy; /* SADB_EXT_ADDRESS_PROXY */ + struct sadb_key *key_auth; /* SADB_EXT_KEY_AUTH */ + struct sadb_key *key_encr; /* SADB_EXT_KEY_ENCRYPT */ + struct sadb_ident *id_src; /* SADB_EXT_IDENTITY_SRC */ + struct sadb_ident *id_dst; /* SADB_EXT_IDENTITY_DST */ + struct sadb_sens *sensitivity; /* SADB_EXT_SENSITIVITY */ + struct sadb_prop *proposal; /* SADB_EXT_PROPOSAL */ + struct sadb_supported *supported_auth; /* SADB_EXT_SUPPORTED_AUTH */ + struct sadb_supported *supported_encr; /* SADB_EXT_SUPPORTED_ENCRYPT */ + struct sadb_spirange *spirange; /* SADB_EXT_SPIRANGE */ + struct sadb_x_kmprivate *x_kmprivate; /* SADB_X_EXT_KMPRIVATE */ + struct sadb_x_policy *x_policy; /* SADB_X_EXT_POLICY */ + struct sadb_x_sa2 *x_sa2; /* SADB_X_EXT_SA2 */ + struct sadb_x_nat_t_type *x_natt_type; /* SADB_X_EXT_NAT_T_TYPE */ + struct sadb_x_nat_t_port *x_natt_sport; /* SADB_X_EXT_NAT_T_SPORT */ + struct sadb_x_nat_t_port *x_natt_dport; /* SADB_X_EXT_NAT_T_DPORT */ + struct sadb_address *x_natt_oa; /* SADB_X_EXT_NAT_T_OA */ + struct sadb_x_sec_ctx *x_sec_ctx; /* SADB_X_EXT_SEC_CTX */ + struct sadb_x_kmaddress *x_kmaddress; /* SADB_X_EXT_KMADDRESS */ + } __attribute__((__packed__)); + }; +}; + +ENUM(sadb_ext_type_names, SADB_EXT_RESERVED, SADB_EXT_MAX, + "SADB_EXT_RESERVED", + "SADB_EXT_SA", + "SADB_EXT_LIFETIME_CURRENT", + "SADB_EXT_LIFETIME_HARD", + "SADB_EXT_LIFETIME_SOFT", + "SADB_EXT_ADDRESS_SRC", + "SADB_EXT_ADDRESS_DST", + "SADB_EXT_ADDRESS_PROXY", + "SADB_EXT_KEY_AUTH", + "SADB_EXT_KEY_ENCRYPT", + "SADB_EXT_IDENTITY_SRC", + "SADB_EXT_IDENTITY_DST", + "SADB_EXT_SENSITIVITY", + "SADB_EXT_PROPOSAL", + "SADB_EXT_SUPPORTED_AUTH", + "SADB_EXT_SUPPORTED_ENCRYPT", + "SADB_EXT_SPIRANGE", + "SADB_X_EXT_KMPRIVATE", + "SADB_X_EXT_POLICY", + "SADB_X_EXT_SA2", + "SADB_X_EXT_NAT_T_TYPE", + "SADB_X_EXT_NAT_T_SPORT", + "SADB_X_EXT_NAT_T_DPORT", + "SADB_X_EXT_NAT_T_OA", + "SADB_X_EXT_SEC_CTX", + "SADB_X_EXT_KMADDRESS" +); + +/** + * convert a protocol identifier to the PF_KEY sa type + */ +static u_int8_t proto2satype(u_int8_t proto) +{ + switch (proto) + { + case IPPROTO_ESP: + return SADB_SATYPE_ESP; + case IPPROTO_AH: + return SADB_SATYPE_AH; + case IPPROTO_COMP: + return SADB_X_SATYPE_IPCOMP; + default: + return proto; + } +} + +/** + * convert a PF_KEY sa type to a protocol identifier + */ +static u_int8_t satype2proto(u_int8_t satype) +{ + switch (satype) + { + case SADB_SATYPE_ESP: + return IPPROTO_ESP; + case SADB_SATYPE_AH: + return IPPROTO_AH; + case SADB_X_SATYPE_IPCOMP: + return IPPROTO_COMP; + default: + return satype; + } +} + +/** + * convert the general ipsec mode to the one defined in ipsec.h + */ +static u_int8_t mode2kernel(ipsec_mode_t mode) +{ + switch (mode) + { + case MODE_TRANSPORT: + return IPSEC_MODE_TRANSPORT; + case MODE_TUNNEL: + return IPSEC_MODE_TUNNEL; +#ifdef HAVE_IPSEC_MODE_BEET + case MODE_BEET: + return IPSEC_MODE_BEET; +#endif + default: + return mode; + } +} + +/** + * convert the general policy direction to the one defined in ipsec.h + */ +static u_int8_t dir2kernel(policy_dir_t dir) +{ + switch (dir) + { + case POLICY_IN: + return IPSEC_DIR_INBOUND; + case POLICY_OUT: + return IPSEC_DIR_OUTBOUND; +#ifdef HAVE_IPSEC_DIR_FWD + case POLICY_FWD: + return IPSEC_DIR_FWD; +#endif + default: + return IPSEC_DIR_INVALID; + } +} + +/** + * convert the policy type to the one defined in ipsec.h + */ +static inline u_int16_t type2kernel(policy_type_t type) +{ + switch (type) + { + case POLICY_IPSEC: + return IPSEC_POLICY_IPSEC; + case POLICY_PASS: + return IPSEC_POLICY_NONE; + case POLICY_DROP: + return IPSEC_POLICY_DISCARD; + } + return type; +} + +#ifdef SADB_X_MIGRATE +/** + * convert the policy direction in ipsec.h to the general one. + */ +static policy_dir_t kernel2dir(u_int8_t dir) +{ + switch (dir) + { + case IPSEC_DIR_INBOUND: + return POLICY_IN; + case IPSEC_DIR_OUTBOUND: + return POLICY_OUT; +#ifdef HAVE_IPSEC_DIR_FWD + case IPSEC_DIR_FWD: + return POLICY_FWD; +#endif + default: + return dir; + } +} +#endif /*SADB_X_MIGRATE*/ + +typedef struct kernel_algorithm_t kernel_algorithm_t; + +/** + * Mapping of IKEv2 algorithms to PF_KEY algorithms + */ +struct kernel_algorithm_t { + /** + * Identifier specified in IKEv2 + */ + int ikev2; + + /** + * Identifier as defined in pfkeyv2.h + */ + int kernel; +}; + +#define END_OF_LIST -1 + +/** + * Algorithms for encryption + */ +static kernel_algorithm_t encryption_algs[] = { +/* {ENCR_DES_IV64, 0 }, */ + {ENCR_DES, SADB_EALG_DESCBC }, + {ENCR_3DES, SADB_EALG_3DESCBC }, +/* {ENCR_RC5, 0 }, */ +/* {ENCR_IDEA, 0 }, */ + {ENCR_CAST, SADB_X_EALG_CASTCBC }, + {ENCR_BLOWFISH, SADB_X_EALG_BLOWFISHCBC }, +/* {ENCR_3IDEA, 0 }, */ +/* {ENCR_DES_IV32, 0 }, */ + {ENCR_NULL, SADB_EALG_NULL }, + {ENCR_AES_CBC, SADB_X_EALG_AESCBC }, +#ifdef SADB_X_EALG_AESCTR + {ENCR_AES_CTR, SADB_X_EALG_AESCTR }, +#endif +/* {ENCR_AES_CCM_ICV8, SADB_X_EALG_AES_CCM_ICV8 }, */ +/* {ENCR_AES_CCM_ICV12, SADB_X_EALG_AES_CCM_ICV12 }, */ +/* {ENCR_AES_CCM_ICV16, SADB_X_EALG_AES_CCM_ICV16 }, */ +#ifdef SADB_X_EALG_AES_GCM_ICV8 /* assume the others are defined too */ + {ENCR_AES_GCM_ICV8, SADB_X_EALG_AES_GCM_ICV8 }, + {ENCR_AES_GCM_ICV12, SADB_X_EALG_AES_GCM_ICV12 }, + {ENCR_AES_GCM_ICV16, SADB_X_EALG_AES_GCM_ICV16 }, +#endif +#ifdef SADB_X_EALG_CAMELLIACBC + {ENCR_CAMELLIA_CBC, SADB_X_EALG_CAMELLIACBC }, +#endif + {END_OF_LIST, 0 }, +}; + +/** + * Algorithms for integrity protection + */ +static kernel_algorithm_t integrity_algs[] = { + {AUTH_HMAC_MD5_96, SADB_AALG_MD5HMAC }, + {AUTH_HMAC_SHA1_96, SADB_AALG_SHA1HMAC }, + {AUTH_HMAC_SHA2_256_128, SADB_X_AALG_SHA2_256HMAC }, + {AUTH_HMAC_SHA2_384_192, SADB_X_AALG_SHA2_384HMAC }, + {AUTH_HMAC_SHA2_512_256, SADB_X_AALG_SHA2_512HMAC }, +/* {AUTH_DES_MAC, 0, }, */ +/* {AUTH_KPDK_MD5, 0, }, */ +#ifdef SADB_X_AALG_AES_XCBC_MAC + {AUTH_AES_XCBC_96, SADB_X_AALG_AES_XCBC_MAC, }, +#endif + {END_OF_LIST, 0, }, +}; + +/** + * Algorithms for IPComp, unused yet + */ +static kernel_algorithm_t compression_algs[] = { +/* {IPCOMP_OUI, 0 }, */ + {IPCOMP_DEFLATE, SADB_X_CALG_DEFLATE }, +#ifdef SADB_X_CALG_LZS + {IPCOMP_LZS, SADB_X_CALG_LZS }, +#endif +#ifdef SADB_X_CALG_LZJH + {IPCOMP_LZJH, SADB_X_CALG_LZJH }, +#endif + {END_OF_LIST, 0 }, +}; + +/** + * Look up a kernel algorithm ID and its key size + */ +static int lookup_algorithm(transform_type_t type, int ikev2) +{ + kernel_algorithm_t *list; + u_int16_t alg = 0; + + switch (type) + { + case ENCRYPTION_ALGORITHM: + list = encryption_algs; + break; + case INTEGRITY_ALGORITHM: + list = integrity_algs; + break; + case COMPRESSION_ALGORITHM: + list = compression_algs; + break; + default: + return 0; + } + while (list->ikev2 != END_OF_LIST) + { + if (ikev2 == list->ikev2) + { + return list->kernel; + } + list++; + } + charon->kernel->lookup_algorithm(charon->kernel, ikev2, type, &alg, NULL); + return alg; +} + +/** + * Helper to set a port in a sockaddr_t, the port has to be in host order + */ +static void set_port(sockaddr_t *addr, u_int16_t port) +{ + switch (addr->sa_family) + { + case AF_INET: + { + struct sockaddr_in *sin = (struct sockaddr_in*)addr; + sin->sin_port = htons(port); + break; + } + case AF_INET6: + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)addr; + sin6->sin6_port = htons(port); + break; + } + } +} + +/** + * Copy a host_t as sockaddr_t to the given memory location. + * @return the number of bytes copied + */ +static size_t hostcpy(void *dest, host_t *host, bool include_port) +{ + sockaddr_t *addr = host->get_sockaddr(host), *dest_addr = dest; + socklen_t *len = host->get_sockaddr_len(host); + + memcpy(dest, addr, *len); +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + dest_addr->sa_len = *len; +#endif + if (!include_port) + { + set_port(dest_addr, 0); + } + return *len; +} + +/** + * add a host to the given sadb_msg + */ +static void add_addr_ext(struct sadb_msg *msg, host_t *host, u_int16_t type, + u_int8_t proto, u_int8_t prefixlen, bool include_port) +{ + struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg); + size_t len; + + addr->sadb_address_exttype = type; + addr->sadb_address_proto = proto; + addr->sadb_address_prefixlen = prefixlen; + len = hostcpy(addr + 1, host, include_port); + addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len); + PFKEY_EXT_ADD(msg, addr); +} + +/** + * adds an empty address extension to the given sadb_msg + */ +static void add_anyaddr_ext(struct sadb_msg *msg, int family, u_int8_t type) +{ + socklen_t len = (family == AF_INET) ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6); + struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg); + addr->sadb_address_exttype = type; + sockaddr_t *saddr = (sockaddr_t*)(addr + 1); + saddr->sa_family = family; +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + saddr->sa_len = len; +#endif + addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len); + PFKEY_EXT_ADD(msg, addr); +} + +#ifdef HAVE_NATT +/** + * add udp encap extensions to a sadb_msg + */ +static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst) +{ + struct sadb_x_nat_t_type* nat_type; + struct sadb_x_nat_t_port* nat_port; + + nat_type = (struct sadb_x_nat_t_type*)PFKEY_EXT_ADD_NEXT(msg); + nat_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + nat_type->sadb_x_nat_t_type_len = PFKEY_LEN(sizeof(*nat_type)); + nat_type->sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP; + PFKEY_EXT_ADD(msg, nat_type); + + nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg); + nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT; + nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(*nat_port)); + nat_port->sadb_x_nat_t_port_port = htons(src->get_port(src)); + PFKEY_EXT_ADD(msg, nat_port); + + nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg); + nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT; + nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(*nat_port)); + nat_port->sadb_x_nat_t_port_port = htons(dst->get_port(dst)); + PFKEY_EXT_ADD(msg, nat_port); +} +#endif /*HAVE_NATT*/ + +/** + * Convert a sadb_address to a traffic_selector + */ +static traffic_selector_t* sadb_address2ts(struct sadb_address *address) +{ + traffic_selector_t *ts; + host_t *host; + u_int8_t proto; + + proto = address->sadb_address_proto; + proto = proto == IPSEC_PROTO_ANY ? 0 : proto; + + /* The Linux 2.6 kernel does not set the protocol and port information + * in the src and dst sadb_address extensions of the SADB_ACQUIRE message. + */ + host = host_create_from_sockaddr((sockaddr_t*)&address[1]); + ts = traffic_selector_create_from_subnet(host, + address->sadb_address_prefixlen, + proto, host->get_port(host), + host->get_port(host) ?: 65535); + return ts; +} + +/** + * Parses a pfkey message received from the kernel + */ +static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out) +{ + struct sadb_ext* ext; + size_t len; + + memset(out, 0, sizeof(pfkey_msg_t)); + out->msg = msg; + + len = msg->sadb_msg_len; + len -= PFKEY_LEN(sizeof(struct sadb_msg)); + + ext = (struct sadb_ext*)(((char*)msg) + sizeof(struct sadb_msg)); + + while (len >= PFKEY_LEN(sizeof(struct sadb_ext))) + { + DBG3(DBG_KNL, " %N", sadb_ext_type_names, ext->sadb_ext_type); + if (ext->sadb_ext_len < PFKEY_LEN(sizeof(struct sadb_ext)) || + ext->sadb_ext_len > len) + { + DBG1(DBG_KNL, "length of %N extension is invalid", + sadb_ext_type_names, ext->sadb_ext_type); + break; + } + + if ((ext->sadb_ext_type > SADB_EXT_MAX) || (!ext->sadb_ext_type)) + { + DBG1(DBG_KNL, "type of PF_KEY extension (%d) is invalid", + ext->sadb_ext_type); + break; + } + + if (out->ext[ext->sadb_ext_type]) + { + DBG1(DBG_KNL, "duplicate %N extension", + sadb_ext_type_names, ext->sadb_ext_type); + break; + } + + out->ext[ext->sadb_ext_type] = ext; + ext = PFKEY_EXT_NEXT_LEN(ext, len); + } + + if (len) + { + DBG1(DBG_KNL, "PF_KEY message length is invalid"); + return FAILED; + } + + return SUCCESS; +} + +/** + * Send a message to a specific PF_KEY socket and handle the response. + */ +static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket, + struct sadb_msg *in, struct sadb_msg **out, size_t *out_len) +{ + unsigned char buf[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg; + int in_len, len; + + this->mutex_pfkey->lock(this->mutex_pfkey); + + /* FIXME: our usage of sequence numbers is probably wrong. check RFC 2367, + * in particular the behavior in response to an SADB_ACQUIRE. */ + in->sadb_msg_seq = ++this->seq; + in->sadb_msg_pid = getpid(); + + in_len = PFKEY_USER_LEN(in->sadb_msg_len); + + while (TRUE) + { + len = send(socket, in, in_len, 0); + + if (len != in_len) + { + if (errno == EINTR) + { + /* interrupted, try again */ + continue; + } + this->mutex_pfkey->unlock(this->mutex_pfkey); + DBG1(DBG_KNL, "error sending to PF_KEY socket: %s", + strerror(errno)); + return FAILED; + } + break; + } + + while (TRUE) + { + msg = (struct sadb_msg*)buf; + + len = recv(socket, buf, sizeof(buf), 0); + + if (len < 0) + { + if (errno == EINTR) + { + DBG1(DBG_KNL, "got interrupted"); + /* interrupted, try again */ + continue; + } + DBG1(DBG_KNL, "error reading from PF_KEY socket: %s", + strerror(errno)); + this->mutex_pfkey->unlock(this->mutex_pfkey); + return FAILED; + } + if (len < sizeof(struct sadb_msg) || + msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg))) + { + DBG1(DBG_KNL, "received corrupted PF_KEY message"); + this->mutex_pfkey->unlock(this->mutex_pfkey); + return FAILED; + } + if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT) + { + DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY " + "message"); + this->mutex_pfkey->unlock(this->mutex_pfkey); + return FAILED; + } + if (msg->sadb_msg_pid != in->sadb_msg_pid) + { + DBG2(DBG_KNL, "received PF_KEY message is not intended for us"); + continue; + } + if (msg->sadb_msg_seq != this->seq) + { + DBG2(DBG_KNL, "received PF_KEY message with unexpected sequence " + "number, was %d expected %d", msg->sadb_msg_seq, + this->seq); + if (msg->sadb_msg_seq == 0) + { + /* FreeBSD and Mac OS X do this for the response to + * SADB_X_SPDGET (but not for the response to SADB_GET). + * FreeBSD: 'key_spdget' in /usr/src/sys/netipsec/key.c. */ + } + else if (msg->sadb_msg_seq < this->seq) + { + continue; + } + else + { + this->mutex_pfkey->unlock(this->mutex_pfkey); + return FAILED; + } + } + if (msg->sadb_msg_type != in->sadb_msg_type) + { + DBG2(DBG_KNL, "received PF_KEY message of wrong type, " + "was %d expected %d, ignoring", msg->sadb_msg_type, + in->sadb_msg_type); + } + break; + } + + *out_len = len; + *out = (struct sadb_msg*)malloc(len); + memcpy(*out, buf, len); + + this->mutex_pfkey->unlock(this->mutex_pfkey); + return SUCCESS; +} + +/** + * Send a message to the default PF_KEY socket and handle the response. + */ +static status_t pfkey_send(private_kernel_pfkey_ipsec_t *this, + struct sadb_msg *in, struct sadb_msg **out, + size_t *out_len) +{ + return pfkey_send_socket(this, this->socket, in, out, out_len); +} + +/** + * Process a SADB_ACQUIRE message from the kernel + */ +static void process_acquire(private_kernel_pfkey_ipsec_t *this, + struct sadb_msg* msg) +{ + pfkey_msg_t response; + u_int32_t index, reqid = 0; + traffic_selector_t *src_ts, *dst_ts; + policy_entry_t *policy; + policy_sa_t *sa; + + switch (msg->sadb_msg_satype) + { + case SADB_SATYPE_UNSPEC: + case SADB_SATYPE_ESP: + case SADB_SATYPE_AH: + break; + default: + /* acquire for AH/ESP only */ + return; + } + DBG2(DBG_KNL, "received an SADB_ACQUIRE"); + + if (parse_pfkey_message(msg, &response) != SUCCESS) + { + DBG1(DBG_KNL, "parsing SADB_ACQUIRE from kernel failed"); + return; + } + + index = response.x_policy->sadb_x_policy_id; + this->mutex->lock(this->mutex); + if (this->policies->find_first(this->policies, + (linked_list_match_t)policy_entry_match_byindex, + (void**)&policy, &index) == SUCCESS && + policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS) + { + reqid = sa->sa->cfg.reqid; + } + else + { + DBG1(DBG_KNL, "received an SADB_ACQUIRE with policy id %d but no " + "matching policy found", index); + } + this->mutex->unlock(this->mutex); + + src_ts = sadb_address2ts(response.src); + dst_ts = sadb_address2ts(response.dst); + + charon->kernel->acquire(charon->kernel, reqid, src_ts, dst_ts); +} + +/** + * Process a SADB_EXPIRE message from the kernel + */ +static void process_expire(private_kernel_pfkey_ipsec_t *this, + struct sadb_msg* msg) +{ + pfkey_msg_t response; + u_int8_t protocol; + u_int32_t spi; + host_t *dst; + bool hard; + + DBG2(DBG_KNL, "received an SADB_EXPIRE"); + + if (parse_pfkey_message(msg, &response) != SUCCESS) + { + DBG1(DBG_KNL, "parsing SADB_EXPIRE from kernel failed"); + return; + } + + protocol = satype2proto(msg->sadb_msg_satype); + spi = response.sa->sadb_sa_spi; + hard = response.lft_hard != NULL; + + if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH) + { + dst = host_create_from_sockaddr((sockaddr_t*)(response.dst + 1)); + if (dst) + { + charon->kernel->expire(charon->kernel, protocol, spi, dst, hard); + dst->destroy(dst); + } + } +} + +#ifdef SADB_X_MIGRATE +/** + * Process a SADB_X_MIGRATE message from the kernel + */ +static void process_migrate(private_kernel_pfkey_ipsec_t *this, + struct sadb_msg* msg) +{ + pfkey_msg_t response; + traffic_selector_t *src_ts, *dst_ts; + policy_dir_t dir; + u_int32_t reqid = 0; + host_t *local = NULL, *remote = NULL; + + DBG2(DBG_KNL, "received an SADB_X_MIGRATE"); + + if (parse_pfkey_message(msg, &response) != SUCCESS) + { + DBG1(DBG_KNL, "parsing SADB_X_MIGRATE from kernel failed"); + return; + } + src_ts = sadb_address2ts(response.src); + dst_ts = sadb_address2ts(response.dst); + dir = kernel2dir(response.x_policy->sadb_x_policy_dir); + DBG2(DBG_KNL, " policy %R === %R %N, id %u", src_ts, dst_ts, + policy_dir_names, dir); + + /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */ + if (response.x_kmaddress) + { + sockaddr_t *local_addr, *remote_addr; + u_int32_t local_len; + + local_addr = (sockaddr_t*)&response.x_kmaddress[1]; + local = host_create_from_sockaddr(local_addr); + local_len = (local_addr->sa_family == AF_INET6)? + sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); + remote_addr = (sockaddr_t*)((u_int8_t*)local_addr + local_len); + remote = host_create_from_sockaddr(remote_addr); + DBG2(DBG_KNL, " kmaddress: %H...%H", local, remote); + } + + if (src_ts && dst_ts && local && remote) + { + charon->kernel->migrate(charon->kernel, reqid, src_ts, dst_ts, dir, + local, remote); + } + else + { + DESTROY_IF(src_ts); + DESTROY_IF(dst_ts); + DESTROY_IF(local); + DESTROY_IF(remote); + } +} +#endif /*SADB_X_MIGRATE*/ + +#ifdef SADB_X_NAT_T_NEW_MAPPING +/** + * Process a SADB_X_NAT_T_NEW_MAPPING message from the kernel + */ +static void process_mapping(private_kernel_pfkey_ipsec_t *this, + struct sadb_msg* msg) +{ + pfkey_msg_t response; + u_int32_t spi; + sockaddr_t *sa; + host_t *dst, *new; + + DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING"); + + if (parse_pfkey_message(msg, &response) != SUCCESS) + { + DBG1(DBG_KNL, "parsing SADB_X_NAT_T_NEW_MAPPING from kernel failed"); + return; + } + + if (!response.x_sa2) + { + DBG1(DBG_KNL, "received SADB_X_NAT_T_NEW_MAPPING is missing required " + "information"); + return; + } + + spi = response.sa->sadb_sa_spi; + + if (satype2proto(msg->sadb_msg_satype) != IPPROTO_ESP) + { + return; + } + + sa = (sockaddr_t*)(response.dst + 1); + dst = host_create_from_sockaddr(sa); + switch (sa->sa_family) + { + case AF_INET: + { + struct sockaddr_in *sin = (struct sockaddr_in*)sa; + sin->sin_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port); + break; + } + case AF_INET6: + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa; + sin6->sin6_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port); + break; + } + default: + break; + } + if (dst) + { + new = host_create_from_sockaddr(sa); + if (new) + { + charon->kernel->mapping(charon->kernel, IPPROTO_ESP, spi, dst, new); + new->destroy(new); + } + dst->destroy(dst); + } +} +#endif /*SADB_X_NAT_T_NEW_MAPPING*/ + +/** + * Receives events from kernel + */ +static bool receive_events(private_kernel_pfkey_ipsec_t *this, int fd, + watcher_event_t event) +{ + unsigned char buf[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg = (struct sadb_msg*)buf; + int len; + + len = recvfrom(this->socket_events, buf, sizeof(buf), MSG_DONTWAIT, NULL, 0); + if (len < 0) + { + switch (errno) + { + case EINTR: + /* interrupted, try again */ + return TRUE; + case EAGAIN: + /* no data ready, select again */ + return TRUE; + default: + DBG1(DBG_KNL, "unable to receive from PF_KEY event socket"); + sleep(1); + return TRUE; + } + } + + if (len < sizeof(struct sadb_msg) || + msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg))) + { + DBG2(DBG_KNL, "received corrupted PF_KEY message"); + return TRUE; + } + if (msg->sadb_msg_pid != 0) + { /* not from kernel. not interested, try another one */ + return TRUE; + } + if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT) + { + DBG1(DBG_KNL, "buffer was too small to receive the complete " + "PF_KEY message"); + return TRUE; + } + + switch (msg->sadb_msg_type) + { + case SADB_ACQUIRE: + process_acquire(this, msg); + break; + case SADB_EXPIRE: + process_expire(this, msg); + break; +#ifdef SADB_X_MIGRATE + case SADB_X_MIGRATE: + process_migrate(this, msg); + break; +#endif /*SADB_X_MIGRATE*/ +#ifdef SADB_X_NAT_T_NEW_MAPPING + case SADB_X_NAT_T_NEW_MAPPING: + process_mapping(this, msg); + break; +#endif /*SADB_X_NAT_T_NEW_MAPPING*/ + default: + break; + } + + return TRUE; +} + +/** + * Get an SPI for a specific protocol from the kernel. + */ + +static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this, + host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max, + u_int32_t *spi) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_spirange *range; + pfkey_msg_t response; + u_int32_t received_spi = 0; + size_t len; + + memset(&request, 0, sizeof(request)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_GETSPI; + msg->sadb_msg_satype = proto2satype(proto); + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); + + range = (struct sadb_spirange*)PFKEY_EXT_ADD_NEXT(msg); + range->sadb_spirange_exttype = SADB_EXT_SPIRANGE; + range->sadb_spirange_len = PFKEY_LEN(sizeof(struct sadb_spirange)); + range->sadb_spirange_min = min; + range->sadb_spirange_max = max; + PFKEY_EXT_ADD(msg, range); + + if (pfkey_send(this, msg, &out, &len) == SUCCESS) + { + if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "allocating SPI failed: %s (%d)", + strerror(out->sadb_msg_errno), out->sadb_msg_errno); + } + else if (parse_pfkey_message(out, &response) == SUCCESS) + { + received_spi = response.sa->sadb_sa_spi; + } + free(out); + } + + if (received_spi == 0) + { + return FAILED; + } + + *spi = received_spi; + return SUCCESS; +} + +METHOD(kernel_ipsec_t, get_spi, status_t, + private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, + u_int8_t protocol, u_int32_t *spi) +{ + if (get_spi_internal(this, src, dst, protocol, + 0xc0000000, 0xcFFFFFFF, spi) != SUCCESS) + { + DBG1(DBG_KNL, "unable to get SPI"); + return FAILED; + } + + DBG2(DBG_KNL, "got SPI %.8x", ntohl(*spi)); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, get_cpi, status_t, + private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, + u_int16_t *cpi) +{ + u_int32_t received_spi = 0; + + DBG2(DBG_KNL, "getting CPI"); + + if (get_spi_internal(this, src, dst, IPPROTO_COMP, + 0x100, 0xEFFF, &received_spi) != SUCCESS) + { + DBG1(DBG_KNL, "unable to get CPI"); + return FAILED; + } + + *cpi = htons((u_int16_t)ntohl(received_spi)); + + DBG2(DBG_KNL, "got CPI %.4x", ntohs(*cpi)); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, add_sa, status_t, + private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi, + u_int8_t protocol, u_int32_t reqid, mark_t mark, u_int32_t tfc, + lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, + u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, + u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_sa *sa; + struct sadb_x_sa2 *sa2; + struct sadb_lifetime *lft; + struct sadb_key *key; + size_t len; + + /* if IPComp is used, we install an additional IPComp SA. if the cpi is 0 + * we are in the recursive call below */ + if (ipcomp != IPCOMP_NONE && cpi != 0) + { + lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}}; + add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark, + tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, + chunk_empty, mode, ipcomp, 0, 0, FALSE, FALSE, FALSE, inbound, + update, NULL, NULL); + ipcomp = IPCOMP_NONE; + /* use transport mode ESP SA, IPComp uses tunnel mode */ + mode = MODE_TRANSPORT; + } + + if (update) + { + /* As we didn't know the reqid during SPI allocation, we used reqid + * zero. Unfortunately we can't SADB_UPDATE to the new reqid, hence we + * have to delete the SPI allocation state manually. The reqid + * selector does not count for that, therefore we have to delete + * that state before installing the new SA to avoid deleting the + * the new state after installing it. */ + mark_t zeromark = {0, 0}; + + if (this->public.interface.del_sa(&this->public.interface, + src, dst, spi, protocol, 0, zeromark) != SUCCESS) + { + DBG1(DBG_KNL, "deleting SPI allocation SA failed"); + } + } + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", + ntohl(spi), reqid); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_ADD; + msg->sadb_msg_satype = proto2satype(protocol); + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + +#ifdef __APPLE__ + if (encap) + { + struct sadb_sa_2 *sa_2; + sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg); + sa_2->sadb_sa_natt_port = dst->get_port(dst); + sa = &sa_2->sa; + sa->sadb_sa_flags |= SADB_X_EXT_NATT; + len = sizeof(struct sadb_sa_2); + } + else +#endif + { + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); + len = sizeof(struct sadb_sa); + } + sa->sadb_sa_exttype = SADB_EXT_SA; + sa->sadb_sa_len = PFKEY_LEN(len); + sa->sadb_sa_spi = spi; + if (protocol == IPPROTO_COMP) + { + sa->sadb_sa_encrypt = lookup_algorithm(COMPRESSION_ALGORITHM, ipcomp); + } + else + { + /* Linux interprets sadb_sa_replay as number of packets/bits in the + * replay window, whereas on BSD it's the size of the window in bytes */ +#ifdef __linux__ + sa->sadb_sa_replay = min(replay_window, 32); +#else + sa->sadb_sa_replay = (replay_window + 7) / 8; +#endif + sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg); + sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg); + } + PFKEY_EXT_ADD(msg, sa); + + sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg); + sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2; + sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange)); + sa2->sadb_x_sa2_mode = mode2kernel(mode); + sa2->sadb_x_sa2_reqid = reqid; + PFKEY_EXT_ADD(msg, sa2); + + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); + + lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); + lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; + lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); + lft->sadb_lifetime_allocations = lifetime->packets.rekey; + lft->sadb_lifetime_bytes = lifetime->bytes.rekey; + lft->sadb_lifetime_addtime = lifetime->time.rekey; + lft->sadb_lifetime_usetime = 0; /* we only use addtime */ + PFKEY_EXT_ADD(msg, lft); + + lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); + lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; + lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); + lft->sadb_lifetime_allocations = lifetime->packets.life; + lft->sadb_lifetime_bytes = lifetime->bytes.life; + lft->sadb_lifetime_addtime = lifetime->time.life; + lft->sadb_lifetime_usetime = 0; /* we only use addtime */ + PFKEY_EXT_ADD(msg, lft); + + if (enc_alg != ENCR_UNDEFINED) + { + if (!sa->sadb_sa_encrypt) + { + DBG1(DBG_KNL, "algorithm %N not supported by kernel!", + encryption_algorithm_names, enc_alg); + return FAILED; + } + DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", + encryption_algorithm_names, enc_alg, enc_key.len * 8); + + key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg); + key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; + key->sadb_key_bits = enc_key.len * 8; + key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + enc_key.len); + memcpy(key + 1, enc_key.ptr, enc_key.len); + + PFKEY_EXT_ADD(msg, key); + } + + if (int_alg != AUTH_UNDEFINED) + { + if (!sa->sadb_sa_auth) + { + DBG1(DBG_KNL, "algorithm %N not supported by kernel!", + integrity_algorithm_names, int_alg); + return FAILED; + } + DBG2(DBG_KNL, " using integrity algorithm %N with key size %d", + integrity_algorithm_names, int_alg, int_key.len * 8); + + key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg); + key->sadb_key_exttype = SADB_EXT_KEY_AUTH; + key->sadb_key_bits = int_key.len * 8; + key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + int_key.len); + memcpy(key + 1, int_key.ptr, int_key.len); + + PFKEY_EXT_ADD(msg, key); + } + +#ifdef HAVE_NATT + if (encap) + { + add_encap_ext(msg, src, dst); + } +#endif /*HAVE_NATT*/ + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi)); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x: %s (%d)", + ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno); + free(out); + return FAILED; + } + + free(out); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, update_sa, status_t, + private_kernel_pfkey_ipsec_t *this, u_int32_t spi, u_int8_t protocol, + u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst, + bool encap, bool new_encap, mark_t mark) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_sa *sa; + pfkey_msg_t response; + size_t len; + + /* we can't update the SA if any of the ip addresses have changed. + * that's because we can't use SADB_UPDATE and by deleting and readding the + * SA the sequence numbers would get lost */ + if (!src->ip_equals(src, new_src) || + !dst->ip_equals(dst, new_dst)) + { + DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: address " + "changes are not supported", ntohl(spi)); + return NOT_SUPPORTED; + } + + /* if IPComp is used, we first update the IPComp SA */ + if (cpi) + { + update_sa(this, htonl(ntohs(cpi)), IPPROTO_COMP, 0, + src, dst, new_src, new_dst, FALSE, FALSE, mark); + } + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_GET; + msg->sadb_msg_satype = proto2satype(protocol); + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); + sa->sadb_sa_exttype = SADB_EXT_SA; + sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); + sa->sadb_sa_spi = spi; + PFKEY_EXT_ADD(msg, sa); + + /* the kernel wants a SADB_EXT_ADDRESS_SRC to be present even though + * it is not used for anything. */ + add_anyaddr_ext(msg, dst->get_family(dst), SADB_EXT_ADDRESS_SRC); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)", + ntohl(spi), strerror(out->sadb_msg_errno), + out->sadb_msg_errno); + free(out); + return FAILED; + } + else if (parse_pfkey_message(out, &response) != SUCCESS) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: parsing " + "response from kernel failed", ntohl(spi)); + free(out); + return FAILED; + } + + DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H", + ntohl(spi), src, dst, new_src, new_dst); + + memset(&request, 0, sizeof(request)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_UPDATE; + msg->sadb_msg_satype = proto2satype(protocol); + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + +#ifdef __APPLE__ + { + struct sadb_sa_2 *sa_2; + sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg); + sa_2->sa.sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa_2)); + memcpy(&sa_2->sa, response.sa, sizeof(struct sadb_sa)); + if (encap) + { + sa_2->sadb_sa_natt_port = new_dst->get_port(new_dst); + sa_2->sa.sadb_sa_flags |= SADB_X_EXT_NATT; + } + } +#else + PFKEY_EXT_COPY(msg, response.sa); +#endif + PFKEY_EXT_COPY(msg, response.x_sa2); + + PFKEY_EXT_COPY(msg, response.src); + PFKEY_EXT_COPY(msg, response.dst); + + PFKEY_EXT_COPY(msg, response.lft_soft); + PFKEY_EXT_COPY(msg, response.lft_hard); + + if (response.key_encr) + { + PFKEY_EXT_COPY(msg, response.key_encr); + } + + if (response.key_auth) + { + PFKEY_EXT_COPY(msg, response.key_auth); + } + +#ifdef HAVE_NATT + if (new_encap) + { + add_encap_ext(msg, new_src, new_dst); + } +#endif /*HAVE_NATT*/ + + free(out); + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi)); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: %s (%d)", + ntohl(spi), strerror(out->sadb_msg_errno), + out->sadb_msg_errno); + free(out); + return FAILED; + } + free(out); + + return SUCCESS; +} + +METHOD(kernel_ipsec_t, query_sa, status_t, + private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, mark_t mark, + u_int64_t *bytes, u_int64_t *packets, time_t *time) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_sa *sa; + pfkey_msg_t response; + size_t len; + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_GET; + msg->sadb_msg_satype = proto2satype(protocol); + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); + sa->sadb_sa_exttype = SADB_EXT_SA; + sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); + sa->sadb_sa_spi = spi; + PFKEY_EXT_ADD(msg, sa); + + /* the Linux Kernel doesn't care for the src address, but other systems do + * (e.g. FreeBSD) + */ + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)", + ntohl(spi), strerror(out->sadb_msg_errno), + out->sadb_msg_errno); + free(out); + return FAILED; + } + else if (parse_pfkey_message(out, &response) != SUCCESS) + { + DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); + free(out); + return FAILED; + } + if (bytes) + { + *bytes = response.lft_current->sadb_lifetime_bytes; + } + if (packets) + { + /* at least on Linux and FreeBSD this contains the number of packets */ + *packets = response.lft_current->sadb_lifetime_allocations; + } + if (time) + { +#ifdef __APPLE__ + /* OS X uses the "last" time of use in usetime */ + *time = response.lft_current->sadb_lifetime_usetime; +#else /* !__APPLE__ */ + /* on Linux, sadb_lifetime_usetime is set to the "first" time of use, + * which is actually correct according to PF_KEY. We have to query + * policies for the last usetime. */ + *time = 0; +#endif /* !__APPLE__ */ + } + + free(out); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, del_sa, status_t, + private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, + u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_sa *sa; + size_t len; + + /* if IPComp was used, we first delete the additional IPComp SA */ + if (cpi) + { + del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0, mark); + } + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_DELETE; + msg->sadb_msg_satype = proto2satype(protocol); + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); + sa->sadb_sa_exttype = SADB_EXT_SA; + sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); + sa->sadb_sa_spi = spi; + PFKEY_EXT_ADD(msg, sa); + + /* the Linux Kernel doesn't care for the src address, but other systems do + * (e.g. FreeBSD) + */ + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi)); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x: %s (%d)", + ntohl(spi), strerror(out->sadb_msg_errno), + out->sadb_msg_errno); + free(out); + return FAILED; + } + + DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi)); + free(out); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, flush_sas, status_t, + private_kernel_pfkey_ipsec_t *this) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct { + u_int8_t proto; + char *name; + } protos[] = { + { SADB_SATYPE_AH, "AH" }, + { SADB_SATYPE_ESP, "ESP" }, + { SADB_X_SATYPE_IPCOMP, "IPComp" }, + }; + size_t len; + int i; + + memset(&request, 0, sizeof(request)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_FLUSH; + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + for (i = 0; i < countof(protos); i++) + { + DBG2(DBG_KNL, "flushing all %s SAD entries", protos[i].name); + + msg->sadb_msg_satype = protos[i].proto; + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to flush %s SAD entries", protos[i].name); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to flush %s SAD entries: %s (%d)", + protos[i].name, strerror(out->sadb_msg_errno), + out->sadb_msg_errno); + free(out); + return FAILED; + } + free(out); + } + return SUCCESS; +} + +/** + * Add an explicit exclude route to a routing entry + */ +static void add_exclude_route(private_kernel_pfkey_ipsec_t *this, + route_entry_t *route, host_t *src, host_t *dst) +{ + enumerator_t *enumerator; + exclude_route_t *exclude; + host_t *gtw; + + enumerator = this->excludes->create_enumerator(this->excludes); + while (enumerator->enumerate(enumerator, &exclude)) + { + if (dst->ip_equals(dst, exclude->dst)) + { + route->exclude = exclude; + exclude->refs++; + } + } + enumerator->destroy(enumerator); + + if (!route->exclude) + { + DBG2(DBG_KNL, "installing new exclude route for %H src %H", dst, src); + gtw = charon->kernel->get_nexthop(charon->kernel, dst, -1, NULL); + if (gtw) + { + char *if_name = NULL; + + if (charon->kernel->get_interface(charon->kernel, src, &if_name) && + charon->kernel->add_route(charon->kernel, + dst->get_address(dst), + dst->get_family(dst) == AF_INET ? 32 : 128, + gtw, src, if_name) == SUCCESS) + { + INIT(exclude, + .dst = dst->clone(dst), + .src = src->clone(src), + .gtw = gtw->clone(gtw), + .refs = 1, + ); + route->exclude = exclude; + this->excludes->insert_last(this->excludes, exclude); + } + else + { + DBG1(DBG_KNL, "installing exclude route for %H failed", dst); + } + gtw->destroy(gtw); + free(if_name); + } + else + { + DBG1(DBG_KNL, "gateway lookup for for %H failed", dst); + } + } +} + +/** + * Remove an exclude route attached to a routing entry + */ +static void remove_exclude_route(private_kernel_pfkey_ipsec_t *this, + route_entry_t *route) +{ + if (route->exclude) + { + enumerator_t *enumerator; + exclude_route_t *exclude; + bool removed = FALSE; + host_t *dst; + + enumerator = this->excludes->create_enumerator(this->excludes); + while (enumerator->enumerate(enumerator, &exclude)) + { + if (route->exclude == exclude) + { + if (--exclude->refs == 0) + { + this->excludes->remove_at(this->excludes, enumerator); + removed = TRUE; + break; + } + } + } + enumerator->destroy(enumerator); + + if (removed) + { + char *if_name = NULL; + + dst = route->exclude->dst; + DBG2(DBG_KNL, "uninstalling exclude route for %H src %H", + dst, route->exclude->src); + if (charon->kernel->get_interface( + charon->kernel, + route->exclude->src, &if_name) && + charon->kernel->del_route(charon->kernel, + dst->get_address(dst), + dst->get_family(dst) == AF_INET ? 32 : 128, + route->exclude->gtw, route->exclude->src, + if_name) != SUCCESS) + { + DBG1(DBG_KNL, "uninstalling exclude route for %H failed", dst); + } + exclude_route_destroy(route->exclude); + free(if_name); + } + route->exclude = NULL; + } +} + +/** + * Try to install a route to the given inbound policy + */ +static bool install_route(private_kernel_pfkey_ipsec_t *this, + policy_entry_t *policy, policy_sa_in_t *in) +{ + route_entry_t *route, *old; + host_t *host, *src, *dst; + bool is_virtual; + + if (charon->kernel->get_address_by_ts(charon->kernel, in->dst_ts, &host, + &is_virtual) != SUCCESS) + { + return FALSE; + } + + /* switch src/dst, as we handle an IN policy */ + src = in->generic.sa->dst; + dst = in->generic.sa->src; + + INIT(route, + .prefixlen = policy->src.mask, + .src_ip = host, + .dst_net = chunk_clone(policy->src.net->get_address(policy->src.net)), + ); + + if (!dst->is_anyaddr(dst)) + { + route->gateway = charon->kernel->get_nexthop(charon->kernel, dst, -1, + src); + + /* if the IP is virtual, we install the route over the interface it has + * been installed on. Otherwise we use the interface we use for IKE, as + * this is required for example on Linux. */ + if (is_virtual) + { + src = route->src_ip; + } + } + else + { /* for shunt policies */ + route->gateway = charon->kernel->get_nexthop(charon->kernel, + policy->src.net, policy->src.mask, + route->src_ip); + + /* we don't have a source address, use the address we found */ + src = route->src_ip; + } + + /* get interface for route, using source address */ + if (!charon->kernel->get_interface(charon->kernel, src, &route->if_name)) + { + route_entry_destroy(route); + return FALSE; + } + + if (policy->route) + { + old = policy->route; + + if (route_entry_equals(old, route)) + { /* such a route already exists */ + route_entry_destroy(route); + return TRUE; + } + /* uninstall previously installed route */ + if (charon->kernel->del_route(charon->kernel, old->dst_net, + old->prefixlen, old->gateway, + old->src_ip, old->if_name) != SUCCESS) + { + DBG1(DBG_KNL, "error uninstalling route installed with policy " + "%R === %R %N", in->src_ts, in->dst_ts, + policy_dir_names, policy->direction); + } + route_entry_destroy(old); + policy->route = NULL; + } + + /* if remote traffic selector covers the IKE peer, add an exclude route */ + if (charon->kernel->get_features(charon->kernel) & KERNEL_REQUIRE_EXCLUDE_ROUTE) + { + if (in->src_ts->is_host(in->src_ts, dst)) + { + DBG1(DBG_KNL, "can't install route for %R === %R %N, conflicts " + "with IKE traffic", in->src_ts, in->dst_ts, policy_dir_names, + policy->direction); + route_entry_destroy(route); + return FALSE; + } + if (in->src_ts->includes(in->src_ts, dst)) + { + add_exclude_route(this, route, in->generic.sa->dst, dst); + } + } + + DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s", + in->src_ts, route->gateway, route->src_ip, route->if_name); + + switch (charon->kernel->add_route(charon->kernel, route->dst_net, + route->prefixlen, route->gateway, + route->src_ip, route->if_name)) + { + case ALREADY_DONE: + /* route exists, do not uninstall */ + remove_exclude_route(this, route); + route_entry_destroy(route); + return TRUE; + case SUCCESS: + /* cache the installed route */ + policy->route = route; + return TRUE; + default: + DBG1(DBG_KNL, "installing route failed: %R via %H src %H dev %s", + in->src_ts, route->gateway, route->src_ip, route->if_name); + remove_exclude_route(this, route); + route_entry_destroy(route); + return FALSE; + } +} + +/** + * Add or update a policy in the kernel. + * + * Note: The mutex has to be locked when entering this function. + */ +static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this, + policy_entry_t *policy, policy_sa_t *mapping, bool update) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_x_policy *pol; + struct sadb_x_ipsecrequest *req; + ipsec_sa_t *ipsec = mapping->sa; + pfkey_msg_t response; + size_t len; + ipsec_mode_t proto_mode; + status_t status; + + memset(&request, 0, sizeof(request)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = update ? SADB_X_SPDUPDATE : SADB_X_SPDADD; + msg->sadb_msg_satype = 0; + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); + pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy)); + pol->sadb_x_policy_id = 0; + pol->sadb_x_policy_dir = dir2kernel(policy->direction); + pol->sadb_x_policy_type = type2kernel(mapping->type); +#ifdef HAVE_STRUCT_SADB_X_POLICY_SADB_X_POLICY_PRIORITY + pol->sadb_x_policy_priority = mapping->priority; +#endif + + /* one or more sadb_x_ipsecrequest extensions are added to the + * sadb_x_policy extension */ + proto_mode = ipsec->cfg.mode; + + req = (struct sadb_x_ipsecrequest*)(pol + 1); + + if (ipsec->cfg.ipcomp.transform != IPCOMP_NONE) + { + req->sadb_x_ipsecrequest_proto = IPPROTO_COMP; + + /* !!! the length here MUST be in octets instead of 64 bit words */ + req->sadb_x_ipsecrequest_len = sizeof(struct sadb_x_ipsecrequest); + req->sadb_x_ipsecrequest_mode = mode2kernel(ipsec->cfg.mode); + req->sadb_x_ipsecrequest_reqid = ipsec->cfg.reqid; + req->sadb_x_ipsecrequest_level = (policy->direction == POLICY_OUT) ? + IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_USE; + if (ipsec->cfg.mode == MODE_TUNNEL) + { + len = hostcpy(req + 1, ipsec->src, FALSE); + req->sadb_x_ipsecrequest_len += len; + len = hostcpy((char*)(req + 1) + len, ipsec->dst, FALSE); + req->sadb_x_ipsecrequest_len += len; + /* use transport mode for other SAs */ + proto_mode = MODE_TRANSPORT; + } + + pol->sadb_x_policy_len += PFKEY_LEN(req->sadb_x_ipsecrequest_len); + req = (struct sadb_x_ipsecrequest*)((char*)(req) + + req->sadb_x_ipsecrequest_len); + } + + req->sadb_x_ipsecrequest_proto = ipsec->cfg.esp.use ? IPPROTO_ESP + : IPPROTO_AH; + /* !!! the length here MUST be in octets instead of 64 bit words */ + req->sadb_x_ipsecrequest_len = sizeof(struct sadb_x_ipsecrequest); + req->sadb_x_ipsecrequest_mode = mode2kernel(proto_mode); + req->sadb_x_ipsecrequest_reqid = ipsec->cfg.reqid; + req->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE; + if (proto_mode == MODE_TUNNEL) + { + len = hostcpy(req + 1, ipsec->src, FALSE); + req->sadb_x_ipsecrequest_len += len; + len = hostcpy((char*)(req + 1) + len, ipsec->dst, FALSE); + req->sadb_x_ipsecrequest_len += len; + } + + pol->sadb_x_policy_len += PFKEY_LEN(req->sadb_x_ipsecrequest_len); + PFKEY_EXT_ADD(msg, pol); + + add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, + policy->src.mask, TRUE); + add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, + policy->dst.mask, TRUE); + +#ifdef __FreeBSD__ + { /* on FreeBSD a lifetime has to be defined to be able to later query + * the current use time. */ + struct sadb_lifetime *lft; + lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); + lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; + lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); + lft->sadb_lifetime_addtime = LONG_MAX; + PFKEY_EXT_ADD(msg, lft); + } +#endif + + this->mutex->unlock(this->mutex); + + status = pfkey_send(this, msg, &out, &len); + if (status == SUCCESS && !update && out->sadb_msg_errno == EEXIST) + { + DBG1(DBG_KNL, "policy already exists, try to update it"); + free(out); + msg->sadb_msg_type = SADB_X_SPDUPDATE; + status = pfkey_send(this, msg, &out, &len); + } + if (status != SUCCESS) + { + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to %s policy: %s (%d)", + update ? "update" : "add", strerror(out->sadb_msg_errno), + out->sadb_msg_errno); + free(out); + return FAILED; + } + else if (parse_pfkey_message(out, &response) != SUCCESS) + { + DBG1(DBG_KNL, "unable to %s policy: parsing response from kernel " + "failed", update ? "update" : "add"); + free(out); + return FAILED; + } + + /* we try to find the policy again and update the kernel index */ + this->mutex->lock(this->mutex); + if (this->policies->find_first(this->policies, NULL, + (void**)&policy) != SUCCESS) + { + DBG2(DBG_KNL, "unable to update index, the policy is already gone, " + "ignoring"); + this->mutex->unlock(this->mutex); + free(out); + return SUCCESS; + } + policy->index = response.x_policy->sadb_x_policy_id; + free(out); + + /* install a route, if: + * - this is an inbound policy (to just get one for each child) + * - we are in tunnel mode or install a bypass policy + * - routing is not disabled via strongswan.conf + */ + if (policy->direction == POLICY_IN && this->install_routes && + (mapping->type != POLICY_IPSEC || ipsec->cfg.mode != MODE_TRANSPORT)) + { + install_route(this, policy, (policy_sa_in_t*)mapping); + } + this->mutex->unlock(this->mutex); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, add_policy, status_t, + private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, + mark_t mark, policy_priority_t priority) +{ + policy_entry_t *policy, *found = NULL; + policy_sa_t *assigned_sa, *current_sa; + enumerator_t *enumerator; + bool update = TRUE; + + if (dir2kernel(direction) == IPSEC_DIR_INVALID) + { /* FWD policies are not supported on all platforms */ + return SUCCESS; + } + + /* create a policy */ + policy = create_policy_entry(src_ts, dst_ts, direction); + + /* find a matching policy */ + this->mutex->lock(this->mutex); + if (this->policies->find_first(this->policies, + (linked_list_match_t)policy_entry_equals, + (void**)&found, policy) == SUCCESS) + { /* use existing policy */ + DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing " + "refcount", src_ts, dst_ts, policy_dir_names, direction); + policy_entry_destroy(policy, this); + policy = found; + } + else + { /* use the new one, if we have no such policy */ + this->policies->insert_first(this->policies, policy); + policy->used_by = linked_list_create(); + } + + /* cache the assigned IPsec SA */ + assigned_sa = policy_sa_create(this, direction, type, src, dst, src_ts, + dst_ts, sa); + assigned_sa->priority = get_priority(policy, priority); + + /* insert the SA according to its priority */ + enumerator = policy->used_by->create_enumerator(policy->used_by); + while (enumerator->enumerate(enumerator, (void**)¤t_sa)) + { + if (current_sa->priority >= assigned_sa->priority) + { + break; + } + update = FALSE; + } + policy->used_by->insert_before(policy->used_by, enumerator, assigned_sa); + enumerator->destroy(enumerator); + + if (!update) + { /* we don't update the policy if the priority is lower than that of the + * currently installed one */ + this->mutex->unlock(this->mutex); + return SUCCESS; + } + + DBG2(DBG_KNL, "%s policy %R === %R %N", + found ? "updating" : "adding", src_ts, dst_ts, + policy_dir_names, direction); + + if (add_policy_internal(this, policy, assigned_sa, found) != SUCCESS) + { + DBG1(DBG_KNL, "unable to %s policy %R === %R %N", + found ? "update" : "add", src_ts, dst_ts, + policy_dir_names, direction); + return FAILED; + } + return SUCCESS; +} + +METHOD(kernel_ipsec_t, query_policy, status_t, + private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts, + traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, + time_t *use_time) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_x_policy *pol; + policy_entry_t *policy, *found = NULL; + pfkey_msg_t response; + size_t len; + + if (dir2kernel(direction) == IPSEC_DIR_INVALID) + { /* FWD policies are not supported on all platforms */ + return NOT_FOUND; + } + + DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts, + policy_dir_names, direction); + + /* create a policy */ + policy = create_policy_entry(src_ts, dst_ts, direction); + + /* find a matching policy */ + this->mutex->lock(this->mutex); + if (this->policies->find_first(this->policies, + (linked_list_match_t)policy_entry_equals, + (void**)&found, policy) != SUCCESS) + { + DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", src_ts, + dst_ts, policy_dir_names, direction); + policy_entry_destroy(policy, this); + this->mutex->unlock(this->mutex); + return NOT_FOUND; + } + policy_entry_destroy(policy, this); + policy = found; + + memset(&request, 0, sizeof(request)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_X_SPDGET; + msg->sadb_msg_satype = 0; + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); + pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + pol->sadb_x_policy_id = policy->index; + pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy)); + pol->sadb_x_policy_dir = dir2kernel(direction); + pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; + PFKEY_EXT_ADD(msg, pol); + + add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, + policy->src.mask, TRUE); + add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, + policy->dst.mask, TRUE); + + this->mutex->unlock(this->mutex); + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to query policy %R === %R %N", src_ts, dst_ts, + policy_dir_names, direction); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to query policy %R === %R %N: %s (%d)", src_ts, + dst_ts, policy_dir_names, direction, + strerror(out->sadb_msg_errno), out->sadb_msg_errno); + free(out); + return FAILED; + } + else if (parse_pfkey_message(out, &response) != SUCCESS) + { + DBG1(DBG_KNL, "unable to query policy %R === %R %N: parsing response " + "from kernel failed", src_ts, dst_ts, policy_dir_names, + direction); + free(out); + return FAILED; + } + else if (response.lft_current == NULL) + { + DBG2(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no " + "use time", src_ts, dst_ts, policy_dir_names, direction); + free(out); + return FAILED; + } + + /* we need the monotonic time, but the kernel returns system time. */ + if (response.lft_current->sadb_lifetime_usetime) + { + *use_time = time_monotonic(NULL) - + (time(NULL) - response.lft_current->sadb_lifetime_usetime); + } + else + { + *use_time = 0; + } + free(out); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, del_policy, status_t, + private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, + mark_t mark, policy_priority_t prio) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + struct sadb_x_policy *pol; + policy_entry_t *policy, *found = NULL; + policy_sa_t *mapping, *to_remove = NULL; + enumerator_t *enumerator; + bool first = TRUE, is_installed = TRUE; + u_int32_t priority; + size_t len; + ipsec_sa_t assigned_sa = { + .src = src, + .dst = dst, + .cfg = *sa, + }; + + if (dir2kernel(direction) == IPSEC_DIR_INVALID) + { /* FWD policies are not supported on all platforms */ + return SUCCESS; + } + + DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts, + policy_dir_names, direction); + + /* create a policy */ + policy = create_policy_entry(src_ts, dst_ts, direction); + + /* find a matching policy */ + this->mutex->lock(this->mutex); + if (this->policies->find_first(this->policies, + (linked_list_match_t)policy_entry_equals, + (void**)&found, policy) != SUCCESS) + { + DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts, + dst_ts, policy_dir_names, direction); + policy_entry_destroy(policy, this); + this->mutex->unlock(this->mutex); + return NOT_FOUND; + } + policy_entry_destroy(policy, this); + policy = found; + + /* remove mapping to SA by reqid and priority, if multiple match, which + * could happen when rekeying due to an address change, remove the oldest */ + priority = get_priority(policy, prio); + enumerator = policy->used_by->create_enumerator(policy->used_by); + while (enumerator->enumerate(enumerator, (void**)&mapping)) + { + if (priority == mapping->priority && + ipsec_sa_equals(mapping->sa, &assigned_sa)) + { + to_remove = mapping; + is_installed = first; + } + else if (priority < mapping->priority) + { + break; + } + first = FALSE; + } + enumerator->destroy(enumerator); + if (!to_remove) + { /* sanity check */ + this->mutex->unlock(this->mutex); + return SUCCESS; + } + policy->used_by->remove(policy->used_by, to_remove, NULL); + mapping = to_remove; + + if (policy->used_by->get_count(policy->used_by) > 0) + { /* policy is used by more SAs, keep in kernel */ + DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed"); + policy_sa_destroy(mapping, &direction, this); + + if (!is_installed) + { /* no need to update as the policy was not installed for this SA */ + this->mutex->unlock(this->mutex); + return SUCCESS; + } + + DBG2(DBG_KNL, "updating policy %R === %R %N", src_ts, dst_ts, + policy_dir_names, direction); + policy->used_by->get_first(policy->used_by, (void**)&mapping); + if (add_policy_internal(this, policy, mapping, TRUE) != SUCCESS) + { + DBG1(DBG_KNL, "unable to update policy %R === %R %N", + src_ts, dst_ts, policy_dir_names, direction); + return FAILED; + } + return SUCCESS; + } + + memset(&request, 0, sizeof(request)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_X_SPDDELETE; + msg->sadb_msg_satype = 0; + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); + pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; + pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy)); + pol->sadb_x_policy_dir = dir2kernel(direction); + pol->sadb_x_policy_type = type2kernel(mapping->type); + PFKEY_EXT_ADD(msg, pol); + + add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, + policy->src.mask, TRUE); + add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, + policy->dst.mask, TRUE); + + if (policy->route) + { + route_entry_t *route = policy->route; + if (charon->kernel->del_route(charon->kernel, route->dst_net, + route->prefixlen, route->gateway, + route->src_ip, route->if_name) != SUCCESS) + { + DBG1(DBG_KNL, "error uninstalling route installed with " + "policy %R === %R %N", src_ts, dst_ts, + policy_dir_names, direction); + } + remove_exclude_route(this, route); + } + + this->policies->remove(this->policies, found, NULL); + policy_sa_destroy(mapping, &direction, this); + policy_entry_destroy(policy, this); + this->mutex->unlock(this->mutex); + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts, + policy_dir_names, direction); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to delete policy %R === %R %N: %s (%d)", src_ts, + dst_ts, policy_dir_names, direction, + strerror(out->sadb_msg_errno), out->sadb_msg_errno); + free(out); + return FAILED; + } + free(out); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, flush_policies, status_t, + private_kernel_pfkey_ipsec_t *this) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + size_t len; + + memset(&request, 0, sizeof(request)); + + DBG2(DBG_KNL, "flushing all policies from SPD"); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_X_SPDFLUSH; + msg->sadb_msg_satype = SADB_SATYPE_UNSPEC; + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + if (pfkey_send(this, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to flush SPD entries"); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to flush SPD entries: %s (%d)", + strerror(out->sadb_msg_errno), out->sadb_msg_errno); + free(out); + return FAILED; + } + free(out); + return SUCCESS; +} + +/** + * Register a socket for ACQUIRE/EXPIRE messages + */ +static status_t register_pfkey_socket(private_kernel_pfkey_ipsec_t *this, + u_int8_t satype) +{ + unsigned char request[PFKEY_BUFFER_SIZE]; + struct sadb_msg *msg, *out; + size_t len; + + memset(&request, 0, sizeof(request)); + + msg = (struct sadb_msg*)request; + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = SADB_REGISTER; + msg->sadb_msg_satype = satype; + msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); + + if (pfkey_send_socket(this, this->socket_events, msg, &out, &len) != SUCCESS) + { + DBG1(DBG_KNL, "unable to register PF_KEY socket"); + return FAILED; + } + else if (out->sadb_msg_errno) + { + DBG1(DBG_KNL, "unable to register PF_KEY socket: %s (%d)", + strerror(out->sadb_msg_errno), out->sadb_msg_errno); + free(out); + return FAILED; + } + free(out); + return SUCCESS; +} + +METHOD(kernel_ipsec_t, bypass_socket, bool, + private_kernel_pfkey_ipsec_t *this, int fd, int family) +{ + struct sadb_x_policy policy; + u_int sol, ipsec_policy; + + switch (family) + { + case AF_INET: + { + sol = SOL_IP; + ipsec_policy = IP_IPSEC_POLICY; + break; + } + case AF_INET6: + { + sol = SOL_IPV6; + ipsec_policy = IPV6_IPSEC_POLICY; + break; + } + default: + return FALSE; + } + + memset(&policy, 0, sizeof(policy)); + policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t); + policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; + policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS; + + policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND; + if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) + { + DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s", + strerror(errno)); + return FALSE; + } + policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND; + if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) + { + DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s", + strerror(errno)); + return FALSE; + } + return TRUE; +} + +METHOD(kernel_ipsec_t, enable_udp_decap, bool, + private_kernel_pfkey_ipsec_t *this, int fd, int family, u_int16_t port) +{ +#ifndef __APPLE__ + int type = UDP_ENCAP_ESPINUDP; + + if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) + { + DBG1(DBG_KNL, "unable to set UDP_ENCAP: %s", strerror(errno)); + return FALSE; + } +#else /* __APPLE__ */ + int intport = port; + + if (sysctlbyname("net.inet.ipsec.esp_port", NULL, NULL, &intport, + sizeof(intport)) != 0) + { + DBG1(DBG_KNL, "could not set net.inet.ipsec.esp_port to %d: %s", + port, strerror(errno)); + return FALSE; + } +#endif /* __APPLE__ */ + + return TRUE; +} + +METHOD(kernel_ipsec_t, destroy, void, + private_kernel_pfkey_ipsec_t *this) +{ + if (this->socket > 0) + { + close(this->socket); + } + if (this->socket_events > 0) + { + lib->watcher->remove(lib->watcher, this->socket_events); + close(this->socket_events); + } + this->policies->invoke_function(this->policies, + (linked_list_invoke_t)policy_entry_destroy, + this); + this->policies->destroy(this->policies); + this->excludes->destroy(this->excludes); + this->sas->destroy(this->sas); + this->mutex->destroy(this->mutex); + this->mutex_pfkey->destroy(this->mutex_pfkey); + free(this); +} + +/* + * Described in header. + */ +kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() +{ + private_kernel_pfkey_ipsec_t *this; + bool register_for_events = TRUE; + int rcv_buffer; + + INIT(this, + .public = { + .interface = { + .get_spi = _get_spi, + .get_cpi = _get_cpi, + .add_sa = _add_sa, + .update_sa = _update_sa, + .query_sa = _query_sa, + .del_sa = _del_sa, + .flush_sas = _flush_sas, + .add_policy = _add_policy, + .query_policy = _query_policy, + .del_policy = _del_policy, + .flush_policies = _flush_policies, + .bypass_socket = _bypass_socket, + .enable_udp_decap = _enable_udp_decap, + .destroy = _destroy, + }, + }, + .policies = linked_list_create(), + .excludes = linked_list_create(), + .sas = hashtable_create((hashtable_hash_t)ipsec_sa_hash, + (hashtable_equals_t)ipsec_sa_equals, 32), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT), + .install_routes = lib->settings->get_bool(lib->settings, + "%s.install_routes", TRUE, + lib->ns), + ); + + if (streq(lib->ns, "starter")) + { /* starter has no threads, so we do not register for kernel events */ + register_for_events = FALSE; + } + + /* create a PF_KEY socket to communicate with the kernel */ + this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); + if (this->socket <= 0) + { + DBG1(DBG_KNL, "unable to create PF_KEY socket"); + destroy(this); + return NULL; + } + + if (register_for_events) + { + /* create a PF_KEY socket for ACQUIRE & EXPIRE */ + this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); + if (this->socket_events <= 0) + { + DBG1(DBG_KNL, "unable to create PF_KEY event socket"); + destroy(this); + return NULL; + } + + rcv_buffer = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-pfkey.events_buffer_size", 0, lib->ns); + if (rcv_buffer > 0) + { + if (setsockopt(this->socket_events, SOL_SOCKET, SO_RCVBUF, + &rcv_buffer, sizeof(rcv_buffer)) == -1) + { + DBG1(DBG_KNL, "unable to set receive buffer size on PF_KEY " + "event socket: %s", strerror(errno)); + } + } + + /* register the event socket */ + if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS || + register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS) + { + DBG1(DBG_KNL, "unable to register PF_KEY event socket"); + destroy(this); + return NULL; + } + + lib->watcher->add(lib->watcher, this->socket_events, WATCHER_READ, + (watcher_cb_t)receive_events, this); + } + + return &this->public; +} diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h new file mode 100644 index 000000000..649f93733 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_pfkey_ipsec_i kernel_pfkey_ipsec + * @{ @ingroup kernel_pfkey + */ + +#ifndef KERNEL_PFKEY_IPSEC_H_ +#define KERNEL_PFKEY_IPSEC_H_ + +#include + +typedef struct kernel_pfkey_ipsec_t kernel_pfkey_ipsec_t; + +/** + * Implementation of the kernel ipsec interface using PF_KEY. + */ +struct kernel_pfkey_ipsec_t { + + /** + * Implements kernel_ipsec_t interface + */ + kernel_ipsec_t interface; +}; + +/** + * Create a PF_KEY kernel ipsec interface instance. + * + * @return kernel_pfkey_ipsec_t instance + */ +kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create(); + +#endif /** KERNEL_PFKEY_IPSEC_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c new file mode 100644 index 000000000..d49fe2422 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + + +#include "kernel_pfkey_plugin.h" + +#include "kernel_pfkey_ipsec.h" + +typedef struct private_kernel_pfkey_plugin_t private_kernel_pfkey_plugin_t; + +/** + * private data of kernel PF_KEY plugin + */ +struct private_kernel_pfkey_plugin_t { + /** + * implements plugin interface + */ + kernel_pfkey_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_kernel_pfkey_plugin_t *this) +{ + return "kernel-pfkey"; +} + +METHOD(plugin_t, get_features, int, + private_kernel_pfkey_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(kernel_ipsec_register, kernel_pfkey_ipsec_create), + PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_kernel_pfkey_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *kernel_pfkey_plugin_create() +{ + private_kernel_pfkey_plugin_t *this; + + if (!lib->caps->check(lib->caps, CAP_NET_ADMIN)) + { /* required to open PF_KEY sockets */ + DBG1(DBG_KNL, "kernel-pfkey plugin requires CAP_NET_ADMIN capability"); + return NULL; + } + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h new file mode 100644 index 000000000..ecccc6303 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_pfkey kernel_pfkey + * @ingroup cplugins + * + * @defgroup kernel_pfkey_plugin kernel_pfkey_plugin + * @{ @ingroup kernel_pfkey + */ + +#ifndef KERNEL_PFKEY_PLUGIN_H_ +#define KERNEL_PFKEY_PLUGIN_H_ + +#include + +typedef struct kernel_pfkey_plugin_t kernel_pfkey_plugin_t; + +/** + * PF_KEY kernel interface plugin + */ +struct kernel_pfkey_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** KERNEL_PFKEY_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_pfroute/Makefile.am b/src/libcharon/plugins/kernel_pfroute/Makefile.am new file mode 100644 index 000000000..51047e38a --- /dev/null +++ b/src/libcharon/plugins/kernel_pfroute/Makefile.am @@ -0,0 +1,19 @@ +AM_CPPFLAGS = \ + -I${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-kernel-pfroute.la +else +plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la +endif + +libstrongswan_kernel_pfroute_la_SOURCES = \ + kernel_pfroute_plugin.h kernel_pfroute_plugin.c \ + kernel_pfroute_net.h kernel_pfroute_net.c + +libstrongswan_kernel_pfroute_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/kernel_pfroute/Makefile.in b/src/libcharon/plugins/kernel_pfroute/Makefile.in new file mode 100644 index 000000000..77d83cbca --- /dev/null +++ b/src/libcharon/plugins/kernel_pfroute/Makefile.in @@ -0,0 +1,782 @@ +# 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/kernel_pfroute +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_kernel_pfroute_la_LIBADD = +am_libstrongswan_kernel_pfroute_la_OBJECTS = kernel_pfroute_plugin.lo \ + kernel_pfroute_net.lo +libstrongswan_kernel_pfroute_la_OBJECTS = \ + $(am_libstrongswan_kernel_pfroute_la_OBJECTS) +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_kernel_pfroute_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_kernel_pfroute_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_kernel_pfroute_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_kernel_pfroute_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_kernel_pfroute_la_SOURCES) +DIST_SOURCES = $(libstrongswan_kernel_pfroute_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@ +EASY_INSTALL = @EASY_INSTALL@ +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@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +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@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +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_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ +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${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-pfroute.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la +libstrongswan_kernel_pfroute_la_SOURCES = \ + kernel_pfroute_plugin.h kernel_pfroute_plugin.c \ + kernel_pfroute_net.h kernel_pfroute_net.c + +libstrongswan_kernel_pfroute_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/kernel_pfroute/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfroute/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-kernel-pfroute.la: $(libstrongswan_kernel_pfroute_la_OBJECTS) $(libstrongswan_kernel_pfroute_la_DEPENDENCIES) $(EXTRA_libstrongswan_kernel_pfroute_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_kernel_pfroute_la_LINK) $(am_libstrongswan_kernel_pfroute_la_rpath) $(libstrongswan_kernel_pfroute_la_OBJECTS) $(libstrongswan_kernel_pfroute_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfroute_net.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfroute_plugin.Plo@am__quote@ + +.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/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c new file mode 100644 index 000000000..4eebdfdad --- /dev/null +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -0,0 +1,1902 @@ +/* + * Copyright (C) 2009-2013 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kernel_pfroute_net.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef HAVE_STRUCT_SOCKADDR_SA_LEN +#error Cannot compile this plugin on systems where 'struct sockaddr' has no sa_len member. +#endif + +/** properly align sockaddrs */ +#ifdef __APPLE__ +/* Apple always uses 4 bytes */ +#define SA_ALIGN 4 +#else +/* while on other platforms like FreeBSD it depends on the architecture */ +#define SA_ALIGN sizeof(long) +#endif +#define SA_LEN(len) ((len) > 0 ? (((len)+SA_ALIGN-1) & ~(SA_ALIGN-1)) : SA_ALIGN) + +/** delay before firing roam events (ms) */ +#define ROAM_DELAY 100 + +/** delay before reinstalling routes (ms) */ +#define ROUTE_DELAY 100 + +typedef struct addr_entry_t addr_entry_t; + +/** + * IP address in an inface_entry_t + */ +struct addr_entry_t { + + /** The ip address */ + host_t *ip; + + /** virtual IP managed by us */ + bool virtual; +}; + +/** + * destroy a addr_entry_t object + */ +static void addr_entry_destroy(addr_entry_t *this) +{ + this->ip->destroy(this->ip); + free(this); +} + +typedef struct iface_entry_t iface_entry_t; + +/** + * A network interface on this system, containing addr_entry_t's + */ +struct iface_entry_t { + + /** interface index */ + int ifindex; + + /** name of the interface */ + char ifname[IFNAMSIZ]; + + /** interface flags, as in netdevice(7) SIOCGIFFLAGS */ + u_int flags; + + /** list of addresses as host_t */ + linked_list_t *addrs; + + /** TRUE if usable by config */ + bool usable; +}; + +/** + * destroy an interface entry + */ +static void iface_entry_destroy(iface_entry_t *this) +{ + this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy); + free(this); +} + +/** + * check if an interface is up + */ +static inline bool iface_entry_up(iface_entry_t *iface) +{ + return (iface->flags & IFF_UP) == IFF_UP; +} + +/** + * check if an interface is up and usable + */ +static inline bool iface_entry_up_and_usable(iface_entry_t *iface) +{ + return iface->usable && iface_entry_up(iface); +} + +typedef struct addr_map_entry_t addr_map_entry_t; + +/** + * Entry that maps an IP address to an interface entry + */ +struct addr_map_entry_t { + /** The IP address */ + host_t *ip; + + /** The address entry for this IP address */ + addr_entry_t *addr; + + /** The interface this address is installed on */ + iface_entry_t *iface; +}; + +/** + * Hash a addr_map_entry_t object, all entries with the same IP address + * are stored in the same bucket + */ +static u_int addr_map_entry_hash(addr_map_entry_t *this) +{ + return chunk_hash(this->ip->get_address(this->ip)); +} + +/** + * Compare two addr_map_entry_t objects, two entries are equal if they are + * installed on the same interface + */ +static bool addr_map_entry_equals(addr_map_entry_t *a, addr_map_entry_t *b) +{ + return a->iface->ifindex == b->iface->ifindex && + a->ip->ip_equals(a->ip, b->ip); +} + +/** + * Used with get_match this finds an address entry if it is installed on + * an up and usable interface + */ +static bool addr_map_entry_match_up_and_usable(addr_map_entry_t *a, + addr_map_entry_t *b) +{ + return !b->addr->virtual && iface_entry_up_and_usable(b->iface) && + a->ip->ip_equals(a->ip, b->ip); +} + +/** + * Used with get_match this finds an address entry if it is installed as virtual + * IP address + */ +static bool addr_map_entry_match_virtual(addr_map_entry_t *a, addr_map_entry_t *b) +{ + return b->addr->virtual && a->ip->ip_equals(a->ip, b->ip); +} + +/** + * Used with get_match this finds an address entry if it is installed on + * any active local interface + */ +static bool addr_map_entry_match_up(addr_map_entry_t *a, addr_map_entry_t *b) +{ + return !b->addr->virtual && iface_entry_up(b->iface) && + a->ip->ip_equals(a->ip, b->ip); +} + +typedef struct route_entry_t route_entry_t; + +/** + * Installed routing entry + */ +struct route_entry_t { + /** Name of the interface the route is bound to */ + char *if_name; + + /** Gateway for this route */ + host_t *gateway; + + /** Destination net */ + chunk_t dst_net; + + /** Destination net prefixlen */ + u_int8_t prefixlen; +}; + +/** + * Clone a route_entry_t object. + */ +static route_entry_t *route_entry_clone(route_entry_t *this) +{ + route_entry_t *route; + + INIT(route, + .if_name = strdup(this->if_name), + .gateway = this->gateway ? this->gateway->clone(this->gateway) : NULL, + .dst_net = chunk_clone(this->dst_net), + .prefixlen = this->prefixlen, + ); + return route; +} + +/** + * Destroy a route_entry_t object + */ +static void route_entry_destroy(route_entry_t *this) +{ + free(this->if_name); + DESTROY_IF(this->gateway); + chunk_free(&this->dst_net); + free(this); +} + +/** + * Hash a route_entry_t object + */ +static u_int route_entry_hash(route_entry_t *this) +{ + return chunk_hash_inc(chunk_from_thing(this->prefixlen), + chunk_hash(this->dst_net)); +} + +/** + * Compare two route_entry_t objects + */ +static bool route_entry_equals(route_entry_t *a, route_entry_t *b) +{ + if (a->if_name && b->if_name && streq(a->if_name, b->if_name) && + chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen) + { + return (!a->gateway && !b->gateway) || (a->gateway && b->gateway && + a->gateway->ip_equals(a->gateway, b->gateway)); + } + return FALSE; +} + +typedef struct net_change_t net_change_t; + +/** + * Queued network changes + */ +struct net_change_t { + /** Name of the interface that got activated (or an IP appeared on) */ + char *if_name; +}; + +/** + * Destroy a net_change_t object + */ +static void net_change_destroy(net_change_t *this) +{ + free(this->if_name); + free(this); +} + +/** + * Hash a net_change_t object + */ +static u_int net_change_hash(net_change_t *this) +{ + return chunk_hash(chunk_create(this->if_name, strlen(this->if_name))); +} + +/** + * Compare two net_change_t objects + */ +static bool net_change_equals(net_change_t *a, net_change_t *b) +{ + return streq(a->if_name, b->if_name); +} + +typedef struct private_kernel_pfroute_net_t private_kernel_pfroute_net_t; + +/** + * Private variables and functions of kernel_pfroute class. + */ +struct private_kernel_pfroute_net_t +{ + /** + * Public part of the kernel_pfroute_t object. + */ + kernel_pfroute_net_t public; + + /** + * lock to access lists and maps + */ + rwlock_t *lock; + + /** + * Cached list of interfaces and their addresses (iface_entry_t) + */ + linked_list_t *ifaces; + + /** + * Map for IP addresses to iface_entry_t objects (addr_map_entry_t) + */ + hashtable_t *addrs; + + /** + * List of tun devices we installed for virtual IPs + */ + linked_list_t *tuns; + + /** + * mutex to communicate exclusively with PF_KEY + */ + mutex_t *mutex; + + /** + * condvar to signal if PF_KEY query got a response + */ + condvar_t *condvar; + + /** + * installed routes + */ + hashtable_t *routes; + + /** + * mutex for routes + */ + mutex_t *routes_lock; + + /** + * interface changes which may trigger route reinstallation + */ + hashtable_t *net_changes; + + /** + * mutex for route reinstallation triggers + */ + mutex_t *net_changes_lock; + + /** + * time of last route reinstallation + */ + timeval_t last_route_reinstall; + + /** + * pid to send PF_ROUTE messages with + */ + pid_t pid; + + /** + * PF_ROUTE socket to communicate with the kernel + */ + int socket; + + /** + * sequence number for messages sent to the kernel + */ + int seq; + + /** + * Sequence number a query is waiting for + */ + int waiting_seq; + + /** + * Allocated reply message from kernel + */ + struct rt_msghdr *reply; + + /** + * earliest time of the next roam event + */ + timeval_t next_roam; + + /** + * roam event due to address change + */ + bool roam_address; + + /** + * lock to check and update roam event time + */ + spinlock_t *roam_lock; + + /** + * Time in ms to wait for IP addresses to appear/disappear + */ + int vip_wait; + + /** + * whether to actually install virtual IPs + */ + bool install_virtual_ip; +}; + + +/** + * Forward declaration + */ +static status_t manage_route(private_kernel_pfroute_net_t *this, int op, + chunk_t dst_net, u_int8_t prefixlen, + host_t *gateway, char *if_name); + +/** + * Clear the queued network changes. + */ +static void net_changes_clear(private_kernel_pfroute_net_t *this) +{ + enumerator_t *enumerator; + net_change_t *change; + + enumerator = this->net_changes->create_enumerator(this->net_changes); + while (enumerator->enumerate(enumerator, NULL, (void**)&change)) + { + this->net_changes->remove_at(this->net_changes, enumerator); + net_change_destroy(change); + } + enumerator->destroy(enumerator); +} + +/** + * Act upon queued network changes. + */ +static job_requeue_t reinstall_routes(private_kernel_pfroute_net_t *this) +{ + enumerator_t *enumerator; + route_entry_t *route; + + this->net_changes_lock->lock(this->net_changes_lock); + this->routes_lock->lock(this->routes_lock); + + enumerator = this->routes->create_enumerator(this->routes); + while (enumerator->enumerate(enumerator, NULL, (void**)&route)) + { + net_change_t *change, lookup = { + .if_name = route->if_name, + }; + /* check if a change for the outgoing interface is queued */ + change = this->net_changes->get(this->net_changes, &lookup); + if (change) + { + manage_route(this, RTM_ADD, route->dst_net, route->prefixlen, + route->gateway, route->if_name); + } + } + enumerator->destroy(enumerator); + this->routes_lock->unlock(this->routes_lock); + + net_changes_clear(this); + this->net_changes_lock->unlock(this->net_changes_lock); + return JOB_REQUEUE_NONE; +} + +/** + * Queue route reinstallation caused by network changes for a given interface. + * + * The route reinstallation is delayed for a while and only done once for + * several calls during this delay, in order to avoid doing it too often. + * The interface name is freed. + */ +static void queue_route_reinstall(private_kernel_pfroute_net_t *this, + char *if_name) +{ + net_change_t *update, *found; + timeval_t now; + job_t *job; + + INIT(update, + .if_name = if_name + ); + + this->net_changes_lock->lock(this->net_changes_lock); + found = this->net_changes->put(this->net_changes, update, update); + if (found) + { + net_change_destroy(found); + } + time_monotonic(&now); + if (timercmp(&now, &this->last_route_reinstall, >)) + { + timeval_add_ms(&now, ROUTE_DELAY); + this->last_route_reinstall = now; + + job = (job_t*)callback_job_create((callback_job_cb_t)reinstall_routes, + this, NULL, NULL); + lib->scheduler->schedule_job_ms(lib->scheduler, job, ROUTE_DELAY); + } + this->net_changes_lock->unlock(this->net_changes_lock); +} + +/** + * Add an address map entry + */ +static void addr_map_entry_add(private_kernel_pfroute_net_t *this, + addr_entry_t *addr, iface_entry_t *iface) +{ + addr_map_entry_t *entry; + + INIT(entry, + .ip = addr->ip, + .addr = addr, + .iface = iface, + ); + entry = this->addrs->put(this->addrs, entry, entry); + free(entry); +} + +/** + * Remove an address map entry (the argument order is a bit strange because + * it is also used with linked_list_t.invoke_function) + */ +static void addr_map_entry_remove(addr_entry_t *addr, iface_entry_t *iface, + private_kernel_pfroute_net_t *this) +{ + addr_map_entry_t *entry, lookup = { + .ip = addr->ip, + .addr = addr, + .iface = iface, + }; + + entry = this->addrs->remove(this->addrs, &lookup); + free(entry); +} + +/** + * callback function that raises the delayed roam event + */ +static job_requeue_t roam_event(private_kernel_pfroute_net_t *this) +{ + bool address; + + this->roam_lock->lock(this->roam_lock); + address = this->roam_address; + this->roam_address = FALSE; + this->roam_lock->unlock(this->roam_lock); + charon->kernel->roam(charon->kernel, address); + return JOB_REQUEUE_NONE; +} + +/** + * fire a roaming event. we delay it for a bit and fire only one event + * for multiple calls. otherwise we would create too many events. + */ +static void fire_roam_event(private_kernel_pfroute_net_t *this, bool address) +{ + timeval_t now; + job_t *job; + + time_monotonic(&now); + this->roam_lock->lock(this->roam_lock); + this->roam_address |= address; + if (!timercmp(&now, &this->next_roam, >)) + { + this->roam_lock->unlock(this->roam_lock); + return; + } + timeval_add_ms(&now, ROAM_DELAY); + this->next_roam = now; + this->roam_lock->unlock(this->roam_lock); + + job = (job_t*)callback_job_create((callback_job_cb_t)roam_event, + this, NULL, NULL); + lib->scheduler->schedule_job_ms(lib->scheduler, job, ROAM_DELAY); +} + +/** + * Data for enumerator over rtmsg sockaddrs + */ +typedef struct { + /** implements enumerator */ + enumerator_t public; + /** copy of attribute bitfield */ + int types; + /** bytes remaining in buffer */ + int remaining; + /** next sockaddr to enumerate */ + struct sockaddr *addr; +} rt_enumerator_t; + +METHOD(enumerator_t, rt_enumerate, bool, + rt_enumerator_t *this, int *xtype, struct sockaddr **addr) +{ + int i, type; + + if (this->remaining < sizeof(this->addr->sa_len) || + this->remaining < this->addr->sa_len) + { + return FALSE; + } + for (i = 0; i < RTAX_MAX; i++) + { + type = (1 << i); + if (this->types & type) + { + this->types &= ~type; + *addr = this->addr; + *xtype = i; + this->remaining -= SA_LEN(this->addr->sa_len); + this->addr = (struct sockaddr*)((char*)this->addr + + SA_LEN(this->addr->sa_len)); + return TRUE; + } + } + return FALSE; +} + +/** + * Create an enumerator over sockaddrs in rt/if messages + */ +static enumerator_t *create_rt_enumerator(int types, int remaining, + struct sockaddr *addr) +{ + rt_enumerator_t *this; + + INIT(this, + .public = { + .enumerate = (void*)_rt_enumerate, + .destroy = (void*)free, + }, + .types = types, + .remaining = remaining, + .addr = addr, + ); + return &this->public; +} + +/** + * Create a safe enumerator over sockaddrs in rt_msghdr + */ +static enumerator_t *create_rtmsg_enumerator(struct rt_msghdr *hdr) +{ + return create_rt_enumerator(hdr->rtm_addrs, hdr->rtm_msglen - sizeof(*hdr), + (struct sockaddr *)(hdr + 1)); +} + +/** + * Create a safe enumerator over sockaddrs in ifa_msghdr + */ +static enumerator_t *create_ifamsg_enumerator(struct ifa_msghdr *hdr) +{ + return create_rt_enumerator(hdr->ifam_addrs, hdr->ifam_msglen - sizeof(*hdr), + (struct sockaddr *)(hdr + 1)); +} + +/** + * Process an RTM_*ADDR message from the kernel + */ +static void process_addr(private_kernel_pfroute_net_t *this, + struct ifa_msghdr *ifa) +{ + struct sockaddr *sockaddr; + host_t *host = NULL; + enumerator_t *ifaces, *addrs; + iface_entry_t *iface; + addr_entry_t *addr; + bool found = FALSE, changed = FALSE, roam = FALSE; + enumerator_t *enumerator; + char *ifname = NULL; + int type; + + enumerator = create_ifamsg_enumerator(ifa); + while (enumerator->enumerate(enumerator, &type, &sockaddr)) + { + if (type == RTAX_IFA) + { + host = host_create_from_sockaddr(sockaddr); + break; + } + } + enumerator->destroy(enumerator); + + if (!host || host->is_anyaddr(host)) + { + DESTROY_IF(host); + return; + } + + this->lock->write_lock(this->lock); + ifaces = this->ifaces->create_enumerator(this->ifaces); + while (ifaces->enumerate(ifaces, &iface)) + { + if (iface->ifindex == ifa->ifam_index) + { + addrs = iface->addrs->create_enumerator(iface->addrs); + while (addrs->enumerate(addrs, &addr)) + { + if (host->ip_equals(host, addr->ip)) + { + found = TRUE; + if (ifa->ifam_type == RTM_DELADDR) + { + iface->addrs->remove_at(iface->addrs, addrs); + if (!addr->virtual && iface->usable) + { + changed = TRUE; + DBG1(DBG_KNL, "%H disappeared from %s", + host, iface->ifname); + } + addr_map_entry_remove(addr, iface, this); + addr_entry_destroy(addr); + } + } + } + addrs->destroy(addrs); + + if (!found && ifa->ifam_type == RTM_NEWADDR) + { + INIT(addr, + .ip = host->clone(host), + ); + changed = TRUE; + ifname = strdup(iface->ifname); + iface->addrs->insert_last(iface->addrs, addr); + addr_map_entry_add(this, addr, iface); + if (iface->usable) + { + DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname); + } + } + + if (changed && iface_entry_up_and_usable(iface)) + { + roam = TRUE; + } + break; + } + } + ifaces->destroy(ifaces); + this->lock->unlock(this->lock); + host->destroy(host); + + if (roam && ifname) + { + queue_route_reinstall(this, ifname); + } + else + { + free(ifname); + } + + if (roam) + { + fire_roam_event(this, TRUE); + } +} + +/** + * Re-initialize address list of an interface if it changes state + */ +static void repopulate_iface(private_kernel_pfroute_net_t *this, + iface_entry_t *iface) +{ + struct ifaddrs *ifap, *ifa; + addr_entry_t *addr; + + while (iface->addrs->remove_last(iface->addrs, (void**)&addr) == SUCCESS) + { + addr_map_entry_remove(addr, iface, this); + addr_entry_destroy(addr); + } + + if (getifaddrs(&ifap) == 0) + { + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr && streq(ifa->ifa_name, iface->ifname)) + { + switch (ifa->ifa_addr->sa_family) + { + case AF_INET: + case AF_INET6: + INIT(addr, + .ip = host_create_from_sockaddr(ifa->ifa_addr), + ); + iface->addrs->insert_last(iface->addrs, addr); + addr_map_entry_add(this, addr, iface); + break; + default: + break; + } + } + } + freeifaddrs(ifap); + } +} + +/** + * Process an RTM_IFINFO message from the kernel + */ +static void process_link(private_kernel_pfroute_net_t *this, + struct if_msghdr *msg) +{ + enumerator_t *enumerator; + iface_entry_t *iface; + bool roam = FALSE, found = FALSE, update_routes = FALSE; + + this->lock->write_lock(this->lock); + enumerator = this->ifaces->create_enumerator(this->ifaces); + while (enumerator->enumerate(enumerator, &iface)) + { + if (iface->ifindex == msg->ifm_index) + { + if (iface->usable) + { + if (!(iface->flags & IFF_UP) && (msg->ifm_flags & IFF_UP)) + { + roam = update_routes = TRUE; + DBG1(DBG_KNL, "interface %s activated", iface->ifname); + } + else if ((iface->flags & IFF_UP) && !(msg->ifm_flags & IFF_UP)) + { + roam = TRUE; + DBG1(DBG_KNL, "interface %s deactivated", iface->ifname); + } + } +#ifdef __APPLE__ + /* There seems to be a race condition on 10.10, where we get + * the RTM_IFINFO, but getifaddrs() does not return the virtual + * IP installed on a tun device, but we also don't get a + * RTM_NEWADDR. We therefore could miss the new address, letting + * virtual IP installation fail. Delaying getifaddrs() helps, + * but is obviously not a clean fix. */ + usleep(50000); +#endif + iface->flags = msg->ifm_flags; + repopulate_iface(this, iface); + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + if (!found) + { + INIT(iface, + .ifindex = msg->ifm_index, + .flags = msg->ifm_flags, + .addrs = linked_list_create(), + ); + if (if_indextoname(iface->ifindex, iface->ifname)) + { + DBG1(DBG_KNL, "interface %s appeared", iface->ifname); + iface->usable = charon->kernel->is_interface_usable(charon->kernel, + iface->ifname); + repopulate_iface(this, iface); + this->ifaces->insert_last(this->ifaces, iface); + if (iface->usable) + { + roam = update_routes = TRUE; + } + } + else + { + free(iface); + } + } + this->lock->unlock(this->lock); + + if (update_routes) + { + queue_route_reinstall(this, strdup(iface->ifname)); + } + + if (roam) + { + fire_roam_event(this, TRUE); + } +} + +#ifdef HAVE_RTM_IFANNOUNCE + +/** + * Process an RTM_IFANNOUNCE message from the kernel + */ +static void process_announce(private_kernel_pfroute_net_t *this, + struct if_announcemsghdr *msg) +{ + enumerator_t *enumerator; + iface_entry_t *iface; + + if (msg->ifan_what != IFAN_DEPARTURE) + { + /* we handle new interfaces in process_link() */ + return; + } + + this->lock->write_lock(this->lock); + enumerator = this->ifaces->create_enumerator(this->ifaces); + while (enumerator->enumerate(enumerator, &iface)) + { + if (iface->ifindex == msg->ifan_index) + { + DBG1(DBG_KNL, "interface %s disappeared", iface->ifname); + this->ifaces->remove_at(this->ifaces, enumerator); + iface_entry_destroy(iface); + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); +} + +#endif /* HAVE_RTM_IFANNOUNCE */ + +/** + * Process an RTM_*ROUTE message from the kernel + */ +static void process_route(private_kernel_pfroute_net_t *this, + struct rt_msghdr *msg) +{ + +} + +/** + * Receives PF_ROUTE messages from kernel + */ +static bool receive_events(private_kernel_pfroute_net_t *this, int fd, + watcher_event_t event) +{ + struct { + union { + struct rt_msghdr rtm; + struct if_msghdr ifm; + struct ifa_msghdr ifam; +#ifdef HAVE_RTM_IFANNOUNCE + struct if_announcemsghdr ifanm; +#endif + }; + char buf[sizeof(struct sockaddr_storage) * RTAX_MAX]; + } msg; + int len, hdrlen; + + len = recv(this->socket, &msg, sizeof(msg), MSG_DONTWAIT); + if (len < 0) + { + switch (errno) + { + case EINTR: + case EAGAIN: + return TRUE; + default: + DBG1(DBG_KNL, "unable to receive from PF_ROUTE event socket"); + sleep(1); + return TRUE; + } + } + + if (len < offsetof(struct rt_msghdr, rtm_flags) || len < msg.rtm.rtm_msglen) + { + DBG1(DBG_KNL, "received invalid PF_ROUTE message"); + return TRUE; + } + if (msg.rtm.rtm_version != RTM_VERSION) + { + DBG1(DBG_KNL, "received PF_ROUTE message with unsupported version: %d", + msg.rtm.rtm_version); + return TRUE; + } + switch (msg.rtm.rtm_type) + { + case RTM_NEWADDR: + case RTM_DELADDR: + hdrlen = sizeof(msg.ifam); + break; + case RTM_IFINFO: + hdrlen = sizeof(msg.ifm); + break; +#ifdef HAVE_RTM_IFANNOUNCE + case RTM_IFANNOUNCE: + hdrlen = sizeof(msg.ifanm); + break; +#endif /* HAVE_RTM_IFANNOUNCE */ + case RTM_ADD: + case RTM_DELETE: + case RTM_GET: + hdrlen = sizeof(msg.rtm); + break; + default: + return TRUE; + } + if (msg.rtm.rtm_msglen < hdrlen) + { + DBG1(DBG_KNL, "ignoring short PF_ROUTE message"); + return TRUE; + } + switch (msg.rtm.rtm_type) + { + case RTM_NEWADDR: + case RTM_DELADDR: + process_addr(this, &msg.ifam); + break; + case RTM_IFINFO: + process_link(this, &msg.ifm); + break; +#ifdef HAVE_RTM_IFANNOUNCE + case RTM_IFANNOUNCE: + process_announce(this, &msg.ifanm); + break; +#endif /* HAVE_RTM_IFANNOUNCE */ + case RTM_ADD: + case RTM_DELETE: + process_route(this, &msg.rtm); + break; + default: + break; + } + + this->mutex->lock(this->mutex); + if (msg.rtm.rtm_pid == this->pid && msg.rtm.rtm_seq == this->waiting_seq) + { + /* seems like the message someone is waiting for, deliver */ + this->reply = realloc(this->reply, msg.rtm.rtm_msglen); + memcpy(this->reply, &msg, msg.rtm.rtm_msglen); + } + /* signal on any event, add_ip()/del_ip() might wait for it */ + this->condvar->broadcast(this->condvar); + this->mutex->unlock(this->mutex); + + return TRUE; +} + + +/** enumerator over addresses */ +typedef struct { + private_kernel_pfroute_net_t* this; + /** which addresses to enumerate */ + kernel_address_type_t which; +} address_enumerator_t; + +/** + * cleanup function for address enumerator + */ +static void address_enumerator_destroy(address_enumerator_t *data) +{ + data->this->lock->unlock(data->this->lock); + free(data); +} + +/** + * filter for addresses + */ +static bool filter_addresses(address_enumerator_t *data, + addr_entry_t** in, host_t** out) +{ + host_t *ip; + if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->virtual) + { /* skip virtual interfaces added by us */ + return FALSE; + } + if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->virtual) + { /* address is regular, but not requested */ + return FALSE; + } + ip = (*in)->ip; + if (ip->get_family(ip) == AF_INET6) + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip); + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + { /* skip addresses with a unusable scope */ + return FALSE; + } + } + *out = ip; + return TRUE; +} + +/** + * enumerator constructor for interfaces + */ +static enumerator_t *create_iface_enumerator(iface_entry_t *iface, + address_enumerator_t *data) +{ + return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs), + (void*)filter_addresses, data, NULL); +} + +/** + * filter for interfaces + */ +static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, + iface_entry_t** out) +{ + if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable) + { /* skip interfaces excluded by config */ + return FALSE; + } + if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK)) + { /* ignore loopback devices */ + return FALSE; + } + if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP)) + { /* skip interfaces not up */ + return FALSE; + } + *out = *in; + return TRUE; +} + +METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, + private_kernel_pfroute_net_t *this, kernel_address_type_t which) +{ + address_enumerator_t *data; + + INIT(data, + .this = this, + .which = which, + ); + + this->lock->read_lock(this->lock); + return enumerator_create_nested( + enumerator_create_filter( + this->ifaces->create_enumerator(this->ifaces), + (void*)filter_interfaces, data, NULL), + (void*)create_iface_enumerator, data, + (void*)address_enumerator_destroy); +} + +METHOD(kernel_net_t, get_features, kernel_feature_t, + private_kernel_pfroute_net_t *this) +{ + return KERNEL_REQUIRE_EXCLUDE_ROUTE; +} + +METHOD(kernel_net_t, get_interface_name, bool, + private_kernel_pfroute_net_t *this, host_t* ip, char **name) +{ + addr_map_entry_t *entry, lookup = { + .ip = ip, + }; + + if (ip->is_anyaddr(ip)) + { + return FALSE; + } + this->lock->read_lock(this->lock); + /* first try to find it on an up and usable interface */ + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match_up_and_usable); + if (entry) + { + if (name) + { + *name = strdup(entry->iface->ifname); + DBG2(DBG_KNL, "%H is on interface %s", ip, *name); + } + this->lock->unlock(this->lock); + return TRUE; + } + /* check if it is a virtual IP */ + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match_virtual); + if (entry) + { + if (name) + { + *name = strdup(entry->iface->ifname); + DBG2(DBG_KNL, "virtual IP %H is on interface %s", ip, *name); + } + this->lock->unlock(this->lock); + return TRUE; + } + /* maybe it is installed on an ignored interface */ + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match_up); + if (!entry) + { /* the address does not exist, is on a down interface */ + DBG2(DBG_KNL, "%H is not a local address or the interface is down", ip); + } + this->lock->unlock(this->lock); + return FALSE; +} + +METHOD(kernel_net_t, add_ip, status_t, + private_kernel_pfroute_net_t *this, host_t *vip, int prefix, + char *ifname) +{ + enumerator_t *ifaces, *addrs; + iface_entry_t *iface; + addr_entry_t *addr; + tun_device_t *tun; + bool timeout = FALSE; + + if (!this->install_virtual_ip) + { /* disabled by config */ + return SUCCESS; + } + + tun = tun_device_create(NULL); + if (!tun) + { + return FAILED; + } + if (prefix == -1) + { + prefix = vip->get_address(vip).len * 8; + } + if (!tun->up(tun) || !tun->set_address(tun, vip, prefix)) + { + tun->destroy(tun); + return FAILED; + } + + /* wait until address appears */ + this->mutex->lock(this->mutex); + while (!timeout && !get_interface_name(this, vip, NULL)) + { + timeout = this->condvar->timed_wait(this->condvar, this->mutex, + this->vip_wait); + } + this->mutex->unlock(this->mutex); + if (timeout) + { + DBG1(DBG_KNL, "virtual IP %H did not appear on %s", + vip, tun->get_name(tun)); + tun->destroy(tun); + return FAILED; + } + + this->lock->write_lock(this->lock); + this->tuns->insert_last(this->tuns, tun); + + ifaces = this->ifaces->create_enumerator(this->ifaces); + while (ifaces->enumerate(ifaces, &iface)) + { + if (streq(iface->ifname, tun->get_name(tun))) + { + addrs = iface->addrs->create_enumerator(iface->addrs); + while (addrs->enumerate(addrs, &addr)) + { + if (addr->ip->ip_equals(addr->ip, vip)) + { + addr->virtual = TRUE; + } + } + addrs->destroy(addrs); + /* during IKEv1 reauthentication, children get moved from + * old the new SA before the virtual IP is available. This + * kills the route for our virtual IP, reinstall. */ + queue_route_reinstall(this, strdup(iface->ifname)); + break; + } + } + ifaces->destroy(ifaces); + /* lets do this while holding the lock, thus preventing another thread + * from deleting the TUN device concurrently, hopefully listeners are quick + * and cause no deadlocks */ + charon->kernel->tun(charon->kernel, tun, TRUE); + this->lock->unlock(this->lock); + + return SUCCESS; +} + +METHOD(kernel_net_t, del_ip, status_t, + private_kernel_pfroute_net_t *this, host_t *vip, int prefix, + bool wait) +{ + enumerator_t *enumerator; + tun_device_t *tun; + host_t *addr; + bool timeout = FALSE, found = FALSE; + + if (!this->install_virtual_ip) + { /* disabled by config */ + return SUCCESS; + } + + this->lock->write_lock(this->lock); + enumerator = this->tuns->create_enumerator(this->tuns); + while (enumerator->enumerate(enumerator, &tun)) + { + addr = tun->get_address(tun, NULL); + if (addr && addr->ip_equals(addr, vip)) + { + this->tuns->remove_at(this->tuns, enumerator); + charon->kernel->tun(charon->kernel, tun, FALSE); + tun->destroy(tun); + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + + if (!found) + { + return NOT_FOUND; + } + /* wait until address disappears */ + if (wait) + { + this->mutex->lock(this->mutex); + while (!timeout && get_interface_name(this, vip, NULL)) + { + timeout = this->condvar->timed_wait(this->condvar, this->mutex, + this->vip_wait); + } + this->mutex->unlock(this->mutex); + if (timeout) + { + DBG1(DBG_KNL, "virtual IP %H did not disappear from tun", vip); + return FAILED; + } + } + return SUCCESS; +} + +/** + * Append a sockaddr_in/in6 of given type to routing message + */ +static void add_rt_addr(struct rt_msghdr *hdr, int type, host_t *addr) +{ + if (addr) + { + int len; + + len = *addr->get_sockaddr_len(addr); + memcpy((char*)hdr + hdr->rtm_msglen, addr->get_sockaddr(addr), len); + hdr->rtm_msglen += SA_LEN(len); + hdr->rtm_addrs |= type; + } +} + +/** + * Append a subnet mask sockaddr using the given prefix to routing message + */ +static void add_rt_mask(struct rt_msghdr *hdr, int type, int family, int prefix) +{ + host_t *mask; + + mask = host_create_netmask(family, prefix); + if (mask) + { + add_rt_addr(hdr, type, mask); + mask->destroy(mask); + } +} + +/** + * Append an interface name sockaddr_dl to routing message + */ +static void add_rt_ifname(struct rt_msghdr *hdr, int type, char *name) +{ + struct sockaddr_dl sdl = { + .sdl_len = sizeof(struct sockaddr_dl), + .sdl_family = AF_LINK, + .sdl_nlen = strlen(name), + }; + + if (strlen(name) <= sizeof(sdl.sdl_data)) + { + memcpy(sdl.sdl_data, name, sdl.sdl_nlen); + memcpy((char*)hdr + hdr->rtm_msglen, &sdl, sdl.sdl_len); + hdr->rtm_msglen += SA_LEN(sdl.sdl_len); + hdr->rtm_addrs |= type; + } +} + +/** + * Add or remove a route + */ +static status_t manage_route(private_kernel_pfroute_net_t *this, int op, + chunk_t dst_net, u_int8_t prefixlen, + host_t *gateway, char *if_name) +{ + struct { + struct rt_msghdr hdr; + char buf[sizeof(struct sockaddr_storage) * RTAX_MAX]; + } msg = { + .hdr = { + .rtm_version = RTM_VERSION, + .rtm_type = op, + .rtm_flags = RTF_UP | RTF_STATIC, + .rtm_pid = this->pid, + .rtm_seq = ref_get(&this->seq), + }, + }; + host_t *dst; + int type; + + if (prefixlen == 0 && dst_net.len) + { + status_t status; + chunk_t half; + + half = chunk_clonea(dst_net); + half.ptr[0] |= 0x80; + prefixlen = 1; + status = manage_route(this, op, half, prefixlen, gateway, if_name); + if (status != SUCCESS) + { + return status; + } + } + + dst = host_create_from_chunk(AF_UNSPEC, dst_net, 0); + if (!dst) + { + return FAILED; + } + + if ((dst->get_family(dst) == AF_INET && prefixlen == 32) || + (dst->get_family(dst) == AF_INET6 && prefixlen == 128)) + { + msg.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY; + } + + msg.hdr.rtm_msglen = sizeof(struct rt_msghdr); + for (type = 0; type < RTAX_MAX; type++) + { + switch (type) + { + case RTAX_DST: + add_rt_addr(&msg.hdr, RTA_DST, dst); + break; + case RTAX_NETMASK: + if (!(msg.hdr.rtm_flags & RTF_HOST)) + { + add_rt_mask(&msg.hdr, RTA_NETMASK, + dst->get_family(dst), prefixlen); + } + break; + case RTAX_IFP: + if (if_name) + { + add_rt_ifname(&msg.hdr, RTA_IFP, if_name); + } + break; + case RTAX_GATEWAY: + if (gateway) + { + add_rt_addr(&msg.hdr, RTA_GATEWAY, gateway); + } + break; + default: + break; + } + } + dst->destroy(dst); + + if (send(this->socket, &msg, msg.hdr.rtm_msglen, 0) != msg.hdr.rtm_msglen) + { + if (errno == EEXIST) + { + return ALREADY_DONE; + } + DBG1(DBG_KNL, "%s PF_ROUTE route failed: %s", + op == RTM_ADD ? "adding" : "deleting", strerror(errno)); + return FAILED; + } + return SUCCESS; +} + +METHOD(kernel_net_t, add_route, status_t, + private_kernel_pfroute_net_t *this, chunk_t dst_net, u_int8_t prefixlen, + host_t *gateway, host_t *src_ip, char *if_name) +{ + status_t status; + route_entry_t *found, route = { + .dst_net = dst_net, + .prefixlen = prefixlen, + .gateway = gateway, + .if_name = if_name, + }; + + this->routes_lock->lock(this->routes_lock); + found = this->routes->get(this->routes, &route); + if (found) + { + this->routes_lock->unlock(this->routes_lock); + return ALREADY_DONE; + } + status = manage_route(this, RTM_ADD, dst_net, prefixlen, gateway, if_name); + if (status == SUCCESS) + { + found = route_entry_clone(&route); + this->routes->put(this->routes, found, found); + } + this->routes_lock->unlock(this->routes_lock); + return status; +} + +METHOD(kernel_net_t, del_route, status_t, + private_kernel_pfroute_net_t *this, chunk_t dst_net, u_int8_t prefixlen, + host_t *gateway, host_t *src_ip, char *if_name) +{ + status_t status; + route_entry_t *found, route = { + .dst_net = dst_net, + .prefixlen = prefixlen, + .gateway = gateway, + .if_name = if_name, + }; + + this->routes_lock->lock(this->routes_lock); + found = this->routes->get(this->routes, &route); + if (!found) + { + this->routes_lock->unlock(this->routes_lock); + return NOT_FOUND; + } + this->routes->remove(this->routes, found); + route_entry_destroy(found); + status = manage_route(this, RTM_DELETE, dst_net, prefixlen, gateway, + if_name); + this->routes_lock->unlock(this->routes_lock); + return status; +} + +/** + * Do a route lookup for dest and return either the nexthop or the source + * address. + */ +static host_t *get_route(private_kernel_pfroute_net_t *this, bool nexthop, + host_t *dest, host_t *src) +{ + struct { + struct rt_msghdr hdr; + char buf[sizeof(struct sockaddr_storage) * RTAX_MAX]; + } msg = { + .hdr = { + .rtm_version = RTM_VERSION, + .rtm_type = RTM_GET, + .rtm_pid = this->pid, + .rtm_seq = ref_get(&this->seq), + }, + }; + host_t *host = NULL; + enumerator_t *enumerator; + struct sockaddr *addr; + bool failed = FALSE; + int type; + +retry: + msg.hdr.rtm_msglen = sizeof(struct rt_msghdr); + for (type = 0; type < RTAX_MAX; type++) + { + switch (type) + { + case RTAX_DST: + add_rt_addr(&msg.hdr, RTA_DST, dest); + break; + case RTAX_IFA: + add_rt_addr(&msg.hdr, RTA_IFA, src); + break; + case RTAX_IFP: + if (!nexthop) + { /* add an empty IFP to ensure we get a source address */ + add_rt_ifname(&msg.hdr, RTA_IFP, ""); + } + break; + default: + break; + } + } + this->mutex->lock(this->mutex); + + while (this->waiting_seq) + { + this->condvar->wait(this->condvar, this->mutex); + } + this->waiting_seq = msg.hdr.rtm_seq; + if (send(this->socket, &msg, msg.hdr.rtm_msglen, 0) == msg.hdr.rtm_msglen) + { + while (TRUE) + { + if (this->condvar->timed_wait(this->condvar, this->mutex, 1000)) + { /* timed out? */ + break; + } + if (!this->reply) + { + continue; + } + enumerator = create_rtmsg_enumerator(this->reply); + while (enumerator->enumerate(enumerator, &type, &addr)) + { + if (nexthop) + { + if (type == RTAX_DST && this->reply->rtm_flags & RTF_HOST) + { /* probably a cloned/cached direct route, only use that + * as fallback if no gateway is found */ + host = host ?: host_create_from_sockaddr(addr); + } + if (type == RTAX_GATEWAY) + { /* could actually be a MAC address */ + host_t *gtw = host_create_from_sockaddr(addr); + if (gtw) + { + DESTROY_IF(host); + host = gtw; + } + } + } + else + { + if (type == RTAX_IFA) + { + host = host_create_from_sockaddr(addr); + } + } + } + enumerator->destroy(enumerator); + break; + } + } + else + { + failed = TRUE; + } + free(this->reply); + this->reply = NULL; + /* signal completion of query to a waiting thread */ + this->waiting_seq = 0; + this->condvar->signal(this->condvar); + this->mutex->unlock(this->mutex); + + if (failed) + { + if (src) + { /* the given source address might be gone, try again without */ + src = NULL; + msg.hdr.rtm_seq = ref_get(&this->seq); + msg.hdr.rtm_addrs = 0; + memset(msg.buf, 0, sizeof(msg.buf)); + goto retry; + } + DBG1(DBG_KNL, "PF_ROUTE lookup failed: %s", strerror(errno)); + } + if (nexthop) + { + host = host ?: dest->clone(dest); + } + else + { /* make sure the source address is not virtual and usable */ + addr_entry_t *entry, lookup = { + .ip = host, + }; + + if (!host) + { + return NULL; + } + this->lock->read_lock(this->lock); + entry = this->addrs->get_match(this->addrs, &lookup, + (void*)addr_map_entry_match_up_and_usable); + this->lock->unlock(this->lock); + if (!entry) + { + host->destroy(host); + return NULL; + } + } + DBG2(DBG_KNL, "using %H as %s to reach %H", host, + nexthop ? "nexthop" : "address", dest); + return host; +} + +METHOD(kernel_net_t, get_source_addr, host_t*, + private_kernel_pfroute_net_t *this, host_t *dest, host_t *src) +{ + return get_route(this, FALSE, dest, src); +} + +METHOD(kernel_net_t, get_nexthop, host_t*, + private_kernel_pfroute_net_t *this, host_t *dest, int prefix, host_t *src) +{ + return get_route(this, TRUE, dest, src); +} + +/** + * Initialize a list of local addresses. + */ +static status_t init_address_list(private_kernel_pfroute_net_t *this) +{ + struct ifaddrs *ifap, *ifa; + iface_entry_t *iface, *current; + addr_entry_t *addr; + enumerator_t *ifaces, *addrs; + + DBG2(DBG_KNL, "known interfaces and IP addresses:"); + + if (getifaddrs(&ifap) < 0) + { + DBG1(DBG_KNL, " failed to get interfaces!"); + return FAILED; + } + + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL) + { + continue; + } + switch(ifa->ifa_addr->sa_family) + { + case AF_LINK: + case AF_INET: + case AF_INET6: + { + iface = NULL; + ifaces = this->ifaces->create_enumerator(this->ifaces); + while (ifaces->enumerate(ifaces, ¤t)) + { + if (streq(current->ifname, ifa->ifa_name)) + { + iface = current; + break; + } + } + ifaces->destroy(ifaces); + + if (!iface) + { + INIT(iface, + .ifindex = if_nametoindex(ifa->ifa_name), + .flags = ifa->ifa_flags, + .addrs = linked_list_create(), + .usable = charon->kernel->is_interface_usable( + charon->kernel, ifa->ifa_name), + ); + memcpy(iface->ifname, ifa->ifa_name, IFNAMSIZ); + this->ifaces->insert_last(this->ifaces, iface); + } + + if (ifa->ifa_addr->sa_family != AF_LINK) + { + INIT(addr, + .ip = host_create_from_sockaddr(ifa->ifa_addr), + ); + iface->addrs->insert_last(iface->addrs, addr); + addr_map_entry_add(this, addr, iface); + } + } + } + } + freeifaddrs(ifap); + + ifaces = this->ifaces->create_enumerator(this->ifaces); + while (ifaces->enumerate(ifaces, &iface)) + { + if (iface->usable && iface->flags & IFF_UP) + { + DBG2(DBG_KNL, " %s", iface->ifname); + addrs = iface->addrs->create_enumerator(iface->addrs); + while (addrs->enumerate(addrs, (void**)&addr)) + { + DBG2(DBG_KNL, " %H", addr->ip); + } + addrs->destroy(addrs); + } + } + ifaces->destroy(ifaces); + + return SUCCESS; +} + +METHOD(kernel_net_t, destroy, void, + private_kernel_pfroute_net_t *this) +{ + enumerator_t *enumerator; + route_entry_t *route; + addr_entry_t *addr; + + enumerator = this->routes->create_enumerator(this->routes); + while (enumerator->enumerate(enumerator, NULL, (void**)&route)) + { + manage_route(this, RTM_DELETE, route->dst_net, route->prefixlen, + route->gateway, route->if_name); + route_entry_destroy(route); + } + enumerator->destroy(enumerator); + this->routes->destroy(this->routes); + this->routes_lock->destroy(this->routes_lock); + + if (this->socket != -1) + { + lib->watcher->remove(lib->watcher, this->socket); + close(this->socket); + } + + net_changes_clear(this); + this->net_changes->destroy(this->net_changes); + this->net_changes_lock->destroy(this->net_changes_lock); + + enumerator = this->addrs->create_enumerator(this->addrs); + while (enumerator->enumerate(enumerator, NULL, (void**)&addr)) + { + free(addr); + } + enumerator->destroy(enumerator); + this->addrs->destroy(this->addrs); + this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy); + this->tuns->destroy(this->tuns); + this->lock->destroy(this->lock); + this->mutex->destroy(this->mutex); + this->condvar->destroy(this->condvar); + this->roam_lock->destroy(this->roam_lock); + free(this->reply); + free(this); +} + +/* + * Described in header. + */ +kernel_pfroute_net_t *kernel_pfroute_net_create() +{ + private_kernel_pfroute_net_t *this; + + INIT(this, + .public = { + .interface = { + .get_features = _get_features, + .get_interface = _get_interface_name, + .create_address_enumerator = _create_address_enumerator, + .get_source_addr = _get_source_addr, + .get_nexthop = _get_nexthop, + .add_ip = _add_ip, + .del_ip = _del_ip, + .add_route = _add_route, + .del_route = _del_route, + .destroy = _destroy, + }, + }, + .pid = getpid(), + .ifaces = linked_list_create(), + .addrs = hashtable_create( + (hashtable_hash_t)addr_map_entry_hash, + (hashtable_equals_t)addr_map_entry_equals, 16), + .routes = hashtable_create((hashtable_hash_t)route_entry_hash, + (hashtable_equals_t)route_entry_equals, 16), + .net_changes = hashtable_create( + (hashtable_hash_t)net_change_hash, + (hashtable_equals_t)net_change_equals, 16), + .tuns = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), + .routes_lock = mutex_create(MUTEX_TYPE_DEFAULT), + .net_changes_lock = mutex_create(MUTEX_TYPE_DEFAULT), + .roam_lock = spinlock_create(), + .vip_wait = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-pfroute.vip_wait", 1000, lib->ns), + .install_virtual_ip = lib->settings->get_bool(lib->settings, + "%s.install_virtual_ip", TRUE, lib->ns), + ); + timerclear(&this->last_route_reinstall); + timerclear(&this->next_roam); + + /* create a PF_ROUTE socket to communicate with the kernel */ + this->socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC); + if (this->socket == -1) + { + DBG1(DBG_KNL, "unable to create PF_ROUTE socket"); + destroy(this); + return NULL; + } + + if (streq(lib->ns, "starter")) + { + /* starter has no threads, so we do not register for kernel events */ + if (shutdown(this->socket, SHUT_RD) != 0) + { + DBG1(DBG_KNL, "closing read end of PF_ROUTE socket failed: %s", + strerror(errno)); + } + } + else + { + lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, + (watcher_cb_t)receive_events, this); + } + if (init_address_list(this) != SUCCESS) + { + DBG1(DBG_KNL, "unable to get interface list"); + destroy(this); + return NULL; + } + + return &this->public; +} diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h new file mode 100644 index 000000000..10c3c9eb7 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_pfroute_net_i kernel_pfroute_net + * @{ @ingroup kernel_pfroute + */ + +#ifndef KERNEL_PFROUTE_NET_H_ +#define KERNEL_PFROUTE_NET_H_ + +#include + +typedef struct kernel_pfroute_net_t kernel_pfroute_net_t; + +/** + * Implementation of the kernel net interface using PF_ROUTE. + */ +struct kernel_pfroute_net_t { + + /** + * Implements kernel_net_t interface + */ + kernel_net_t interface; +}; + +/** + * Create a PF_ROUTE kernel net interface instance. + * + * @return kernel_pfroute_net_t instance + */ +kernel_pfroute_net_t *kernel_pfroute_net_create(); + +#endif /** KERNEL_PFROUTE_NET_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c new file mode 100644 index 000000000..acd834ba3 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2009 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + + +#include "kernel_pfroute_plugin.h" + +#include "kernel_pfroute_net.h" + +typedef struct private_kernel_pfroute_plugin_t private_kernel_pfroute_plugin_t; + +/** + * private data of kernel PF_ROUTE plugin + */ +struct private_kernel_pfroute_plugin_t { + /** + * implements plugin interface + */ + kernel_pfroute_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_kernel_pfroute_plugin_t *this) +{ + return "kernel-pfroute"; +} + +METHOD(plugin_t, get_features, int, + private_kernel_pfroute_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(kernel_net_register, kernel_pfroute_net_create), + PLUGIN_PROVIDE(CUSTOM, "kernel-net"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_kernel_pfroute_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *kernel_pfroute_plugin_create() +{ + private_kernel_pfroute_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h new file mode 100644 index 000000000..50642a572 --- /dev/null +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup kernel_pfroute kernel_pfroute + * @ingroup cplugins + * + * @defgroup kernel_pfroute_plugin kernel_pfroute_plugin + * @{ @ingroup kernel_pfroute + */ + +#ifndef KERNEL_PFROUTE_PLUGIN_H_ +#define KERNEL_PFROUTE_PLUGIN_H_ + +#include + +typedef struct kernel_pfroute_plugin_t kernel_pfroute_plugin_t; + +/** + * PF_ROUTE kernel interface plugin + */ +struct kernel_pfroute_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** KERNEL_PFROUTE_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/kernel_wfp/Makefile.am b/src/libcharon/plugins/kernel_wfp/Makefile.am index 85e5089a3..737a79b6c 100644 --- a/src/libcharon/plugins/kernel_wfp/Makefile.am +++ b/src/libcharon/plugins/kernel_wfp/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/kernel_wfp/Makefile.in b/src/libcharon/plugins/kernel_wfp/Makefile.in index efb214b88..cfe643f26 100644 --- a/src/libcharon/plugins/kernel_wfp/Makefile.in +++ b/src/libcharon/plugins/kernel_wfp/Makefile.in @@ -424,6 +424,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -439,7 +441,6 @@ 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 = \ diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c index 95f79f168..e1c429885 100644 --- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c +++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c @@ -20,7 +20,6 @@ #include "kernel_wfp_ipsec.h" #include -#include #include #include #include @@ -1396,10 +1395,9 @@ static bool uninstall_route(private_kernel_wfp_ipsec_t *this, { if (--route->refs == 0) { - if (hydra->kernel_interface->get_interface(hydra->kernel_interface, - src, &name)) + if (charon->kernel->get_interface(charon->kernel, src, &name)) { - res = hydra->kernel_interface->del_route(hydra->kernel_interface, + res = charon->kernel->del_route(charon->kernel, dst->get_address(dst), mask, gtw, src, name) == SUCCESS; free(name); } @@ -1442,10 +1440,9 @@ static bool install_route(private_kernel_wfp_ipsec_t *this, } else { - if (hydra->kernel_interface->get_interface(hydra->kernel_interface, - src, &name)) + if (charon->kernel->get_interface(charon->kernel, src, &name)) { - if (hydra->kernel_interface->add_route(hydra->kernel_interface, + if (charon->kernel->add_route(charon->kernel, dst->get_address(dst), mask, gtw, src, name) == SUCCESS) { INIT(route, @@ -1486,14 +1483,13 @@ static bool manage_route(private_kernel_wfp_ipsec_t *this, { return FALSE; } - if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface, - src_ts, &src, NULL) != SUCCESS) + if (charon->kernel->get_address_by_ts(charon->kernel, src_ts, &src, + NULL) != SUCCESS) { dst->destroy(dst); return FALSE; } - gtw = hydra->kernel_interface->get_nexthop(hydra->kernel_interface, - remote, -1, local); + gtw = charon->kernel->get_nexthop(charon->kernel, remote, -1, local); if (add) { done = install_route(this, dst, mask, src, gtw); @@ -1650,8 +1646,7 @@ static void acquire(private_kernel_wfp_ipsec_t *this, UINT64 filter_id, { src = src ? src->clone(src) : NULL; dst = dst ? dst->clone(dst) : NULL; - hydra->kernel_interface->acquire(hydra->kernel_interface, reqid, - src, dst); + charon->kernel->acquire(charon->kernel, reqid, src, dst); } } @@ -2069,8 +2064,8 @@ static job_requeue_t expire_job(expire_data_t *data) if (entry) { - hydra->kernel_interface->expire(hydra->kernel_interface, protocol, - data->spi, data->dst, data->hard); + charon->kernel->expire(charon->kernel, protocol, data->spi, data->dst, + data->hard); } return JOB_REQUEUE_NONE; diff --git a/src/libcharon/plugins/led/Makefile.am b/src/libcharon/plugins/led/Makefile.am index 18d6af399..9868f9efa 100644 --- a/src/libcharon/plugins/led/Makefile.am +++ b/src/libcharon/plugins/led/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in index 7942868f6..63bbf1975 100644 --- a/src/libcharon/plugins/led/Makefile.in +++ b/src/libcharon/plugins/led/Makefile.in @@ -413,6 +413,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -428,7 +430,6 @@ 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 = \ diff --git a/src/libcharon/plugins/load_tester/Makefile.am b/src/libcharon/plugins/load_tester/Makefile.am index 31e1b5c6f..af3adb257 100644 --- a/src/libcharon/plugins/load_tester/Makefile.am +++ b/src/libcharon/plugins/load_tester/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in index 52dbec53f..14fcd6f4c 100644 --- a/src/libcharon/plugins/load_tester/Makefile.in +++ b/src/libcharon/plugins/load_tester/Makefile.in @@ -426,6 +426,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -441,7 +443,6 @@ 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 \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c index 8a500635c..8f6abde0c 100644 --- a/src/libcharon/plugins/load_tester/load_tester_config.c +++ b/src/libcharon/plugins/load_tester/load_tester_config.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -656,8 +655,8 @@ static host_t *allocate_addr(private_load_tester_config_t *this, uint num) id->destroy(id); return NULL; } - if (hydra->kernel_interface->add_ip(hydra->kernel_interface, - found, this->prefix, iface) != SUCCESS) + if (charon->kernel->add_ip(charon->kernel, found, this->prefix, + iface) != SUCCESS) { DBG1(DBG_CFG, "installing load-tester IP %H on %s failed", found, iface); found->destroy(found); @@ -852,8 +851,8 @@ METHOD(load_tester_config_t, delete_ip, void, { if (pool->release_address(pool, entry->host, entry->id)) { - hydra->kernel_interface->del_ip(hydra->kernel_interface, - entry->host, this->prefix, FALSE); + charon->kernel->del_ip(charon->kernel, entry->host, + this->prefix, FALSE); break; } } @@ -882,8 +881,8 @@ static void cleanup_leases(private_load_tester_config_t *this) { if (online) { - hydra->kernel_interface->del_ip(hydra->kernel_interface, - addr, this->prefix, FALSE); + charon->kernel->del_ip(charon->kernel, addr, this->prefix, + FALSE); entry = this->leases->remove(this->leases, addr); if (entry) { diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c index c7380b974..6cf3a909c 100644 --- a/src/libcharon/plugins/load_tester/load_tester_plugin.c +++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c @@ -23,7 +23,6 @@ #include -#include #include #include #include @@ -240,16 +239,24 @@ METHOD(plugin_t, get_features, int, PLUGIN_SDEPEND(PRIVKEY, KEY_RSA), PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY), PLUGIN_SDEPEND(CERT_DECODE, CERT_X509), + PLUGIN_CALLBACK(kernel_ipsec_register, load_tester_ipsec_create), + PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"), }; + int count = countof(f); + *features = f; - return countof(f); + + if (!lib->settings->get_bool(lib->settings, + "%s.plugins.load-tester.fake_kernel", FALSE, lib->ns)) + { + count -= 2; + } + return count; } METHOD(plugin_t, destroy, void, private_load_tester_plugin_t *this) { - hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface, - (kernel_ipsec_constructor_t)load_tester_ipsec_create); this->mutex->destroy(this->mutex); this->condvar->destroy(this->condvar); free(this); @@ -289,12 +296,5 @@ plugin_t *load_tester_plugin_create() .mutex = mutex_create(MUTEX_TYPE_DEFAULT), .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), ); - - if (lib->settings->get_bool(lib->settings, - "%s.plugins.load-tester.fake_kernel", FALSE, lib->ns)) - { - hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface, - (kernel_ipsec_constructor_t)load_tester_ipsec_create); - } return &this->public.plugin; } diff --git a/src/libcharon/plugins/lookip/Makefile.am b/src/libcharon/plugins/lookip/Makefile.am index 223654ea9..623275b21 100644 --- a/src/libcharon/plugins/lookip/Makefile.am +++ b/src/libcharon/plugins/lookip/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/lookip/Makefile.in b/src/libcharon/plugins/lookip/Makefile.in index 264c58ff5..9b56d94fe 100644 --- a/src/libcharon/plugins/lookip/Makefile.in +++ b/src/libcharon/plugins/lookip/Makefile.in @@ -422,6 +422,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -437,7 +439,6 @@ 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 \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/maemo/Makefile.am b/src/libcharon/plugins/maemo/Makefile.am index fe5c963fd..02c283f5b 100644 --- a/src/libcharon/plugins/maemo/Makefile.am +++ b/src/libcharon/plugins/maemo/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in index 76c9012b2..5cc654967 100644 --- a/src/libcharon/plugins/maemo/Makefile.in +++ b/src/libcharon/plugins/maemo/Makefile.in @@ -418,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -433,7 +435,6 @@ 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 = \ diff --git a/src/libcharon/plugins/medcli/Makefile.am b/src/libcharon/plugins/medcli/Makefile.am index cfa825980..0408c8963 100644 --- a/src/libcharon/plugins/medcli/Makefile.am +++ b/src/libcharon/plugins/medcli/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in index 35740c369..32c428487 100644 --- a/src/libcharon/plugins/medcli/Makefile.in +++ b/src/libcharon/plugins/medcli/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/medsrv/Makefile.am b/src/libcharon/plugins/medsrv/Makefile.am index f21220260..1d1cb4465 100644 --- a/src/libcharon/plugins/medsrv/Makefile.am +++ b/src/libcharon/plugins/medsrv/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in index 8fe160ef3..de0217a80 100644 --- a/src/libcharon/plugins/medsrv/Makefile.in +++ b/src/libcharon/plugins/medsrv/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/osx_attr/Makefile.am b/src/libcharon/plugins/osx_attr/Makefile.am index aa1d46290..908aa8806 100644 --- a/src/libcharon/plugins/osx_attr/Makefile.am +++ b/src/libcharon/plugins/osx_attr/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/osx_attr/Makefile.in b/src/libcharon/plugins/osx_attr/Makefile.in index 9a5e438e1..6a1a81f08 100644 --- a/src/libcharon/plugins/osx_attr/Makefile.in +++ b/src/libcharon/plugins/osx_attr/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/p_cscf/Makefile.am b/src/libcharon/plugins/p_cscf/Makefile.am new file mode 100644 index 000000000..1e00a56a8 --- /dev/null +++ b/src/libcharon/plugins/p_cscf/Makefile.am @@ -0,0 +1,19 @@ +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-p-cscf.la +else +plugin_LTLIBRARIES = libstrongswan-p-cscf.la +endif + +libstrongswan_p_cscf_la_SOURCES = \ + p_cscf_plugin.c p_cscf_plugin.h \ + p_cscf_handler.c p_cscf_handler.h + +libstrongswan_p_cscf_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/p_cscf/Makefile.in b/src/libcharon/plugins/p_cscf/Makefile.in new file mode 100644 index 000000000..7f78db85a --- /dev/null +++ b/src/libcharon/plugins/p_cscf/Makefile.in @@ -0,0 +1,782 @@ +# 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/p_cscf +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_p_cscf_la_LIBADD = +am_libstrongswan_p_cscf_la_OBJECTS = p_cscf_plugin.lo \ + p_cscf_handler.lo +libstrongswan_p_cscf_la_OBJECTS = \ + $(am_libstrongswan_p_cscf_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_p_cscf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_p_cscf_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_p_cscf_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_p_cscf_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_p_cscf_la_SOURCES) +DIST_SOURCES = $(libstrongswan_p_cscf_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@ +EASY_INSTALL = @EASY_INSTALL@ +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@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +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@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +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_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ +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-p-cscf.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-p-cscf.la +libstrongswan_p_cscf_la_SOURCES = \ + p_cscf_plugin.c p_cscf_plugin.h \ + p_cscf_handler.c p_cscf_handler.h + +libstrongswan_p_cscf_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/p_cscf/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/p_cscf/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-p-cscf.la: $(libstrongswan_p_cscf_la_OBJECTS) $(libstrongswan_p_cscf_la_DEPENDENCIES) $(EXTRA_libstrongswan_p_cscf_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_p_cscf_la_LINK) $(am_libstrongswan_p_cscf_la_rpath) $(libstrongswan_p_cscf_la_OBJECTS) $(libstrongswan_p_cscf_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p_cscf_handler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/p_cscf_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/p_cscf/p_cscf_handler.c b/src/libcharon/plugins/p_cscf/p_cscf_handler.c new file mode 100644 index 000000000..76633845e --- /dev/null +++ b/src/libcharon/plugins/p_cscf/p_cscf_handler.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2016 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. + */ + +#include "p_cscf_handler.h" + +#include +#include + +typedef struct private_p_cscf_handler_t private_p_cscf_handler_t; + +/** + * Private data + */ +struct private_p_cscf_handler_t { + + /** + * Public interface + */ + p_cscf_handler_t public; +}; + +METHOD(attribute_handler_t, handle, bool, + private_p_cscf_handler_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data) +{ + host_t *server; + int family = AF_INET6; + + switch (type) + { + case P_CSCF_IP4_ADDRESS: + family = AF_INET; + /* fall-through */ + case P_CSCF_IP6_ADDRESS: + server = host_create_from_chunk(family, data, 0); + if (!server) + { + DBG1(DBG_CFG, "received invalid P-CSCF server IP"); + return FALSE; + } + DBG1(DBG_CFG, "received P-CSCF server IP %H", server); + server->destroy(server); + return TRUE; + default: + return FALSE; + } +} + +METHOD(attribute_handler_t, release, void, + private_p_cscf_handler_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data) +{ + switch (type) + { + case P_CSCF_IP4_ADDRESS: + case P_CSCF_IP6_ADDRESS: + /* nothing to do as we only log the server IPs */ + break; + default: + break; + } +} + +/** + * Data for attribute enumerator + */ +typedef struct { + enumerator_t public; + bool request_ipv4; + bool request_ipv6; +} attr_enumerator_t; + +METHOD(enumerator_t, enumerate_attrs, bool, + attr_enumerator_t *this, configuration_attribute_type_t *type, + chunk_t *data) +{ + if (this->request_ipv4) + { + *type = P_CSCF_IP4_ADDRESS; + *data = chunk_empty; + this->request_ipv4 = FALSE; + return TRUE; + } + if (this->request_ipv6) + { + *type = P_CSCF_IP6_ADDRESS; + *data = chunk_empty; + this->request_ipv6 = FALSE; + return TRUE; + } + return FALSE; +} + +/** + * Check if the given host has a matching address family + */ +static bool is_family(host_t *host, int *family) +{ + return host->get_family(host) == *family; +} + +/** + * Check if a list has a host of a given family + */ +static bool has_host_family(linked_list_t *list, int family) +{ + return list->find_first(list, (void*)is_family, NULL, &family) == SUCCESS; +} + +METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, + private_p_cscf_handler_t *this, ike_sa_t *ike_sa, + linked_list_t *vips) +{ + attr_enumerator_t *enumerator; + + if (ike_sa->get_version(ike_sa) == IKEV1) + { + return enumerator_create_empty(); + } + + INIT(enumerator, + .public = { + .enumerate = (void*)_enumerate_attrs, + .destroy = (void*)free, + }, + ); + if (lib->settings->get_bool(lib->settings, "%s.plugins.p-cscf.enable.%s", + FALSE, lib->ns, ike_sa->get_name(ike_sa))) + { + enumerator->request_ipv4 = has_host_family(vips, AF_INET); + enumerator->request_ipv6 = has_host_family(vips, AF_INET6); + } + return &enumerator->public; +} + +METHOD(p_cscf_handler_t, destroy, void, + private_p_cscf_handler_t *this) +{ + free(this); +} + +/** + * See header + */ +p_cscf_handler_t *p_cscf_handler_create() +{ + private_p_cscf_handler_t *this; + + INIT(this, + .public = { + .handler = { + .handle = _handle, + .release = _release, + .create_attribute_enumerator = _create_attribute_enumerator, + }, + .destroy = _destroy, + }, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/p_cscf/p_cscf_handler.h b/src/libcharon/plugins/p_cscf/p_cscf_handler.h new file mode 100644 index 000000000..ad4f1acce --- /dev/null +++ b/src/libcharon/plugins/p_cscf/p_cscf_handler.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 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 p_cscf_handler p_cscf_handler + * @{ @ingroup p_cscf + */ + +#ifndef P_CSCF_HANDLER_H_ +#define P_CSCF_HANDLER_H_ + +#include + +typedef struct p_cscf_handler_t p_cscf_handler_t; + +/** + * Attribute handler for P-CSCF server addresses. + */ +struct p_cscf_handler_t { + + /** + * Implements attribute_handler_t. + */ + attribute_handler_t handler; + + /** + * Destroy a p_cscf_handler_t. + */ + void (*destroy)(p_cscf_handler_t *this); +}; + +/** + * Create an p_cscf_handler_t instance. + */ +p_cscf_handler_t *p_cscf_handler_create(); + +#endif /** P_CSCF_HANDLER_H_ @}*/ diff --git a/src/libcharon/plugins/p_cscf/p_cscf_plugin.c b/src/libcharon/plugins/p_cscf/p_cscf_plugin.c new file mode 100644 index 000000000..8e2bc727e --- /dev/null +++ b/src/libcharon/plugins/p_cscf/p_cscf_plugin.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2016 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. + */ + +#include "p_cscf_plugin.h" +#include "p_cscf_handler.h" + +#include + +typedef struct private_p_cscf_plugin_t private_p_cscf_plugin_t; + +/** + * Private data + */ +struct private_p_cscf_plugin_t { + + /** + * Public interface + */ + p_cscf_plugin_t public; + + /** + * P-CSCF server address attribute handler + */ + p_cscf_handler_t *handler; +}; + +METHOD(plugin_t, get_name, char*, + private_p_cscf_plugin_t *this) +{ + return "p-cscf"; +} + +/** + * Register handler + */ +static bool plugin_cb(private_p_cscf_plugin_t *this, + plugin_feature_t *feature, bool reg, void *cb_data) +{ + if (reg) + { + charon->attributes->add_handler(charon->attributes, + &this->handler->handler); + } + else + { + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); + } + return TRUE; +} + +METHOD(plugin_t, get_features, int, + private_p_cscf_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL), + PLUGIN_PROVIDE(CUSTOM, "p-cscf"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_p_cscf_plugin_t *this) +{ + this->handler->destroy(this->handler); + free(this); +} + +/** + * See header + */ +plugin_t *p_cscf_plugin_create() +{ + private_p_cscf_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + .handler = p_cscf_handler_create(), + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/p_cscf/p_cscf_plugin.h b/src/libcharon/plugins/p_cscf/p_cscf_plugin.h new file mode 100644 index 000000000..51b17674d --- /dev/null +++ b/src/libcharon/plugins/p_cscf/p_cscf_plugin.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 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 p_cscf p_cscf + * @ingroup cplugins + * + * @defgroup p_cscf_plugin p_cscf_plugin + * @{ @ingroup p_cscf + */ + +#ifndef P_CSCF_PLUGIN_H_ +#define P_CSCF_PLUGIN_H_ + +#include + +typedef struct p_cscf_plugin_t p_cscf_plugin_t; + +/** + * Plugin that requests P-CSCF server addresses from an ePDG as specified + * in RFC 7651. + */ +struct p_cscf_plugin_t { + + /** + * Implements plugin interface. + */ + plugin_t plugin; +}; + +#endif /** P_CSCF_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/radattr/Makefile.am b/src/libcharon/plugins/radattr/Makefile.am index 15d5a0a1f..74d9351f2 100644 --- a/src/libcharon/plugins/radattr/Makefile.am +++ b/src/libcharon/plugins/radattr/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libradius diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in index baff3fc76..3f39ba237 100644 --- a/src/libcharon/plugins/radattr/Makefile.in +++ b/src/libcharon/plugins/radattr/Makefile.in @@ -417,6 +417,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ 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 \ -I$(top_srcdir)/src/libradius diff --git a/src/libcharon/plugins/resolve/Makefile.am b/src/libcharon/plugins/resolve/Makefile.am index 9cfc370c0..d3d4e73cf 100644 --- a/src/libcharon/plugins/resolve/Makefile.am +++ b/src/libcharon/plugins/resolve/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DRESOLV_CONF=\"${resolv_conf}\" diff --git a/src/libcharon/plugins/resolve/Makefile.in b/src/libcharon/plugins/resolve/Makefile.in index 91479bf52..70d97cc32 100644 --- a/src/libcharon/plugins/resolve/Makefile.in +++ b/src/libcharon/plugins/resolve/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 \ -DRESOLV_CONF=\"${resolv_conf}\" diff --git a/src/libcharon/plugins/resolve/resolve_handler.c b/src/libcharon/plugins/resolve/resolve_handler.c index 74c3960ff..ec3decc4d 100644 --- a/src/libcharon/plugins/resolve/resolve_handler.c +++ b/src/libcharon/plugins/resolve/resolve_handler.c @@ -20,7 +20,6 @@ #include #include -#include #include #include diff --git a/src/libcharon/plugins/smp/Makefile.am b/src/libcharon/plugins/smp/Makefile.am index 3aa533e56..252db32a6 100644 --- a/src/libcharon/plugins/smp/Makefile.am +++ b/src/libcharon/plugins/smp/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in index 572e7fc2f..221cda71a 100644 --- a/src/libcharon/plugins/smp/Makefile.in +++ b/src/libcharon/plugins/smp/Makefile.in @@ -414,6 +414,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -429,7 +431,6 @@ 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 \ -DIPSEC_PIDDIR=\"${piddir}\" diff --git a/src/libcharon/plugins/smp/smp.c b/src/libcharon/plugins/smp/smp.c index 2aa061fd2..56b19c792 100644 --- a/src/libcharon/plugins/smp/smp.c +++ b/src/libcharon/plugins/smp/smp.c @@ -229,8 +229,8 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer local = ike_sa->get_my_host(ike_sa); xmlTextWriterStartElement(writer, "local"); xmlTextWriterWriteFormatElement(writer, "spi", "%.16llx", - id->is_initiator(id) ? id->get_initiator_spi(id) - : id->get_responder_spi(id)); + be64toh(id->is_initiator(id) ? id->get_initiator_spi(id) + : id->get_responder_spi(id))); write_id(writer, "identification", ike_sa->get_my_id(ike_sa)); write_address(writer, "address", local); xmlTextWriterWriteFormatElement(writer, "port", "%d", @@ -246,8 +246,8 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer remote = ike_sa->get_other_host(ike_sa); xmlTextWriterStartElement(writer, "remote"); xmlTextWriterWriteFormatElement(writer, "spi", "%.16llx", - id->is_initiator(id) ? id->get_responder_spi(id) - : id->get_initiator_spi(id)); + be64toh(id->is_initiator(id) ? id->get_responder_spi(id) + : id->get_initiator_spi(id))); write_id(writer, "identification", ike_sa->get_other_id(ike_sa)); write_address(writer, "address", remote); xmlTextWriterWriteFormatElement(writer, "port", "%d", diff --git a/src/libcharon/plugins/socket_default/Makefile.am b/src/libcharon/plugins/socket_default/Makefile.am index e524ffd18..7231703b3 100644 --- a/src/libcharon/plugins/socket_default/Makefile.am +++ b/src/libcharon/plugins/socket_default/Makefile.am @@ -1,7 +1,6 @@ AM_CPPFLAGS = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in index 25b40995b..3dcfaf4a6 100644 --- a/src/libcharon/plugins/socket_default/Makefile.in +++ b/src/libcharon/plugins/socket_default/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ xml_LIBS = @xml_LIBS@ AM_CPPFLAGS = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c index 13bf3e775..6e432d9cf 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -41,7 +41,6 @@ #include #include -#include #include #include @@ -720,16 +719,15 @@ static int open_socket(private_socket_default_socket_t *this, } #endif - if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, - skt, family)) + if (!charon->kernel->bypass_socket(charon->kernel, skt, family)) { DBG1(DBG_NET, "installing IKE bypass policy failed"); } /* enable UDP decapsulation for NAT-T sockets */ if (port == &this->natt && - !hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface, - skt, family, this->natt)) + !charon->kernel->enable_udp_decap(charon->kernel, skt, family, + this->natt)) { DBG1(DBG_NET, "enabling UDP decapsulation for %s on port %d failed", family == AF_INET ? "IPv4" : "IPv6", this->natt); diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.am b/src/libcharon/plugins/socket_dynamic/Makefile.am index a1e21b98b..087ebb728 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.am +++ b/src/libcharon/plugins/socket_dynamic/Makefile.am @@ -1,7 +1,6 @@ AM_CPPFLAGS = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in index 5c010a59a..88bc22f5e 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.in +++ b/src/libcharon/plugins/socket_dynamic/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ xml_LIBS = @xml_LIBS@ AM_CPPFLAGS = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c index a032134c3..b89cae47b 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c @@ -36,7 +36,6 @@ #include #include -#include #include #include #include @@ -438,15 +437,13 @@ static int open_socket(private_socket_dynamic_socket_t *this, return 0; } - if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, - fd, family)) + if (!charon->kernel->bypass_socket(charon->kernel, fd, family)) { DBG1(DBG_NET, "installing IKE bypass policy failed"); } /* enable UDP decapsulation on each socket */ - if (!hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface, - fd, family, *port)) + if (!charon->kernel->enable_udp_decap(charon->kernel, fd, family, *port)) { DBG1(DBG_NET, "enabling UDP decapsulation for %s on port %d failed", family == AF_INET ? "IPv4" : "IPv6", *port); diff --git a/src/libcharon/plugins/socket_win/Makefile.am b/src/libcharon/plugins/socket_win/Makefile.am index f01178fcc..293d9bc9f 100644 --- a/src/libcharon/plugins/socket_win/Makefile.am +++ b/src/libcharon/plugins/socket_win/Makefile.am @@ -1,7 +1,6 @@ AM_CPPFLAGS = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/socket_win/Makefile.in b/src/libcharon/plugins/socket_win/Makefile.in index 0c3bf31b9..683011062 100644 --- a/src/libcharon/plugins/socket_win/Makefile.in +++ b/src/libcharon/plugins/socket_win/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -432,7 +434,6 @@ xml_LIBS = @xml_LIBS@ AM_CPPFLAGS = \ -I${linux_headers} \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/socket_win/socket_win_socket.c b/src/libcharon/plugins/socket_win/socket_win_socket.c index fbfbedae1..94af08e80 100644 --- a/src/libcharon/plugins/socket_win/socket_win_socket.c +++ b/src/libcharon/plugins/socket_win/socket_win_socket.c @@ -19,7 +19,6 @@ #include "socket_win_socket.h" #include -#include #include #include @@ -397,13 +396,11 @@ static SOCKET open_socket(private_socket_win_socket_t *this, int i) closesocket(s); return INVALID_SOCKET; } - if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, - s, AF_INET)) + if (!charon->kernel->bypass_socket(charon->kernel, s, AF_INET)) { DBG1(DBG_NET, "installing IPv4 IKE bypass policy failed"); } - if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, - s, AF_INET6)) + if (!charon->kernel->bypass_socket(charon->kernel, s, AF_INET6)) { DBG1(DBG_NET, "installing IPv6 IKE bypass policy failed"); } diff --git a/src/libcharon/plugins/sql/Makefile.am b/src/libcharon/plugins/sql/Makefile.am index c947db892..44a3d5f4a 100644 --- a/src/libcharon/plugins/sql/Makefile.am +++ b/src/libcharon/plugins/sql/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in index f74257af2..b09379b02 100644 --- a/src/libcharon/plugins/sql/Makefile.in +++ b/src/libcharon/plugins/sql/Makefile.in @@ -414,6 +414,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -429,7 +431,6 @@ 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 = \ diff --git a/src/libcharon/plugins/stroke/Makefile.am b/src/libcharon/plugins/stroke/Makefile.am index b90688791..26edc3dcd 100644 --- a/src/libcharon/plugins/stroke/Makefile.am +++ b/src/libcharon/plugins/stroke/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/stroke \ -DIPSEC_CONFDIR=\"${sysconfdir}\" \ diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in index a316f5c25..2b22b333a 100644 --- a/src/libcharon/plugins/stroke/Makefile.in +++ b/src/libcharon/plugins/stroke/Makefile.in @@ -418,6 +418,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -433,7 +435,6 @@ 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 \ -I$(top_srcdir)/src/stroke \ -DIPSEC_CONFDIR=\"${sysconfdir}\" \ diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 68cf83089..d0eb2aac3 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -16,7 +16,6 @@ #include "stroke_config.h" -#include #include #include #include @@ -201,8 +200,7 @@ static bool is_local(char *address, bool any_allowed) host = host_create_from_dns(token, 0, 0); if (host) { - if (hydra->kernel_interface->get_interface( - hydra->kernel_interface, host, NULL)) + if (charon->kernel->get_interface(charon->kernel, host, NULL)) { found = TRUE; } @@ -312,117 +310,6 @@ static void build_crl_policy(auth_cfg_t *cfg, bool local, int policy) } } -/** - * Parse public key / signature strength constraints - */ -static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg) -{ - enumerator_t *enumerator; - bool rsa = FALSE, ecdsa = FALSE, bliss = FALSE, - rsa_len = FALSE, ecdsa_len = FALSE, bliss_strength = FALSE; - int strength; - char *token; - - enumerator = enumerator_create_token(auth, "-", ""); - while (enumerator->enumerate(enumerator, &token)) - { - bool found = FALSE; - int i; - struct { - char *name; - signature_scheme_t scheme; - key_type_t key; - } schemes[] = { - { "md5", SIGN_RSA_EMSA_PKCS1_MD5, KEY_RSA, }, - { "sha1", SIGN_RSA_EMSA_PKCS1_SHA1, KEY_RSA, }, - { "sha224", SIGN_RSA_EMSA_PKCS1_SHA224, KEY_RSA, }, - { "sha256", SIGN_RSA_EMSA_PKCS1_SHA256, KEY_RSA, }, - { "sha384", SIGN_RSA_EMSA_PKCS1_SHA384, KEY_RSA, }, - { "sha512", SIGN_RSA_EMSA_PKCS1_SHA512, KEY_RSA, }, - { "sha1", SIGN_ECDSA_WITH_SHA1_DER, KEY_ECDSA, }, - { "sha256", SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, }, - { "sha384", SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, }, - { "sha512", SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, }, - { "sha256", SIGN_ECDSA_256, KEY_ECDSA, }, - { "sha384", SIGN_ECDSA_384, KEY_ECDSA, }, - { "sha512", SIGN_ECDSA_521, KEY_ECDSA, }, - { "sha256", SIGN_BLISS_WITH_SHA2_256, KEY_BLISS, }, - { "sha384", SIGN_BLISS_WITH_SHA2_384, KEY_BLISS, }, - { "sha512", SIGN_BLISS_WITH_SHA2_512, KEY_BLISS, }, - }; - - if (rsa_len || ecdsa_len || bliss_strength) - { /* expecting a key strength token */ - strength = atoi(token); - if (strength) - { - if (rsa_len) - { - cfg->add(cfg, AUTH_RULE_RSA_STRENGTH, (uintptr_t)strength); - } - else if (ecdsa_len) - { - cfg->add(cfg, AUTH_RULE_ECDSA_STRENGTH, (uintptr_t)strength); - } - else if (bliss_strength) - { - cfg->add(cfg, AUTH_RULE_BLISS_STRENGTH, (uintptr_t)strength); - } - } - rsa_len = ecdsa_len = bliss_strength = FALSE; - if (strength) - { - continue; - } - } - if (streq(token, "rsa")) - { - rsa = rsa_len = TRUE; - continue; - } - if (streq(token, "ecdsa")) - { - ecdsa = ecdsa_len = TRUE; - continue; - } - if (streq(token, "bliss")) - { - bliss = bliss_strength = TRUE; - continue; - } - if (streq(token, "pubkey")) - { - continue; - } - - for (i = 0; i < countof(schemes); i++) - { - if (streq(schemes[i].name, token)) - { - /* for each matching string, allow the scheme, if: - * - it is an RSA scheme, and we enforced RSA - * - it is an ECDSA scheme, and we enforced ECDSA - * - it is not a key type specific scheme - */ - if ((rsa && schemes[i].key == KEY_RSA) || - (ecdsa && schemes[i].key == KEY_ECDSA) || - (bliss && schemes[i].key == KEY_BLISS) || - (!rsa && !ecdsa && !bliss)) - { - cfg->add(cfg, AUTH_RULE_SIGNATURE_SCHEME, - (uintptr_t)schemes[i].scheme); - } - found = TRUE; - } - } - if (!found) - { - DBG1(DBG_CFG, "ignoring invalid auth token: '%s'", token); - } - } - enumerator->destroy(enumerator); -} - /** * build authentication config */ @@ -619,15 +506,15 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, } /* authentication metod (class, actually) */ - if (strpfx(auth, "pubkey") || + if (strpfx(auth, "ike:") || + strpfx(auth, "pubkey") || strpfx(auth, "rsa") || strpfx(auth, "ecdsa") || strpfx(auth, "bliss")) { cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); build_crl_policy(cfg, local, msg->add_conn.crl_policy); - - parse_pubkey_constraints(auth, cfg); + cfg->add_pubkey_constraints(cfg, auth, TRUE); } else if (streq(auth, "psk") || streq(auth, "secret")) { @@ -660,7 +547,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, if (pos) { *pos = 0; - parse_pubkey_constraints(pos + 1, cfg); + cfg->add_pubkey_constraints(cfg, pos + 1, FALSE); } type = eap_vendor_type_from_string(auth); if (type) diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c index 5a1a5074d..36da5ff21 100644 --- a/src/libcharon/plugins/stroke/stroke_control.c +++ b/src/libcharon/plugins/stroke/stroke_control.c @@ -16,7 +16,6 @@ #include "stroke_control.h" -#include #include #include diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index c0192b5c0..0371c7032 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -2,6 +2,9 @@ * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -23,22 +26,12 @@ #include #endif /* HAVE_MALLINFO */ -#include #include #include #include #include -#include -#include -#include +#include #include -#include -#include - -/* warning intervals for list functions */ -#define CERT_WARNING_INTERVAL 30 /* days */ -#define CRL_WARNING_INTERVAL 7 /* days */ -#define AC_WARNING_INTERVAL 1 /* day */ typedef struct private_stroke_list_t private_stroke_list_t; @@ -68,6 +61,11 @@ struct private_stroke_list_t { stroke_attribute_t *attribute; }; +/** + * Static certificate printer object + */ +static certificate_printer_t *cert_printer = NULL; + /** * Log tasks of a specific queue to out */ @@ -139,8 +137,10 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all) fprintf(out, "%12s[%d]: %N SPIs: %.16"PRIx64"_i%s %.16"PRIx64"_r%s", ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa), ike_version_names, ike_sa->get_version(ike_sa), - id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "", - id->get_responder_spi(id), id->is_initiator(id) ? "" : "*"); + be64toh(id->get_initiator_spi(id)), + id->is_initiator(id) ? "*" : "", + be64toh(id->get_responder_spi(id)), + id->is_initiator(id) ? "" : "*"); if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED) @@ -244,40 +244,36 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) proposal = child_sa->get_proposal(child_sa); if (proposal) { - u_int16_t encr_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED; - u_int16_t encr_size = 0, int_size = 0; - u_int16_t esn = NO_EXT_SEQ_NUMBERS; + u_int16_t alg, ks; bool first = TRUE; - proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, - &encr_alg, &encr_size); - proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, - &int_alg, &int_size); - proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, - &esn, NULL); - - if (encr_alg != ENCR_UNDEFINED) + if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, + &alg, &ks) && alg != ENCR_UNDEFINED) { - fprintf(out, "%N", encryption_algorithm_names, encr_alg); + fprintf(out, "%N", encryption_algorithm_names, alg); first = FALSE; - if (encr_size) + if (ks) { - fprintf(out, "_%u", encr_size); + fprintf(out, "_%u", ks); } } - if (int_alg != AUTH_UNDEFINED) + if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, + &alg, &ks) && alg != AUTH_UNDEFINED) { - if (!first) - { - fprintf(out, "/"); - } - fprintf(out, "%N", integrity_algorithm_names, int_alg); - if (int_size) + fprintf(out, "%s%N", first ? "" : "/", + integrity_algorithm_names, alg); + if (ks) { - fprintf(out, "_%u", int_size); + fprintf(out, "_%u", ks); } } - if (esn == EXT_SEQ_NUMBERS) + if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + &alg, NULL)) + { + fprintf(out, "/%N", diffie_hellman_group_names, alg); + } + if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, + &alg, NULL) && alg == EXT_SEQ_NUMBERS) { fprintf(out, "/ESN"); } @@ -538,8 +534,8 @@ METHOD(stroke_list_t, status, void, } enumerator->destroy(enumerator); - enumerator = hydra->kernel_interface->create_address_enumerator( - hydra->kernel_interface, ADDR_TYPE_REGULAR); + enumerator = charon->kernel->create_address_enumerator(charon->kernel, + ADDR_TYPE_REGULAR); fprintf(out, "Listening IP addresses:\n"); while (enumerator->enumerate(enumerator, (void**)&host)) { @@ -738,14 +734,20 @@ static linked_list_t* create_unique_cert_list(certificate_type_t type) } /** - * Print a single public key. + * Is there a matching private key? */ -static void list_public_key(public_key_t *public, FILE *out) +static bool has_privkey(certificate_t *cert) { + public_key_t *public; private_key_t *private = NULL; chunk_t keyid; identification_t *id; + public = cert->get_public_key(cert); + if (!public) + { + return FALSE; + } if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyid)) { id = identification_create_from_encoding(ID_KEY_ID, keyid); @@ -753,521 +755,56 @@ static void list_public_key(public_key_t *public, FILE *out) public->get_type(public), id, NULL); id->destroy(id); } - - fprintf(out, " pubkey: %N %d bits%s\n", - key_type_names, public->get_type(public), - public->get_keysize(public), - private ? ", has private key" : ""); - if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid)) - { - fprintf(out, " keyid: %#B\n", &keyid); - } - if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyid)) - { - fprintf(out, " subjkey: %#B\n", &keyid); - } + public->destroy(public); DESTROY_IF(private); -} - -/** - * list all raw public keys - */ -static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out) -{ - bool first = TRUE; - time_t now = time(NULL), notBefore, notAfter; - enumerator_t *enumerator; - certificate_t *cert; - - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, (void**)&cert)) - { - identification_t *subject = cert->get_subject(cert); - public_key_t *public = cert->get_public_key(cert); - - if (public) - { - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of Raw Public Keys:\n"); - first = FALSE; - } - fprintf(out, "\n"); - - /* list subject if available */ - if (subject->get_type(subject) != ID_KEY_ID) - { - fprintf(out, " subject: %#Y\n", subject); - } - - /* list validity if available*/ - cert->get_validity(cert, &now, ¬Before, ¬After); - if (notBefore != UNDEFINED_TIME && notAfter != UNDEFINED_TIME) - { - fprintf(out, " validity: not before %T, ", ¬Before, utc); - if (now < notBefore) - { - fprintf(out, "not valid yet (valid in %V)\n", &now, ¬Before); - } - else - { - fprintf(out, "ok\n"); - } - fprintf(out, " not after %T, ", ¬After, utc); - if (now > notAfter) - { - fprintf(out, "expired (%V ago)\n", &now, ¬After); - } - else - { - fprintf(out, "ok"); - if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %V)", &now, ¬After); - } - fprintf(out, " \n"); - } - } - - list_public_key(public, out); - public->destroy(public); - } - } - enumerator->destroy(enumerator); -} - -/** - * list OpenPGP certificates - */ -static void stroke_list_pgp(linked_list_t *list,bool utc, FILE *out) -{ - bool first = TRUE; - time_t now = time(NULL); - enumerator_t *enumerator = list->create_enumerator(list); - certificate_t *cert; - - while (enumerator->enumerate(enumerator, (void**)&cert)) - { - time_t created, until; - public_key_t *public; - pgp_certificate_t *pgp_cert = (pgp_certificate_t*)cert; - chunk_t fingerprint = pgp_cert->get_fingerprint(pgp_cert); - - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of PGP End Entity Certificates:\n"); - first = FALSE; - } - fprintf(out, "\n"); - fprintf(out, " userid: '%Y'\n", cert->get_subject(cert)); - - fprintf(out, " digest: %#B\n", &fingerprint); - - /* list validity */ - cert->get_validity(cert, &now, &created, &until); - fprintf(out, " created: %T\n", &created, utc); - fprintf(out, " until: %T%s\n", &until, utc, - (until == TIME_32_BIT_SIGNED_MAX) ? " (expires never)":""); - - public = cert->get_public_key(cert); - if (public) - { - list_public_key(public, out); - public->destroy(public); - } - } - enumerator->destroy(enumerator); + return (private != NULL); } /** * list all X.509 certificates matching the flags */ -static void stroke_list_certs(linked_list_t *list, char *label, - x509_flag_t flags, bool utc, FILE *out) +static void stroke_list_x509_certs(linked_list_t *list, x509_flag_t flag) { - bool first = TRUE; - time_t now = time(NULL); enumerator_t *enumerator; certificate_t *cert; - x509_flag_t flag_mask; - - /* mask all auxiliary flags */ - flag_mask = ~(X509_SERVER_AUTH | X509_CLIENT_AUTH | X509_IKE_INTERMEDIATE | - X509_SELF_SIGNED | X509_IP_ADDR_BLOCKS); enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, (void**)&cert)) { x509_t *x509 = (x509_t*)cert; - x509_flag_t x509_flags = x509->get_flags(x509) & flag_mask; + x509_flag_t flags = x509->get_flags(x509) & X509_ANY; /* list only if flag is set or flag == 0 */ - if ((x509_flags & flags) || (x509_flags == flags)) + if ((flags & flag) || flags == flag) { - enumerator_t *enumerator; - identification_t *altName; - bool first_altName = TRUE; - u_int pathlen; - chunk_t serial, authkey; - time_t notBefore, notAfter; - public_key_t *public; - - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of %s:\n", label); - first = FALSE; - } - fprintf(out, "\n"); - - /* list subjectAltNames */ - enumerator = x509->create_subjectAltName_enumerator(x509); - while (enumerator->enumerate(enumerator, (void**)&altName)) - { - if (first_altName) - { - fprintf(out, " altNames: "); - first_altName = FALSE; - } - else - { - fprintf(out, ", "); - } - fprintf(out, "%Y", altName); - } - if (!first_altName) - { - fprintf(out, "\n"); - } - enumerator->destroy(enumerator); - - fprintf(out, " subject: \"%Y\"\n", cert->get_subject(cert)); - fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); - serial = chunk_skip_zero(x509->get_serial(x509)); - fprintf(out, " serial: %#B\n", &serial); - - /* list validity */ - cert->get_validity(cert, &now, ¬Before, ¬After); - fprintf(out, " validity: not before %T, ", ¬Before, utc); - if (now < notBefore) - { - fprintf(out, "not valid yet (valid in %V)\n", &now, ¬Before); - } - else - { - fprintf(out, "ok\n"); - } - fprintf(out, " not after %T, ", ¬After, utc); - if (now > notAfter) - { - fprintf(out, "expired (%V ago)\n", &now, ¬After); - } - else - { - fprintf(out, "ok"); - if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %V)", &now, ¬After); - } - fprintf(out, " \n"); - } - - public = cert->get_public_key(cert); - if (public) - { - list_public_key(public, out); - public->destroy(public); - } - - /* list optional authorityKeyIdentifier */ - authkey = x509->get_authKeyIdentifier(x509); - if (authkey.ptr) - { - fprintf(out, " authkey: %#B\n", &authkey); - } - - /* list optional pathLenConstraint */ - pathlen = x509->get_constraint(x509, X509_PATH_LEN); - if (pathlen != X509_NO_CONSTRAINT) - { - fprintf(out, " pathlen: %u\n", pathlen); - } - - /* list optional ipAddrBlocks */ - if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS) - { - traffic_selector_t *ipAddrBlock; - bool first_ipAddrBlock = TRUE; - - fprintf(out, " addresses: "); - enumerator = x509->create_ipAddrBlock_enumerator(x509); - while (enumerator->enumerate(enumerator, &ipAddrBlock)) - { - if (first_ipAddrBlock) - { - first_ipAddrBlock = FALSE; - } - else - { - fprintf(out, ", "); - } - fprintf(out, "%R", ipAddrBlock); - } - enumerator->destroy(enumerator); - fprintf(out, "\n"); - } + cert_printer->print_caption(cert_printer, CERT_X509, flag); + cert_printer->print(cert_printer, cert, has_privkey(cert)); } } enumerator->destroy(enumerator); } /** - * list all X.509 attribute certificates + * list all other certificates types */ -static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out) +static void stroke_list_other_certs(certificate_type_t type) { - bool first = TRUE; - time_t notBefore, notAfter, now = time(NULL); enumerator_t *enumerator; certificate_t *cert; + linked_list_t *list; + + list = create_unique_cert_list(type); enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, &cert)) { - ac_t *ac = (ac_t*)cert; - ac_group_type_t type; - identification_t *id; - enumerator_t *groups; - chunk_t chunk; - bool firstgroup = TRUE; - - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of X.509 Attribute Certificates:\n"); - first = FALSE; - } - fprintf(out, "\n"); - - id = cert->get_subject(cert); - if (id) - { - fprintf(out, " holder: \"%Y\"\n", id); - } - id = ac->get_holderIssuer(ac); - if (id) - { - fprintf(out, " hissuer: \"%Y\"\n", id); - } - chunk = chunk_skip_zero(ac->get_holderSerial(ac)); - if (chunk.ptr) - { - fprintf(out, " hserial: %#B\n", &chunk); - } - groups = ac->create_group_enumerator(ac); - while (groups->enumerate(groups, &type, &chunk)) - { - int oid; - char *str; - - if (firstgroup) - { - fprintf(out, " groups: "); - firstgroup = FALSE; - } - else - { - fprintf(out, " "); - } - switch (type) - { - case AC_GROUP_TYPE_STRING: - fprintf(out, "%.*s", (int)chunk.len, chunk.ptr); - break; - case AC_GROUP_TYPE_OID: - oid = asn1_known_oid(chunk); - if (oid == OID_UNKNOWN) - { - str = asn1_oid_to_string(chunk); - if (str) - { - fprintf(out, "%s", str); - free(str); - } - else - { - fprintf(out, "OID:%#B", &chunk); - } - } - else - { - fprintf(out, "%s", oid_names[oid].name); - } - break; - case AC_GROUP_TYPE_OCTETS: - fprintf(out, "%#B", &chunk); - break; - } - fprintf(out, "\n"); - } - groups->destroy(groups); - fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); - chunk = chunk_skip_zero(ac->get_serial(ac)); - fprintf(out, " serial: %#B\n", &chunk); - - /* list validity */ - cert->get_validity(cert, &now, ¬Before, ¬After); - fprintf(out, " validity: not before %T, ", ¬Before, utc); - if (now < notBefore) - { - fprintf(out, "not valid yet (valid in %V)\n", &now, ¬Before); - } - else - { - fprintf(out, "ok\n"); - } - fprintf(out, " not after %T, ", ¬After, utc); - if (now > notAfter) - { - fprintf(out, "expired (%V ago)\n", &now, ¬After); - } - else - { - fprintf(out, "ok"); - if (now > notAfter - AC_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %V)", &now, ¬After); - } - fprintf(out, " \n"); - } - - /* list optional authorityKeyIdentifier */ - chunk = ac->get_authKeyIdentifier(ac); - if (chunk.ptr) - { - fprintf(out, " authkey: %#B\n", &chunk); - } + cert_printer->print_caption(cert_printer, cert->get_type(cert), X509_NONE); + cert_printer->print(cert_printer, cert, has_privkey(cert)); } enumerator->destroy(enumerator); -} - -/** - * list all X.509 CRLs - */ -static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out) -{ - bool first = TRUE; - time_t thisUpdate, nextUpdate, now = time(NULL); - enumerator_t *enumerator = list->create_enumerator(list); - certificate_t *cert; - while (enumerator->enumerate(enumerator, (void**)&cert)) - { - crl_t *crl = (crl_t*)cert; - chunk_t chunk; - - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of X.509 CRLs:\n"); - first = FALSE; - } - fprintf(out, "\n"); - - fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert)); - - /* list optional crlNumber */ - chunk = chunk_skip_zero(crl->get_serial(crl)); - if (chunk.ptr) - { - fprintf(out, " serial: %#B\n", &chunk); - } - if (crl->is_delta_crl(crl, &chunk)) - { - chunk = chunk_skip_zero(chunk); - fprintf(out, " delta for: %#B\n", &chunk); - } - - /* count the number of revoked certificates */ - { - int count = 0; - enumerator_t *enumerator = crl->create_enumerator(crl); - - while (enumerator->enumerate(enumerator, NULL, NULL, NULL)) - { - count++; - } - fprintf(out, " revoked: %d certificate%s\n", count, - (count == 1)? "" : "s"); - enumerator->destroy(enumerator); - } - - /* list validity */ - cert->get_validity(cert, &now, &thisUpdate, &nextUpdate); - fprintf(out, " updates: this %T\n", &thisUpdate, utc); - fprintf(out, " next %T, ", &nextUpdate, utc); - if (now > nextUpdate) - { - fprintf(out, "expired (%V ago)\n", &now, &nextUpdate); - } - else - { - fprintf(out, "ok"); - if (now > nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %V)", &now, &nextUpdate); - } - fprintf(out, " \n"); - } - - /* list optional authorityKeyIdentifier */ - chunk = crl->get_authKeyIdentifier(crl); - if (chunk.ptr) - { - fprintf(out, " authkey: %#B\n", &chunk); - } - } - enumerator->destroy(enumerator); -} - -/** - * list all OCSP responses - */ -static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out) -{ - bool first = TRUE, ok; - enumerator_t *enumerator = list->create_enumerator(list); - certificate_t *cert; - time_t produced, usable, now = time(NULL); - - while (enumerator->enumerate(enumerator, (void**)&cert)) - { - if (first) - { - fprintf(out, "\n"); - fprintf(out, "List of OCSP responses:\n"); - fprintf(out, "\n"); - first = FALSE; - } - fprintf(out, " signer: \"%Y\"\n", cert->get_issuer(cert)); - - /* check validity */ - ok = cert->get_validity(cert, &now, &produced, &usable); - fprintf(out, " validity: produced at %T\n", &produced, utc); - fprintf(out, " usable till %T, ", &usable, utc); - if (ok) - { - fprintf(out, "ok\n"); - } - else - { - fprintf(out, "expired (%V ago)\n", &now, &usable); - } - } - enumerator->destroy(enumerator); + list->destroy_offset(list, offsetof(certificate_t, destroy)); } /** @@ -1439,19 +976,15 @@ METHOD(stroke_list_t, list, void, { linked_list_t *cert_list = NULL; + cert_printer = certificate_printer_create(out, TRUE, msg->list.utc); + if (msg->list.flags & LIST_PUBKEYS) { - linked_list_t *pubkey_list = create_unique_cert_list(CERT_TRUSTED_PUBKEY); - - stroke_list_pubkeys(pubkey_list, msg->list.utc, out); - pubkey_list->destroy_offset(pubkey_list, offsetof(certificate_t, destroy)); + stroke_list_other_certs(CERT_TRUSTED_PUBKEY); } if (msg->list.flags & LIST_CERTS) { - linked_list_t *pgp_list = create_unique_cert_list(CERT_GPG); - - stroke_list_pgp(pgp_list, msg->list.utc, out); - pgp_list->destroy_offset(pgp_list, offsetof(certificate_t, destroy)); + stroke_list_other_certs(CERT_GPG); } if (msg->list.flags & (LIST_CERTS | LIST_CACERTS | LIST_OCSPCERTS | LIST_AACERTS)) { @@ -1459,47 +992,33 @@ METHOD(stroke_list_t, list, void, } if (msg->list.flags & LIST_CERTS) { - stroke_list_certs(cert_list, "X.509 End Entity Certificates", - X509_NONE, msg->list.utc, out); + stroke_list_x509_certs(cert_list, X509_NONE); } if (msg->list.flags & LIST_CACERTS) { - stroke_list_certs(cert_list, "X.509 CA Certificates", - X509_CA, msg->list.utc, out); + stroke_list_x509_certs(cert_list, X509_CA); } if (msg->list.flags & LIST_OCSPCERTS) { - stroke_list_certs(cert_list, "X.509 OCSP Signer Certificates", - X509_OCSP_SIGNER, msg->list.utc, out); + stroke_list_x509_certs(cert_list, X509_OCSP_SIGNER); } if (msg->list.flags & LIST_AACERTS) { - stroke_list_certs(cert_list, "X.509 AA Certificates", - X509_AA, msg->list.utc, out); + stroke_list_x509_certs(cert_list, X509_AA); } DESTROY_OFFSET_IF(cert_list, offsetof(certificate_t, destroy)); if (msg->list.flags & LIST_ACERTS) { - linked_list_t *ac_list = create_unique_cert_list(CERT_X509_AC); - - stroke_list_acerts(ac_list, msg->list.utc, out); - ac_list->destroy_offset(ac_list, offsetof(certificate_t, destroy)); + stroke_list_other_certs(CERT_X509_AC); } if (msg->list.flags & LIST_CRLS) { - linked_list_t *crl_list = create_unique_cert_list(CERT_X509_CRL); - - stroke_list_crls(crl_list, msg->list.utc, out); - crl_list->destroy_offset(crl_list, offsetof(certificate_t, destroy)); + stroke_list_other_certs(CERT_X509_CRL); } if (msg->list.flags & LIST_OCSP) { - linked_list_t *ocsp_list = create_unique_cert_list(CERT_X509_OCSP_RESPONSE); - - stroke_list_ocsp(ocsp_list, msg->list.utc, out); - - ocsp_list->destroy_offset(ocsp_list, offsetof(certificate_t, destroy)); + stroke_list_other_certs(CERT_X509_OCSP_RESPONSE); } if (msg->list.flags & LIST_ALGS) { @@ -1509,6 +1028,8 @@ METHOD(stroke_list_t, list, void, { list_plugins(out); } + cert_printer->destroy(cert_printer); + cert_printer = NULL; } /** diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 29563e32f..ee32dbca2 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -590,17 +590,10 @@ static void stroke_loglevel(private_stroke_socket_t *this, fprintf(out, "command not allowed!\n"); return; } - if (strcaseeq(msg->loglevel.type, "any")) + if (!enum_from_name(debug_names, msg->loglevel.type, &group)) { - group = DBG_ANY; - } - else - { - if (!enum_from_name(debug_names, msg->loglevel.type, &group)) - { - fprintf(out, "unknown type '%s'!\n", msg->loglevel.type); - return; - } + fprintf(out, "unknown type '%s'!\n", msg->loglevel.type); + return; } charon->set_level(charon, group, msg->loglevel.level); } diff --git a/src/libcharon/plugins/systime_fix/Makefile.am b/src/libcharon/plugins/systime_fix/Makefile.am index 40a346440..95a33230f 100644 --- a/src/libcharon/plugins/systime_fix/Makefile.am +++ b/src/libcharon/plugins/systime_fix/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon if MONOLITHIC diff --git a/src/libcharon/plugins/systime_fix/Makefile.in b/src/libcharon/plugins/systime_fix/Makefile.in index be148b6c3..0daff4434 100644 --- a/src/libcharon/plugins/systime_fix/Makefile.in +++ b/src/libcharon/plugins/systime_fix/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-systime-fix.la diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.am b/src/libcharon/plugins/tnc_ifmap/Makefile.am index 90fbf4651..dab98129d 100644 --- a/src/libcharon/plugins/tnc_ifmap/Makefile.am +++ b/src/libcharon/plugins/tnc_ifmap/Makefile.am @@ -1,7 +1,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libtls \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in index 17cc341c5..f124a1b38 100644 --- a/src/libcharon/plugins/tnc_ifmap/Makefile.in +++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in @@ -419,6 +419,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -435,7 +437,6 @@ xml_LIBS = @xml_LIBS@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libtls \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c index d2ba2e345..2bad4fab0 100644 --- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c @@ -18,7 +18,6 @@ #include "tnc_ifmap_renew_session_job.h" #include -#include #include #define IFMAP_RENEW_SESSION_INTERVAL 150 @@ -51,8 +50,8 @@ static bool publish_device_ip_addresses(private_tnc_ifmap_listener_t *this) host_t *host; bool success = TRUE; - enumerator = hydra->kernel_interface->create_address_enumerator( - hydra->kernel_interface, ADDR_TYPE_REGULAR); + enumerator = charon->kernel->create_address_enumerator(charon->kernel, + ADDR_TYPE_REGULAR); while (enumerator->enumerate(enumerator, &host)) { if (!this->ifmap->publish_device_ip(this->ifmap, host)) diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.am b/src/libcharon/plugins/tnc_pdp/Makefile.am index 3478c5b30..fcda7d76f 100644 --- a/src/libcharon/plugins/tnc_pdp/Makefile.am +++ b/src/libcharon/plugins/tnc_pdp/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon \ -I$(top_srcdir)/src/libradius \ -I$(top_srcdir)/src/libtncif \ diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in index ef05275b7..bfd8cf820 100644 --- a/src/libcharon/plugins/tnc_pdp/Makefile.in +++ b/src/libcharon/plugins/tnc_pdp/Makefile.in @@ -420,6 +420,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -435,7 +437,6 @@ 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 \ -I$(top_srcdir)/src/libradius \ -I$(top_srcdir)/src/libtncif \ diff --git a/src/libcharon/plugins/uci/Makefile.am b/src/libcharon/plugins/uci/Makefile.am index 134ced0e3..296c8db04 100644 --- a/src/libcharon/plugins/uci/Makefile.am +++ b/src/libcharon/plugins/uci/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in index 2c031383a..a1c64ca1b 100644 --- a/src/libcharon/plugins/uci/Makefile.in +++ b/src/libcharon/plugins/uci/Makefile.in @@ -414,6 +414,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -429,7 +431,6 @@ 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 = \ diff --git a/src/libcharon/plugins/unity/Makefile.am b/src/libcharon/plugins/unity/Makefile.am index 38923e068..1244cb317 100644 --- a/src/libcharon/plugins/unity/Makefile.am +++ b/src/libcharon/plugins/unity/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/unity/Makefile.in b/src/libcharon/plugins/unity/Makefile.in index 4f0a7e736..00bb1498c 100644 --- a/src/libcharon/plugins/unity/Makefile.in +++ b/src/libcharon/plugins/unity/Makefile.in @@ -415,6 +415,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -430,7 +432,6 @@ 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 = \ diff --git a/src/libcharon/plugins/updown/Makefile.am b/src/libcharon/plugins/updown/Makefile.am index f03f4744c..f8738adee 100644 --- a/src/libcharon/plugins/updown/Makefile.am +++ b/src/libcharon/plugins/updown/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in index 619d17a0e..863e14430 100644 --- a/src/libcharon/plugins/updown/Makefile.in +++ b/src/libcharon/plugins/updown/Makefile.in @@ -416,6 +416,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -431,7 +433,6 @@ 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 = \ diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c index 96282bee0..e51caab10 100644 --- a/src/libcharon/plugins/updown/updown_listener.c +++ b/src/libcharon/plugins/updown/updown_listener.c @@ -1,7 +1,8 @@ /* * Copyright (C) 2013 Tobias Brunner * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2016 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -21,7 +22,6 @@ #include "updown_listener.h" #include -#include #include #include @@ -205,25 +205,47 @@ static void push_vip_env(private_updown_listener_t *this, ike_sa_t *ike_sa, enumerator->destroy(enumerator); } +#define PORT_BUF_LEN 12 + /** * Determine proper values for port env variable */ -static u_int16_t get_port(traffic_selector_t *me, - traffic_selector_t *other, bool local) +static char* get_port(traffic_selector_t *me, traffic_selector_t *other, + char *port_buf, bool local) { + uint16_t port, to, from; + switch (max(me->get_protocol(me), other->get_protocol(other))) { case IPPROTO_ICMP: case IPPROTO_ICMPV6: { - u_int16_t port = me->get_from_port(me); - - port = max(port, other->get_from_port(other)); - return local ? traffic_selector_icmp_type(port) - : traffic_selector_icmp_code(port); + port = max(me->get_from_port(me), other->get_from_port(other)); + snprintf(port_buf, PORT_BUF_LEN, "%u", + local ? traffic_selector_icmp_type(port) + : traffic_selector_icmp_code(port)); + return port_buf; } } - return local ? me->get_from_port(me) : other->get_from_port(other); + if (local) + { + from = me->get_from_port(me); + to = me->get_to_port(me); + } + else + { + from = other->get_from_port(other); + to = other->get_to_port(other); + } + if (from == to || (from == 0 && to == 65535)) + { + snprintf(port_buf, PORT_BUF_LEN, "%u", from); + } + else + { + snprintf(port_buf, PORT_BUF_LEN, "%u:%u", from, to); + } + return port_buf; } /** @@ -241,6 +263,7 @@ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa, int out; FILE *shell; process_t *process; + char port_buf[PORT_BUF_LEN]; char *envp[128] = {}; me = ike_sa->get_my_host(ike_sa); @@ -265,8 +288,7 @@ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa, config->get_name(config)); if (up) { - if (hydra->kernel_interface->get_interface(hydra->kernel_interface, - me, &iface)) + if (charon->kernel->get_interface(charon->kernel, me, &iface)) { cache_iface(this, child_sa->get_reqid(child_sa), iface); } @@ -289,25 +311,29 @@ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa, 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)) + if (!my_ts->to_subnet(my_ts, &host, &mask)) { - push_env(envp, countof(envp), "PLUTO_MY_CLIENT=%+H/%u", host, mask); - host->destroy(host); + DBG1(DBG_CHD, "updown approximates local TS %R " + "by next larger subnet", my_ts); } - push_env(envp, countof(envp), "PLUTO_MY_PORT=%u", - get_port(my_ts, other_ts, TRUE)); + push_env(envp, countof(envp), "PLUTO_MY_CLIENT=%+H/%u", host, mask); + host->destroy(host); + push_env(envp, countof(envp), "PLUTO_MY_PORT=%s", + get_port(my_ts, other_ts, port_buf, 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)) + if (!other_ts->to_subnet(other_ts, &host, &mask)) { - push_env(envp, countof(envp), "PLUTO_PEER_CLIENT=%+H/%u", host, mask); - host->destroy(host); + DBG1(DBG_CHD, "updown approximates remote TS %R " + "by next larger subnet", other_ts); } - push_env(envp, countof(envp), "PLUTO_PEER_PORT=%u", - get_port(my_ts, other_ts, FALSE)); + push_env(envp, countof(envp), "PLUTO_PEER_CLIENT=%+H/%u", host, mask); + host->destroy(host); + push_env(envp, countof(envp), "PLUTO_PEER_PORT=%s", + get_port(my_ts, other_ts, port_buf, 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) || diff --git a/src/libcharon/plugins/vici/Makefile.am b/src/libcharon/plugins/vici/Makefile.am index c99d23e4e..ca9b49906 100644 --- a/src/libcharon/plugins/vici/Makefile.am +++ b/src/libcharon/plugins/vici/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libstrongswan/plugins/pubkey \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" @@ -18,6 +18,7 @@ libstrongswan_vici_la_SOURCES = \ vici_message.h vici_message.c \ vici_builder.h vici_builder.c \ vici_dispatcher.h vici_dispatcher.c \ + vici_cert_info.h vici_cert_info.c \ vici_query.h vici_query.c \ vici_control.h vici_control.c \ vici_config.h vici_config.c \ @@ -38,6 +39,7 @@ ipseclib_LTLIBRARIES = libvici.la libvici_la_SOURCES = \ vici_message.c vici_message.h \ vici_builder.c vici_builder.h \ + vici_cert_info.h vici_cert_info.c \ libvici.c libvici.h libvici_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la @@ -79,3 +81,7 @@ endif if USE_PYTHON_EGGS SUBDIRS += python endif + +if USE_PERL_CPAN +SUBDIRS += perl +endif diff --git a/src/libcharon/plugins/vici/Makefile.in b/src/libcharon/plugins/vici/Makefile.in index 1a7870ae9..86ed00792 100644 --- a/src/libcharon/plugins/vici/Makefile.in +++ b/src/libcharon/plugins/vici/Makefile.in @@ -82,6 +82,7 @@ TESTS = vici_tests$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) @USE_RUBY_GEMS_TRUE@am__append_1 = ruby @USE_PYTHON_EGGS_TRUE@am__append_2 = python +@USE_PERL_CPAN_TRUE@am__append_3 = perl subdir = src/libcharon/plugins/vici DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -134,9 +135,10 @@ LTLIBRARIES = $(ipseclib_LTLIBRARIES) $(noinst_LTLIBRARIES) \ $(plugin_LTLIBRARIES) libstrongswan_vici_la_LIBADD = am_libstrongswan_vici_la_OBJECTS = vici_socket.lo vici_message.lo \ - vici_builder.lo vici_dispatcher.lo vici_query.lo \ - vici_control.lo vici_config.lo vici_cred.lo vici_attribute.lo \ - vici_authority.lo vici_logger.lo vici_plugin.lo + vici_builder.lo vici_dispatcher.lo vici_cert_info.lo \ + vici_query.lo vici_control.lo vici_config.lo vici_cred.lo \ + vici_attribute.lo vici_authority.lo vici_logger.lo \ + vici_plugin.lo libstrongswan_vici_la_OBJECTS = $(am_libstrongswan_vici_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -150,7 +152,8 @@ libstrongswan_vici_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @MONOLITHIC_TRUE@am_libstrongswan_vici_la_rpath = libvici_la_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la -am_libvici_la_OBJECTS = vici_message.lo vici_builder.lo libvici.lo +am_libvici_la_OBJECTS = vici_message.lo vici_builder.lo \ + vici_cert_info.lo libvici.lo libvici_la_OBJECTS = $(am_libvici_la_OBJECTS) am__EXEEXT_1 = vici_tests$(EXEEXT) am__dirstamp = $(am__leading_dot)dirstamp @@ -270,7 +273,7 @@ am__tty_colors = { \ std=''; \ fi; \ } -DIST_SUBDIRS = ruby python +DIST_SUBDIRS = ruby python perl DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -509,6 +512,8 @@ strongswan_conf = @strongswan_conf@ strongswan_options = @strongswan_options@ swanctldir = @swanctldir@ sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ systemd_daemon_LIBS = @systemd_daemon_LIBS@ systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ @@ -524,7 +529,7 @@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libstrongswan/plugins/pubkey \ -I$(top_srcdir)/src/libcharon \ -DIPSEC_PIDDIR=\"${piddir}\" @@ -538,6 +543,7 @@ libstrongswan_vici_la_SOURCES = \ vici_message.h vici_message.c \ vici_builder.h vici_builder.c \ vici_dispatcher.h vici_dispatcher.c \ + vici_cert_info.h vici_cert_info.c \ vici_query.h vici_query.c \ vici_control.h vici_control.c \ vici_config.h vici_config.c \ @@ -553,6 +559,7 @@ ipseclib_LTLIBRARIES = libvici.la libvici_la_SOURCES = \ vici_message.c vici_message.h \ vici_builder.c vici_builder.h \ + vici_cert_info.h vici_cert_info.c \ libvici.c libvici.h libvici_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la @@ -578,7 +585,7 @@ vici_tests_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ $(top_builddir)/src/libstrongswan/tests/libtest.la -SUBDIRS = $(am__append_1) $(am__append_2) +SUBDIRS = $(am__append_1) $(am__append_2) $(am__append_3) all: all-recursive .SUFFIXES: @@ -739,6 +746,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vici_attribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vici_authority.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vici_builder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vici_cert_info.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vici_config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vici_control.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vici_cred.Plo@am__quote@ diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md index b9531d8a5..52929bd74 100644 --- a/src/libcharon/plugins/vici/README.md +++ b/src/libcharon/plugins/vici/README.md @@ -258,7 +258,8 @@ Initiates an SA while streaming _control-log_ events. { child = - timeout = + ike = + timeout = init-limits = loglevel = } => { @@ -266,6 +267,9 @@ Initiates an SA while streaming _control-log_ events. errmsg = } +The default timeout of 0 waits indefinitely for a result, and a timeout value +of -1 returns a result immediately. + ### terminate() ### Terminates an SA while streaming _control-log_ events. @@ -275,19 +279,40 @@ Terminates an SA while streaming _control-log_ events. ike = child_id = ike_id = - timeout = + timeout = loglevel = } => { success = errmsg = } +The default timeout of 0 waits indefinitely for a result, and a timeout value +of -1 returns a result immediately. + +### redirect() ### + +Redirect a client-initiated IKE_SA to another gateway. Only for IKEv2 and if +supported by the peer. + + { + ike = + ike-id = + peer-ip = + peer-id = + } => { + success = + errmsg = + } + ### install() ### Install a trap, drop or bypass policy defined by a CHILD_SA config. { child = + ike = } => { success = errmsg = @@ -361,7 +386,9 @@ call includes all certificates known by the daemon, not only those loaded over vici. { - type = + type = + flag = subject = } => { # completes after streaming list-cert events @@ -419,7 +446,8 @@ Unload a previously loaded connection definition by name. Load a certificate into the daemon. { - type = + type = + flag = data = } => { success = @@ -544,6 +572,16 @@ List the currently loaded pools. } } +### get-algorithms() ### + +List currently loaded algorithms and their implementation. + + {} => { + = { + = + } + } + ## Server-issued events ## Based on the packet layer, the vici plugin raises event messages using named @@ -588,8 +626,10 @@ command. version = state = local-host = + local-port = local-id = remote-host = + remote-port = remote-id = remote-xauth-id = remote-eap-id = @@ -735,9 +775,13 @@ The _list-cert_ event is issued to stream loaded certificates during an active _list-certs_ command. { - type = + type = + flag = has_privkey = data = + subject = + not-before =