summaryrefslogtreecommitdiff
path: root/src/libcharon
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon')
-rw-r--r--src/libcharon/Android.mk8
-rw-r--r--src/libcharon/Makefile.am54
-rw-r--r--src/libcharon/Makefile.in406
-rw-r--r--src/libcharon/attributes/attribute_handler.h76
-rw-r--r--src/libcharon/attributes/attribute_manager.c347
-rw-r--r--src/libcharon/attributes/attribute_manager.h154
-rw-r--r--src/libcharon/attributes/attribute_provider.h71
-rw-r--r--src/libcharon/attributes/attributes.c114
-rw-r--r--src/libcharon/attributes/attributes.h91
-rw-r--r--src/libcharon/attributes/mem_pool.c735
-rw-r--r--src/libcharon/attributes/mem_pool.h154
-rw-r--r--src/libcharon/bus/bus.c28
-rw-r--r--src/libcharon/bus/bus.h9
-rw-r--r--src/libcharon/bus/listeners/listener.h11
-rw-r--r--src/libcharon/config/ike_cfg.c17
-rw-r--r--src/libcharon/config/proposal.c2
-rw-r--r--src/libcharon/control/controller.c44
-rw-r--r--src/libcharon/control/controller.h4
-rw-r--r--src/libcharon/daemon.c7
-rw-r--r--src/libcharon/daemon.h15
-rw-r--r--src/libcharon/encoding/message.c16
-rw-r--r--src/libcharon/encoding/parser.c21
-rw-r--r--src/libcharon/encoding/parser.h12
-rw-r--r--src/libcharon/encoding/payloads/delete_payload.c15
-rw-r--r--src/libcharon/encoding/payloads/delete_payload.h10
-rw-r--r--src/libcharon/encoding/payloads/encrypted_payload.c1
-rw-r--r--src/libcharon/encoding/payloads/id_payload.c7
-rw-r--r--src/libcharon/encoding/payloads/ke_payload.c10
-rw-r--r--src/libcharon/encoding/payloads/ke_payload.h2
-rw-r--r--src/libcharon/encoding/payloads/notify_payload.c22
-rw-r--r--src/libcharon/encoding/payloads/notify_payload.h2
-rw-r--r--src/libcharon/encoding/payloads/payload.c62
-rw-r--r--src/libcharon/encoding/payloads/payload.h3
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.c276
-rw-r--r--src/libcharon/kernel/kernel_handler.c25
-rw-r--r--src/libcharon/plugins/addrblock/Makefile.in5
-rw-r--r--src/libcharon/plugins/android_dns/Makefile.in5
-rw-r--r--src/libcharon/plugins/android_dns/android_dns_handler.c7
-rw-r--r--src/libcharon/plugins/android_dns/android_dns_plugin.c9
-rw-r--r--src/libcharon/plugins/android_log/Makefile.in5
-rw-r--r--src/libcharon/plugins/attr/Makefile.am19
-rw-r--r--src/libcharon/plugins/attr/Makefile.in777
-rw-r--r--src/libcharon/plugins/attr/attr_plugin.c109
-rw-r--r--src/libcharon/plugins/attr/attr_plugin.h (renamed from src/libcharon/plugins/unit_tester/tests.h)36
-rw-r--r--src/libcharon/plugins/attr/attr_provider.c329
-rw-r--r--src/libcharon/plugins/attr/attr_provider.h54
-rw-r--r--src/libcharon/plugins/attr_sql/Makefile.am19
-rw-r--r--src/libcharon/plugins/attr_sql/Makefile.in (renamed from src/libcharon/plugins/unit_tester/Makefile.in)105
-rw-r--r--src/libcharon/plugins/attr_sql/attr_sql_plugin.c129
-rw-r--r--src/libcharon/plugins/attr_sql/attr_sql_plugin.h (renamed from src/libcharon/plugins/unit_tester/unit_tester.h)28
-rw-r--r--src/libcharon/plugins/attr_sql/attr_sql_provider.c478
-rw-r--r--src/libcharon/plugins/attr_sql/attr_sql_provider.h50
-rw-r--r--src/libcharon/plugins/certexpire/Makefile.in5
-rw-r--r--src/libcharon/plugins/connmark/Makefile.am20
-rw-r--r--src/libcharon/plugins/connmark/Makefile.in782
-rw-r--r--src/libcharon/plugins/connmark/connmark_listener.c538
-rw-r--r--src/libcharon/plugins/connmark/connmark_listener.h49
-rw-r--r--src/libcharon/plugins/connmark/connmark_plugin.c105
-rw-r--r--src/libcharon/plugins/connmark/connmark_plugin.h42
-rw-r--r--src/libcharon/plugins/coupling/Makefile.in5
-rw-r--r--src/libcharon/plugins/dhcp/Makefile.in5
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_plugin.c9
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_provider.c12
-rw-r--r--src/libcharon/plugins/dnscert/Makefile.in5
-rw-r--r--src/libcharon/plugins/duplicheck/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_aka/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_dynamic/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_gtc/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_identity/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_md5/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_mschapv2/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_peap/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_radius/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_accounting.c2
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_plugin.c23
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_provider.c24
-rw-r--r--src/libcharon/plugins/eap_sim/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_sim_file/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_tls/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls.c7
-rw-r--r--src/libcharon/plugins/eap_tnc/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc.c27
-rw-r--r--src/libcharon/plugins/eap_ttls/Makefile.in5
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls.c7
-rw-r--r--src/libcharon/plugins/error_notify/Makefile.in5
-rw-r--r--src/libcharon/plugins/ext_auth/Makefile.in5
-rw-r--r--src/libcharon/plugins/farp/Makefile.in5
-rw-r--r--src/libcharon/plugins/forecast/Makefile.am21
-rw-r--r--src/libcharon/plugins/forecast/Makefile.in784
-rw-r--r--src/libcharon/plugins/forecast/forecast_forwarder.c496
-rw-r--r--src/libcharon/plugins/forecast/forecast_forwarder.h47
-rw-r--r--src/libcharon/plugins/forecast/forecast_listener.c680
-rw-r--r--src/libcharon/plugins/forecast/forecast_listener.h68
-rw-r--r--src/libcharon/plugins/forecast/forecast_plugin.c118
-rw-r--r--src/libcharon/plugins/forecast/forecast_plugin.h42
-rw-r--r--src/libcharon/plugins/ha/Makefile.in5
-rw-r--r--src/libcharon/plugins/ha/ha_attribute.c4
-rw-r--r--src/libcharon/plugins/ha/ha_cache.c29
-rw-r--r--src/libcharon/plugins/ha/ha_child.c4
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c15
-rw-r--r--src/libcharon/plugins/ha/ha_ike.c10
-rw-r--r--src/libcharon/plugins/ha/ha_plugin.c10
-rw-r--r--src/libcharon/plugins/ipseckey/Makefile.in5
-rw-r--r--src/libcharon/plugins/kernel_iph/Makefile.in5
-rw-r--r--src/libcharon/plugins/kernel_libipsec/Makefile.in5
-rw-r--r--src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c20
-rw-r--r--src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c110
-rw-r--r--src/libcharon/plugins/kernel_wfp/Makefile.in5
-rw-r--r--src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c36
-rw-r--r--src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h10
-rw-r--r--src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c258
-rw-r--r--src/libcharon/plugins/led/Makefile.in5
-rw-r--r--src/libcharon/plugins/load_tester/Makefile.in5
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_config.c24
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c51
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_ipsec.c8
-rw-r--r--src/libcharon/plugins/lookip/Makefile.in5
-rw-r--r--src/libcharon/plugins/maemo/Makefile.in5
-rw-r--r--src/libcharon/plugins/medcli/Makefile.in5
-rw-r--r--src/libcharon/plugins/medsrv/Makefile.in5
-rw-r--r--src/libcharon/plugins/osx_attr/Makefile.in5
-rw-r--r--src/libcharon/plugins/osx_attr/osx_attr_handler.c6
-rw-r--r--src/libcharon/plugins/osx_attr/osx_attr_plugin.c9
-rw-r--r--src/libcharon/plugins/radattr/Makefile.in5
-rw-r--r--src/libcharon/plugins/resolve/Makefile.am20
-rw-r--r--src/libcharon/plugins/resolve/Makefile.in781
-rw-r--r--src/libcharon/plugins/resolve/resolve_handler.c380
-rw-r--r--src/libcharon/plugins/resolve/resolve_handler.h49
-rw-r--r--src/libcharon/plugins/resolve/resolve_plugin.c101
-rw-r--r--src/libcharon/plugins/resolve/resolve_plugin.h42
-rw-r--r--src/libcharon/plugins/smp/Makefile.in5
-rw-r--r--src/libcharon/plugins/socket_default/Makefile.in5
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.c76
-rw-r--r--src/libcharon/plugins/socket_dynamic/Makefile.in5
-rw-r--r--src/libcharon/plugins/socket_win/Makefile.in5
-rw-r--r--src/libcharon/plugins/sql/Makefile.in5
-rw-r--r--src/libcharon/plugins/stroke/Makefile.in5
-rw-r--r--src/libcharon/plugins/stroke/stroke_attribute.c27
-rw-r--r--src/libcharon/plugins/stroke/stroke_ca.c81
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c74
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c8
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c315
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.h7
-rw-r--r--src/libcharon/plugins/stroke/stroke_handler.c3
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c16
-rw-r--r--src/libcharon/plugins/stroke/stroke_plugin.c1
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c13
-rw-r--r--src/libcharon/plugins/systime_fix/Makefile.in5
-rw-r--r--src/libcharon/plugins/tnc_ifmap/Makefile.in5
-rw-r--r--src/libcharon/plugins/tnc_pdp/Makefile.in5
-rw-r--r--src/libcharon/plugins/tnc_pdp/tnc_pdp.c25
-rw-r--r--src/libcharon/plugins/uci/Makefile.in5
-rw-r--r--src/libcharon/plugins/unit_tester/Makefile.am26
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_agent.c67
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_auth_info.c140
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_cert.c108
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_curl.c44
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_med_db.c54
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_mysql.c89
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_pool.c100
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_sqlite.c93
-rw-r--r--src/libcharon/plugins/unit_tester/unit_tester.c152
-rw-r--r--src/libcharon/plugins/unity/Makefile.in5
-rw-r--r--src/libcharon/plugins/unity/unity_handler.c29
-rw-r--r--src/libcharon/plugins/unity/unity_handler.h5
-rw-r--r--src/libcharon/plugins/unity/unity_narrow.c90
-rw-r--r--src/libcharon/plugins/unity/unity_plugin.c17
-rw-r--r--src/libcharon/plugins/unity/unity_provider.c6
-rw-r--r--src/libcharon/plugins/updown/Makefile.in5
-rw-r--r--src/libcharon/plugins/updown/updown_handler.c57
-rw-r--r--src/libcharon/plugins/updown/updown_listener.c1
-rw-r--r--src/libcharon/plugins/updown/updown_plugin.c9
-rw-r--r--src/libcharon/plugins/vici/Makefile.am4
-rw-r--r--src/libcharon/plugins/vici/Makefile.in10
-rw-r--r--src/libcharon/plugins/vici/README.md97
-rw-r--r--src/libcharon/plugins/vici/libvici.c8
-rw-r--r--src/libcharon/plugins/vici/python/LICENSE19
-rw-r--r--src/libcharon/plugins/vici/python/MANIFEST.in1
-rw-r--r--src/libcharon/plugins/vici/python/Makefile.am33
-rw-r--r--src/libcharon/plugins/vici/python/Makefile.in686
-rw-r--r--src/libcharon/plugins/vici/python/setup.py.in34
-rw-r--r--src/libcharon/plugins/vici/python/vici/__init__.py1
-rw-r--r--src/libcharon/plugins/vici/python/vici/compat.py14
-rw-r--r--src/libcharon/plugins/vici/python/vici/exception.py10
-rw-r--r--src/libcharon/plugins/vici/python/vici/protocol.py196
-rw-r--r--src/libcharon/plugins/vici/python/vici/session.py327
-rw-r--r--src/libcharon/plugins/vici/python/vici/test/__init__.py0
-rw-r--r--src/libcharon/plugins/vici/python/vici/test/test_protocol.py144
-rw-r--r--src/libcharon/plugins/vici/ruby/Makefile.am6
-rw-r--r--src/libcharon/plugins/vici/ruby/Makefile.in11
-rw-r--r--src/libcharon/plugins/vici/ruby/lib/vici.rb30
-rw-r--r--src/libcharon/plugins/vici/ruby/vici.gemspec.in2
-rw-r--r--src/libcharon/plugins/vici/vici_attribute.c67
-rw-r--r--src/libcharon/plugins/vici/vici_builder.c79
-rw-r--r--src/libcharon/plugins/vici/vici_builder.h8
-rw-r--r--src/libcharon/plugins/vici/vici_config.c51
-rw-r--r--src/libcharon/plugins/vici/vici_control.c4
-rw-r--r--src/libcharon/plugins/vici/vici_plugin.c9
-rw-r--r--src/libcharon/plugins/vici/vici_query.c17
-rw-r--r--src/libcharon/plugins/whitelist/Makefile.in5
-rw-r--r--src/libcharon/plugins/xauth_eap/Makefile.in5
-rw-r--r--src/libcharon/plugins/xauth_generic/Makefile.in5
-rw-r--r--src/libcharon/plugins/xauth_noauth/Makefile.in5
-rw-r--r--src/libcharon/plugins/xauth_pam/Makefile.in5
-rw-r--r--src/libcharon/processing/jobs/adopt_children_job.c58
-rw-r--r--src/libcharon/processing/jobs/delete_child_sa_job.c26
-rw-r--r--src/libcharon/processing/jobs/delete_child_sa_job.h9
-rw-r--r--src/libcharon/processing/jobs/dpd_timeout_job.c6
-rw-r--r--src/libcharon/processing/jobs/inactivity_job.c16
-rw-r--r--src/libcharon/processing/jobs/inactivity_job.h4
-rw-r--r--src/libcharon/processing/jobs/initiate_tasks_job.c96
-rw-r--r--src/libcharon/processing/jobs/initiate_tasks_job.h49
-rw-r--r--src/libcharon/processing/jobs/migrate_job.c62
-rw-r--r--src/libcharon/processing/jobs/migrate_job.h2
-rw-r--r--src/libcharon/processing/jobs/rekey_child_sa_job.c27
-rw-r--r--src/libcharon/processing/jobs/rekey_child_sa_job.h10
-rw-r--r--src/libcharon/processing/jobs/rekey_ike_sa_job.c3
-rw-r--r--src/libcharon/processing/jobs/update_sa_job.c33
-rw-r--r--src/libcharon/processing/jobs/update_sa_job.h8
-rw-r--r--src/libcharon/sa/authenticator.c9
-rw-r--r--src/libcharon/sa/authenticator.h10
-rw-r--r--src/libcharon/sa/child_sa.c147
-rw-r--r--src/libcharon/sa/child_sa.h25
-rw-r--r--src/libcharon/sa/child_sa_manager.c333
-rw-r--r--src/libcharon/sa/child_sa_manager.h89
-rw-r--r--src/libcharon/sa/eap/eap_method.h12
-rw-r--r--src/libcharon/sa/ike_sa.c82
-rw-r--r--src/libcharon/sa/ike_sa.h10
-rw-r--r--src/libcharon/sa/ike_sa_manager.c95
-rw-r--r--src/libcharon/sa/ike_sa_manager.h10
-rw-r--r--src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c10
-rw-r--r--src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c11
-rw-r--r--src/libcharon/sa/ikev1/keymat_v1.c9
-rw-r--r--src/libcharon/sa/ikev1/phase1.c14
-rw-r--r--src/libcharon/sa/ikev1/task_manager_v1.c5
-rw-r--r--src/libcharon/sa/ikev1/tasks/isakmp_delete.c39
-rw-r--r--src/libcharon/sa/ikev1/tasks/main_mode.c39
-rw-r--r--src/libcharon/sa/ikev1/tasks/mode_config.c137
-rw-r--r--src/libcharon/sa/ikev1/tasks/quick_delete.c6
-rw-r--r--src/libcharon/sa/ikev1/tasks/quick_mode.c76
-rw-r--r--src/libcharon/sa/ikev1/tasks/quick_mode.h8
-rw-r--r--src/libcharon/sa/ikev2/authenticators/eap_authenticator.c7
-rw-r--r--src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c314
-rw-r--r--src/libcharon/sa/ikev2/keymat_v2.c35
-rw-r--r--src/libcharon/sa/ikev2/keymat_v2.h18
-rw-r--r--src/libcharon/sa/ikev2/task_manager_v2.c113
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_create.c84
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_create.h8
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_delete.c4
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_rekey.c10
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_cert_pre.c4
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_config.c19
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_init.c206
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_mobike.c27
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_reauth.h2
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c102
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h56
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_rekey.c36
-rw-r--r--src/libcharon/sa/task.c1
-rw-r--r--src/libcharon/sa/task.h6
-rw-r--r--src/libcharon/sa/trap_manager.c11
-rw-r--r--src/libcharon/tests/Makefile.am21
-rw-r--r--src/libcharon/tests/Makefile.in874
-rw-r--r--src/libcharon/tests/libcharon_tests.c56
-rw-r--r--src/libcharon/tests/libcharon_tests.h16
-rw-r--r--src/libcharon/tests/suites/test_mem_pool.c230
271 files changed, 16192 insertions, 2409 deletions
diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk
index 4212ee87a..5eef6fdc6 100644
--- a/src/libcharon/Android.mk
+++ b/src/libcharon/Android.mk
@@ -3,6 +3,10 @@ include $(CLEAR_VARS)
# copy-n-paste from Makefile.am
libcharon_la_SOURCES := \
+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 \
@@ -62,6 +66,7 @@ processing/jobs/start_action_job.c processing/jobs/start_action_job.h \
processing/jobs/roam_job.c processing/jobs/roam_job.h \
processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
+processing/jobs/initiate_tasks_job.c processing/jobs/initiate_tasks_job.h \
sa/eap/eap_method.c sa/eap/eap_method.h sa/eap/eap_inner_method.h \
sa/eap/eap_manager.c sa/eap/eap_manager.h \
sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
@@ -72,6 +77,7 @@ sa/ike_sa.c sa/ike_sa.h \
sa/ike_sa_id.c sa/ike_sa_id.h \
sa/keymat.h sa/keymat.c \
sa/ike_sa_manager.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 \
@@ -97,6 +103,7 @@ sa/ikev2/tasks/ike_natd.c sa/ikev2/tasks/ike_natd.h \
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_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h
@@ -238,4 +245,3 @@ LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES += libstrongswan libhydra
include $(BUILD_SHARED_LIBRARY)
-
diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am
index e98f5e137..cd81a5eee 100644
--- a/src/libcharon/Makefile.am
+++ b/src/libcharon/Makefile.am
@@ -1,6 +1,10 @@
ipseclib_LTLIBRARIES = libcharon.la
libcharon_la_SOURCES = \
+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 \
@@ -60,6 +64,7 @@ processing/jobs/start_action_job.c processing/jobs/start_action_job.h \
processing/jobs/roam_job.c processing/jobs/roam_job.h \
processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
+processing/jobs/initiate_tasks_job.c processing/jobs/initiate_tasks_job.h \
sa/eap/eap_method.c sa/eap/eap_method.h sa/eap/eap_inner_method.h \
sa/eap/eap_manager.c sa/eap/eap_manager.h \
sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
@@ -70,6 +75,7 @@ sa/ike_sa.c sa/ike_sa.h \
sa/ike_sa_id.c sa/ike_sa_id.h \
sa/keymat.h sa/keymat.c \
sa/ike_sa_manager.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 \
@@ -96,6 +102,7 @@ sa/ikev2/tasks/ike_natd.c sa/ikev2/tasks/ike_natd.h \
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_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h
endif
@@ -203,6 +210,20 @@ if MONOLITHIC
endif
endif
+if USE_CONNMARK
+ SUBDIRS += plugins/connmark
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/connmark/libstrongswan-connmark.la
+endif
+endif
+
+if USE_FORECAST
+ SUBDIRS += plugins/forecast
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/forecast/libstrongswan-forecast.la
+endif
+endif
+
if USE_FARP
SUBDIRS += plugins/farp
if MONOLITHIC
@@ -595,13 +616,6 @@ if MONOLITHIC
endif
endif
-if USE_UNIT_TESTS
- SUBDIRS += plugins/unit_tester
-if MONOLITHIC
- libcharon_la_LIBADD += plugins/unit_tester/libstrongswan-unit-tester.la
-endif
-endif
-
if USE_XAUTH_GENERIC
SUBDIRS += plugins/xauth_generic
if MONOLITHIC
@@ -629,3 +643,29 @@ if MONOLITHIC
libcharon_la_LIBADD += plugins/xauth_noauth/libstrongswan-xauth-noauth.la
endif
endif
+
+if USE_RESOLVE
+ SUBDIRS += plugins/resolve
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/resolve/libstrongswan-resolve.la
+endif
+endif
+
+if USE_ATTR
+ SUBDIRS += plugins/attr
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/attr/libstrongswan-attr.la
+endif
+endif
+
+if USE_ATTR_SQL
+ SUBDIRS += plugins/attr_sql
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/attr_sql/libstrongswan-attr-sql.la
+endif
+endif
+
+if MONOLITHIC
+ SUBDIRS += .
+endif
+SUBDIRS += tests
diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in
index 4d89794b5..3d425e0b4 100644
--- a/src/libcharon/Makefile.in
+++ b/src/libcharon/Makefile.in
@@ -98,6 +98,7 @@ host_triplet = @host@
@USE_IKEV2_TRUE@sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \
@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_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
@@ -146,124 +147,132 @@ host_triplet = @host@
@MONOLITHIC_TRUE@@USE_SOCKET_DYNAMIC_TRUE@am__append_11 = plugins/socket_dynamic/libstrongswan-socket-dynamic.la
@USE_SOCKET_WIN_TRUE@am__append_12 = plugins/socket_win
@MONOLITHIC_TRUE@@USE_SOCKET_WIN_TRUE@am__append_13 = plugins/socket_win/libstrongswan-socket-win.la
-@USE_FARP_TRUE@am__append_14 = plugins/farp
-@MONOLITHIC_TRUE@@USE_FARP_TRUE@am__append_15 = plugins/farp/libstrongswan-farp.la
-@USE_STROKE_TRUE@am__append_16 = plugins/stroke
-@MONOLITHIC_TRUE@@USE_STROKE_TRUE@am__append_17 = plugins/stroke/libstrongswan-stroke.la
-@USE_VICI_TRUE@am__append_18 = plugins/vici
-@MONOLITHIC_TRUE@@USE_VICI_TRUE@am__append_19 = plugins/vici/libstrongswan-vici.la
-@USE_SMP_TRUE@am__append_20 = plugins/smp
-@MONOLITHIC_TRUE@@USE_SMP_TRUE@am__append_21 = plugins/smp/libstrongswan-smp.la
-@USE_SQL_TRUE@am__append_22 = plugins/sql
-@MONOLITHIC_TRUE@@USE_SQL_TRUE@am__append_23 = plugins/sql/libstrongswan-sql.la
-@USE_DNSCERT_TRUE@am__append_24 = plugins/dnscert
-@MONOLITHIC_TRUE@@USE_DNSCERT_TRUE@am__append_25 = plugins/dnscert/libstrongswan-dnscert.la
-@USE_IPSECKEY_TRUE@am__append_26 = plugins/ipseckey
-@MONOLITHIC_TRUE@@USE_IPSECKEY_TRUE@am__append_27 = plugins/ipseckey/libstrongswan-ipseckey.la
-@USE_UPDOWN_TRUE@am__append_28 = plugins/updown
-@MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_29 = plugins/updown/libstrongswan-updown.la
-@USE_EXT_AUTH_TRUE@am__append_30 = plugins/ext_auth
-@MONOLITHIC_TRUE@@USE_EXT_AUTH_TRUE@am__append_31 = plugins/ext_auth/libstrongswan-ext-auth.la
-@USE_EAP_IDENTITY_TRUE@am__append_32 = plugins/eap_identity
-@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_33 = plugins/eap_identity/libstrongswan-eap-identity.la
-@USE_EAP_SIM_TRUE@am__append_34 = plugins/eap_sim
-@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_35 = plugins/eap_sim/libstrongswan-eap-sim.la
-@USE_EAP_SIM_FILE_TRUE@am__append_36 = plugins/eap_sim_file
-@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_37 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la
-@USE_EAP_SIM_PCSC_TRUE@am__append_38 = plugins/eap_sim_pcsc
-@MONOLITHIC_TRUE@@USE_EAP_SIM_PCSC_TRUE@am__append_39 = plugins/eap_sim_pcsc/libstrongswan-eap-sim-pcsc.la
-@USE_EAP_SIMAKA_SQL_TRUE@am__append_40 = plugins/eap_simaka_sql
-@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_41 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la
-@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_42 = plugins/eap_simaka_pseudonym
-@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_43 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la
-@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_44 = plugins/eap_simaka_reauth
-@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_45 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la
-@USE_EAP_AKA_TRUE@am__append_46 = plugins/eap_aka
-@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_47 = plugins/eap_aka/libstrongswan-eap-aka.la
-@USE_EAP_AKA_3GPP2_TRUE@am__append_48 = plugins/eap_aka_3gpp2
-@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_49 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
-@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_50 = $(top_builddir)/src/libsimaka/libsimaka.la
-@USE_EAP_MD5_TRUE@am__append_51 = plugins/eap_md5
-@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_52 = plugins/eap_md5/libstrongswan-eap-md5.la
-@USE_EAP_GTC_TRUE@am__append_53 = plugins/eap_gtc
-@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_54 = plugins/eap_gtc/libstrongswan-eap-gtc.la
-@USE_EAP_MSCHAPV2_TRUE@am__append_55 = plugins/eap_mschapv2
-@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_56 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
-@USE_EAP_DYNAMIC_TRUE@am__append_57 = plugins/eap_dynamic
-@MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE@am__append_58 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la
-@USE_EAP_RADIUS_TRUE@am__append_59 = plugins/eap_radius
-@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_60 = plugins/eap_radius/libstrongswan-eap-radius.la
-@USE_EAP_TLS_TRUE@am__append_61 = plugins/eap_tls
-@MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE@am__append_62 = plugins/eap_tls/libstrongswan-eap-tls.la
-@USE_EAP_TTLS_TRUE@am__append_63 = plugins/eap_ttls
-@MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE@am__append_64 = plugins/eap_ttls/libstrongswan-eap-ttls.la
-@USE_EAP_PEAP_TRUE@am__append_65 = plugins/eap_peap
-@MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE@am__append_66 = plugins/eap_peap/libstrongswan-eap-peap.la
-@USE_EAP_TNC_TRUE@am__append_67 = plugins/eap_tnc
-@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_68 = plugins/eap_tnc/libstrongswan-eap-tnc.la
-@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_69 = $(top_builddir)/src/libtls/libtls.la
-@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@am__append_70 = $(top_builddir)/src/libradius/libradius.la
-@USE_TNC_IFMAP_TRUE@am__append_71 = plugins/tnc_ifmap
-@MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE@am__append_72 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
-@USE_TNC_PDP_TRUE@am__append_73 = plugins/tnc_pdp
-@MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE@am__append_74 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la
-@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@am__append_75 = $(top_builddir)/src/libtnccs/libtnccs.la
-@USE_MEDSRV_TRUE@am__append_76 = plugins/medsrv
-@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_77 = plugins/medsrv/libstrongswan-medsrv.la
-@USE_MEDCLI_TRUE@am__append_78 = plugins/medcli
-@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_79 = plugins/medcli/libstrongswan-medcli.la
-@USE_DHCP_TRUE@am__append_80 = plugins/dhcp
-@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_81 = plugins/dhcp/libstrongswan-dhcp.la
-@USE_OSX_ATTR_TRUE@am__append_82 = plugins/osx_attr
-@MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE@am__append_83 = plugins/osx_attr/libstrongswan-osx-attr.la
-@USE_ANDROID_DNS_TRUE@am__append_84 = plugins/android_dns
-@MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE@am__append_85 = plugins/android_dns/libstrongswan-android-dns.la
-@USE_ANDROID_LOG_TRUE@am__append_86 = plugins/android_log
-@MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE@am__append_87 = plugins/android_log/libstrongswan-android-log.la
-@USE_MAEMO_TRUE@am__append_88 = plugins/maemo
-@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_89 = plugins/maemo/libstrongswan-maemo.la
-@USE_HA_TRUE@am__append_90 = plugins/ha
-@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_91 = plugins/ha/libstrongswan-ha.la
-@USE_KERNEL_LIBIPSEC_TRUE@am__append_92 = plugins/kernel_libipsec
-@MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE@am__append_93 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la
-@USE_KERNEL_WFP_TRUE@am__append_94 = plugins/kernel_wfp
-@MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE@am__append_95 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la
-@USE_KERNEL_IPH_TRUE@am__append_96 = plugins/kernel_iph
-@MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE@am__append_97 = plugins/kernel_iph/libstrongswan-kernel-iph.la
-@USE_WHITELIST_TRUE@am__append_98 = plugins/whitelist
-@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_99 = plugins/whitelist/libstrongswan-whitelist.la
-@USE_LOOKIP_TRUE@am__append_100 = plugins/lookip
-@MONOLITHIC_TRUE@@USE_LOOKIP_TRUE@am__append_101 = plugins/lookip/libstrongswan-lookip.la
-@USE_ERROR_NOTIFY_TRUE@am__append_102 = plugins/error_notify
-@MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE@am__append_103 = plugins/error_notify/libstrongswan-error-notify.la
-@USE_CERTEXPIRE_TRUE@am__append_104 = plugins/certexpire
-@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_105 = plugins/certexpire/libstrongswan-certexpire.la
-@USE_SYSTIME_FIX_TRUE@am__append_106 = plugins/systime_fix
-@MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE@am__append_107 = plugins/systime_fix/libstrongswan-systime-fix.la
-@USE_LED_TRUE@am__append_108 = plugins/led
-@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_109 = plugins/led/libstrongswan-led.la
-@USE_DUPLICHECK_TRUE@am__append_110 = plugins/duplicheck
-@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_111 = plugins/duplicheck/libstrongswan-duplicheck.la
-@USE_COUPLING_TRUE@am__append_112 = plugins/coupling
-@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_113 = plugins/coupling/libstrongswan-coupling.la
-@USE_RADATTR_TRUE@am__append_114 = plugins/radattr
-@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_115 = plugins/radattr/libstrongswan-radattr.la
-@USE_UCI_TRUE@am__append_116 = plugins/uci
-@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_117 = plugins/uci/libstrongswan-uci.la
-@USE_ADDRBLOCK_TRUE@am__append_118 = plugins/addrblock
-@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_119 = plugins/addrblock/libstrongswan-addrblock.la
-@USE_UNITY_TRUE@am__append_120 = plugins/unity
-@MONOLITHIC_TRUE@@USE_UNITY_TRUE@am__append_121 = plugins/unity/libstrongswan-unity.la
-@USE_UNIT_TESTS_TRUE@am__append_122 = plugins/unit_tester
-@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_123 = plugins/unit_tester/libstrongswan-unit-tester.la
-@USE_XAUTH_GENERIC_TRUE@am__append_124 = plugins/xauth_generic
-@MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE@am__append_125 = plugins/xauth_generic/libstrongswan-xauth-generic.la
-@USE_XAUTH_EAP_TRUE@am__append_126 = plugins/xauth_eap
-@MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE@am__append_127 = plugins/xauth_eap/libstrongswan-xauth-eap.la
-@USE_XAUTH_PAM_TRUE@am__append_128 = plugins/xauth_pam
-@MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE@am__append_129 = plugins/xauth_pam/libstrongswan-xauth-pam.la
-@USE_XAUTH_NOAUTH_TRUE@am__append_130 = plugins/xauth_noauth
-@MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE@am__append_131 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la
+@USE_CONNMARK_TRUE@am__append_14 = plugins/connmark
+@MONOLITHIC_TRUE@@USE_CONNMARK_TRUE@am__append_15 = plugins/connmark/libstrongswan-connmark.la
+@USE_FORECAST_TRUE@am__append_16 = plugins/forecast
+@MONOLITHIC_TRUE@@USE_FORECAST_TRUE@am__append_17 = plugins/forecast/libstrongswan-forecast.la
+@USE_FARP_TRUE@am__append_18 = plugins/farp
+@MONOLITHIC_TRUE@@USE_FARP_TRUE@am__append_19 = plugins/farp/libstrongswan-farp.la
+@USE_STROKE_TRUE@am__append_20 = plugins/stroke
+@MONOLITHIC_TRUE@@USE_STROKE_TRUE@am__append_21 = plugins/stroke/libstrongswan-stroke.la
+@USE_VICI_TRUE@am__append_22 = plugins/vici
+@MONOLITHIC_TRUE@@USE_VICI_TRUE@am__append_23 = plugins/vici/libstrongswan-vici.la
+@USE_SMP_TRUE@am__append_24 = plugins/smp
+@MONOLITHIC_TRUE@@USE_SMP_TRUE@am__append_25 = plugins/smp/libstrongswan-smp.la
+@USE_SQL_TRUE@am__append_26 = plugins/sql
+@MONOLITHIC_TRUE@@USE_SQL_TRUE@am__append_27 = plugins/sql/libstrongswan-sql.la
+@USE_DNSCERT_TRUE@am__append_28 = plugins/dnscert
+@MONOLITHIC_TRUE@@USE_DNSCERT_TRUE@am__append_29 = plugins/dnscert/libstrongswan-dnscert.la
+@USE_IPSECKEY_TRUE@am__append_30 = plugins/ipseckey
+@MONOLITHIC_TRUE@@USE_IPSECKEY_TRUE@am__append_31 = plugins/ipseckey/libstrongswan-ipseckey.la
+@USE_UPDOWN_TRUE@am__append_32 = plugins/updown
+@MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_33 = plugins/updown/libstrongswan-updown.la
+@USE_EXT_AUTH_TRUE@am__append_34 = plugins/ext_auth
+@MONOLITHIC_TRUE@@USE_EXT_AUTH_TRUE@am__append_35 = plugins/ext_auth/libstrongswan-ext-auth.la
+@USE_EAP_IDENTITY_TRUE@am__append_36 = plugins/eap_identity
+@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_37 = plugins/eap_identity/libstrongswan-eap-identity.la
+@USE_EAP_SIM_TRUE@am__append_38 = plugins/eap_sim
+@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_39 = plugins/eap_sim/libstrongswan-eap-sim.la
+@USE_EAP_SIM_FILE_TRUE@am__append_40 = plugins/eap_sim_file
+@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_41 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la
+@USE_EAP_SIM_PCSC_TRUE@am__append_42 = plugins/eap_sim_pcsc
+@MONOLITHIC_TRUE@@USE_EAP_SIM_PCSC_TRUE@am__append_43 = plugins/eap_sim_pcsc/libstrongswan-eap-sim-pcsc.la
+@USE_EAP_SIMAKA_SQL_TRUE@am__append_44 = plugins/eap_simaka_sql
+@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_45 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la
+@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_46 = plugins/eap_simaka_pseudonym
+@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_47 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la
+@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_48 = plugins/eap_simaka_reauth
+@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_49 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la
+@USE_EAP_AKA_TRUE@am__append_50 = plugins/eap_aka
+@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_51 = plugins/eap_aka/libstrongswan-eap-aka.la
+@USE_EAP_AKA_3GPP2_TRUE@am__append_52 = plugins/eap_aka_3gpp2
+@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_53 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
+@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_54 = $(top_builddir)/src/libsimaka/libsimaka.la
+@USE_EAP_MD5_TRUE@am__append_55 = plugins/eap_md5
+@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_56 = plugins/eap_md5/libstrongswan-eap-md5.la
+@USE_EAP_GTC_TRUE@am__append_57 = plugins/eap_gtc
+@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_58 = plugins/eap_gtc/libstrongswan-eap-gtc.la
+@USE_EAP_MSCHAPV2_TRUE@am__append_59 = plugins/eap_mschapv2
+@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_60 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
+@USE_EAP_DYNAMIC_TRUE@am__append_61 = plugins/eap_dynamic
+@MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE@am__append_62 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la
+@USE_EAP_RADIUS_TRUE@am__append_63 = plugins/eap_radius
+@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_64 = plugins/eap_radius/libstrongswan-eap-radius.la
+@USE_EAP_TLS_TRUE@am__append_65 = plugins/eap_tls
+@MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE@am__append_66 = plugins/eap_tls/libstrongswan-eap-tls.la
+@USE_EAP_TTLS_TRUE@am__append_67 = plugins/eap_ttls
+@MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE@am__append_68 = plugins/eap_ttls/libstrongswan-eap-ttls.la
+@USE_EAP_PEAP_TRUE@am__append_69 = plugins/eap_peap
+@MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE@am__append_70 = plugins/eap_peap/libstrongswan-eap-peap.la
+@USE_EAP_TNC_TRUE@am__append_71 = plugins/eap_tnc
+@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_72 = plugins/eap_tnc/libstrongswan-eap-tnc.la
+@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_73 = $(top_builddir)/src/libtls/libtls.la
+@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@am__append_74 = $(top_builddir)/src/libradius/libradius.la
+@USE_TNC_IFMAP_TRUE@am__append_75 = plugins/tnc_ifmap
+@MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE@am__append_76 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
+@USE_TNC_PDP_TRUE@am__append_77 = plugins/tnc_pdp
+@MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE@am__append_78 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la
+@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@am__append_79 = $(top_builddir)/src/libtnccs/libtnccs.la
+@USE_MEDSRV_TRUE@am__append_80 = plugins/medsrv
+@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_81 = plugins/medsrv/libstrongswan-medsrv.la
+@USE_MEDCLI_TRUE@am__append_82 = plugins/medcli
+@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_83 = plugins/medcli/libstrongswan-medcli.la
+@USE_DHCP_TRUE@am__append_84 = plugins/dhcp
+@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
subdir = src/libcharon
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
@@ -325,12 +334,12 @@ libcharon_la_DEPENDENCIES = \
$(am__append_29) $(am__append_31) $(am__append_33) \
$(am__append_35) $(am__append_37) $(am__append_39) \
$(am__append_41) $(am__append_43) $(am__append_45) \
- $(am__append_47) $(am__append_49) $(am__append_50) \
- $(am__append_52) $(am__append_54) $(am__append_56) \
+ $(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_69) $(am__append_70) $(am__append_72) \
- $(am__append_74) $(am__append_75) $(am__append_77) \
+ $(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) \
@@ -339,8 +348,14 @@ libcharon_la_DEPENDENCIES = \
$(am__append_109) $(am__append_111) $(am__append_113) \
$(am__append_115) $(am__append_117) $(am__append_119) \
$(am__append_121) $(am__append_123) $(am__append_125) \
- $(am__append_127) $(am__append_129) $(am__append_131)
-am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
+ $(am__append_127) $(am__append_129) $(am__append_131) \
+ $(am__append_133) $(am__append_135) $(am__append_137) \
+ $(am__append_139)
+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 \
@@ -421,7 +436,9 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
processing/jobs/roam_job.h processing/jobs/update_sa_job.c \
processing/jobs/update_sa_job.h \
processing/jobs/inactivity_job.c \
- processing/jobs/inactivity_job.h sa/eap/eap_method.c \
+ processing/jobs/inactivity_job.h \
+ processing/jobs/initiate_tasks_job.c \
+ processing/jobs/initiate_tasks_job.h sa/eap/eap_method.c \
sa/eap/eap_method.h sa/eap/eap_inner_method.h \
sa/eap/eap_manager.c sa/eap/eap_manager.h \
sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
@@ -429,7 +446,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
sa/authenticator.c sa/authenticator.h sa/child_sa.c \
sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
sa/ike_sa_id.h sa/keymat.h sa/keymat.c sa/ike_sa_manager.c \
- sa/ike_sa_manager.h sa/task_manager.h sa/task_manager.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/ikev2/keymat_v2.h sa/ikev2/task_manager_v2.c \
@@ -454,6 +472,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
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_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 \
@@ -514,6 +534,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
@USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_mobike.lo \
@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_auth_lifetime.lo \
@USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_vendor.lo
@USE_IKEV1_TRUE@am__objects_2 = sa/ikev1/keymat_v1.lo \
@@ -543,7 +564,9 @@ am__dirstamp = $(am__leading_dot)dirstamp
@USE_ME_TRUE@ sa/ikev2/connect_manager.lo \
@USE_ME_TRUE@ sa/ikev2/mediation_manager.lo \
@USE_ME_TRUE@ sa/ikev2/tasks/ike_me.lo
-am_libcharon_la_OBJECTS = bus/bus.lo bus/listeners/file_logger.lo \
+am_libcharon_la_OBJECTS = attributes/attributes.lo \
+ attributes/attribute_manager.lo attributes/mem_pool.lo \
+ bus/bus.lo bus/listeners/file_logger.lo \
config/backend_manager.lo config/child_cfg.lo \
config/ike_cfg.lo config/peer_cfg.lo config/proposal.lo \
control/controller.lo daemon.lo encoding/generator.lo \
@@ -587,13 +610,14 @@ am_libcharon_la_OBJECTS = bus/bus.lo bus/listeners/file_logger.lo \
processing/jobs/send_keepalive_job.lo \
processing/jobs/start_action_job.lo \
processing/jobs/roam_job.lo processing/jobs/update_sa_job.lo \
- processing/jobs/inactivity_job.lo sa/eap/eap_method.lo \
+ processing/jobs/inactivity_job.lo \
+ processing/jobs/initiate_tasks_job.lo sa/eap/eap_method.lo \
sa/eap/eap_manager.lo sa/xauth/xauth_method.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/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/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)
libcharon_la_OBJECTS = $(am_libcharon_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -676,11 +700,11 @@ am__define_uniq_tagged_files = \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \
- plugins/socket_dynamic plugins/socket_win plugins/farp \
- plugins/stroke plugins/vici plugins/smp plugins/sql \
- plugins/dnscert plugins/ipseckey plugins/updown \
- plugins/ext_auth plugins/eap_identity plugins/eap_sim \
- plugins/eap_sim_file plugins/eap_sim_pcsc \
+ plugins/socket_dynamic plugins/socket_win plugins/connmark \
+ plugins/forecast plugins/farp plugins/stroke plugins/vici \
+ plugins/smp plugins/sql plugins/dnscert plugins/ipseckey \
+ plugins/updown plugins/ext_auth plugins/eap_identity \
+ plugins/eap_sim plugins/eap_sim_file plugins/eap_sim_pcsc \
plugins/eap_simaka_sql plugins/eap_simaka_pseudonym \
plugins/eap_simaka_reauth plugins/eap_aka \
plugins/eap_aka_3gpp2 plugins/eap_md5 plugins/eap_gtc \
@@ -694,8 +718,9 @@ DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \
plugins/error_notify plugins/certexpire plugins/systime_fix \
plugins/led plugins/duplicheck plugins/coupling \
plugins/radattr plugins/uci plugins/addrblock plugins/unity \
- plugins/unit_tester plugins/xauth_generic plugins/xauth_eap \
- plugins/xauth_pam plugins/xauth_noauth
+ plugins/xauth_generic plugins/xauth_eap plugins/xauth_pam \
+ plugins/xauth_noauth plugins/resolve plugins/attr \
+ plugins/attr_sql tests
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -747,6 +772,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -807,10 +833,12 @@ 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@
@@ -884,6 +912,8 @@ 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@
@@ -943,16 +973,20 @@ urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
ipseclib_LTLIBRARIES = libcharon.la
-libcharon_la_SOURCES = 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 \
+libcharon_la_SOURCES = 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 \
encoding/payloads/auth_payload.h \
encoding/payloads/cert_payload.c \
encoding/payloads/cert_payload.h \
@@ -1023,7 +1057,9 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
processing/jobs/roam_job.h processing/jobs/update_sa_job.c \
processing/jobs/update_sa_job.h \
processing/jobs/inactivity_job.c \
- processing/jobs/inactivity_job.h sa/eap/eap_method.c \
+ processing/jobs/inactivity_job.h \
+ processing/jobs/initiate_tasks_job.c \
+ processing/jobs/initiate_tasks_job.h sa/eap/eap_method.c \
sa/eap/eap_method.h sa/eap/eap_inner_method.h \
sa/eap/eap_manager.c sa/eap/eap_manager.h \
sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
@@ -1031,7 +1067,8 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
sa/authenticator.c sa/authenticator.h sa/child_sa.c \
sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
sa/ike_sa_id.h sa/keymat.h sa/keymat.c sa/ike_sa_manager.c \
- sa/ike_sa_manager.h sa/task_manager.h sa/task_manager.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 $(am__append_1) \
$(am__append_2) $(am__append_3) $(am__append_5)
@@ -1057,12 +1094,12 @@ libcharon_la_LIBADD = \
$(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_50) $(am__append_52) $(am__append_54) \
+ $(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_69) $(am__append_70) \
- $(am__append_72) $(am__append_74) $(am__append_75) \
- $(am__append_77) $(am__append_79) $(am__append_81) \
+ $(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) \
@@ -1071,7 +1108,8 @@ libcharon_la_LIBADD = \
$(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_131) $(am__append_133) $(am__append_135) \
+ $(am__append_137) $(am__append_139)
EXTRA_DIST = Android.mk
@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_6) $(am__append_8) \
@MONOLITHIC_FALSE@ $(am__append_10) $(am__append_12) \
@@ -1084,13 +1122,13 @@ EXTRA_DIST = Android.mk
@MONOLITHIC_FALSE@ $(am__append_38) $(am__append_40) \
@MONOLITHIC_FALSE@ $(am__append_42) $(am__append_44) \
@MONOLITHIC_FALSE@ $(am__append_46) $(am__append_48) \
-@MONOLITHIC_FALSE@ $(am__append_51) $(am__append_53) \
+@MONOLITHIC_FALSE@ $(am__append_50) $(am__append_52) \
@MONOLITHIC_FALSE@ $(am__append_55) $(am__append_57) \
@MONOLITHIC_FALSE@ $(am__append_59) $(am__append_61) \
@MONOLITHIC_FALSE@ $(am__append_63) $(am__append_65) \
-@MONOLITHIC_FALSE@ $(am__append_67) $(am__append_71) \
-@MONOLITHIC_FALSE@ $(am__append_73) $(am__append_76) \
-@MONOLITHIC_FALSE@ $(am__append_78) $(am__append_80) \
+@MONOLITHIC_FALSE@ $(am__append_67) $(am__append_69) \
+@MONOLITHIC_FALSE@ $(am__append_71) $(am__append_75) \
+@MONOLITHIC_FALSE@ $(am__append_77) $(am__append_80) \
@MONOLITHIC_FALSE@ $(am__append_82) $(am__append_84) \
@MONOLITHIC_FALSE@ $(am__append_86) $(am__append_88) \
@MONOLITHIC_FALSE@ $(am__append_90) $(am__append_92) \
@@ -1103,7 +1141,9 @@ EXTRA_DIST = Android.mk
@MONOLITHIC_FALSE@ $(am__append_118) $(am__append_120) \
@MONOLITHIC_FALSE@ $(am__append_122) $(am__append_124) \
@MONOLITHIC_FALSE@ $(am__append_126) $(am__append_128) \
-@MONOLITHIC_FALSE@ $(am__append_130)
+@MONOLITHIC_FALSE@ $(am__append_130) $(am__append_132) \
+@MONOLITHIC_FALSE@ $(am__append_134) $(am__append_136) \
+@MONOLITHIC_FALSE@ $(am__append_138) tests
# build optional plugins
########################
@@ -1118,13 +1158,13 @@ EXTRA_DIST = Android.mk
@MONOLITHIC_TRUE@ $(am__append_38) $(am__append_40) \
@MONOLITHIC_TRUE@ $(am__append_42) $(am__append_44) \
@MONOLITHIC_TRUE@ $(am__append_46) $(am__append_48) \
-@MONOLITHIC_TRUE@ $(am__append_51) $(am__append_53) \
+@MONOLITHIC_TRUE@ $(am__append_50) $(am__append_52) \
@MONOLITHIC_TRUE@ $(am__append_55) $(am__append_57) \
@MONOLITHIC_TRUE@ $(am__append_59) $(am__append_61) \
@MONOLITHIC_TRUE@ $(am__append_63) $(am__append_65) \
-@MONOLITHIC_TRUE@ $(am__append_67) $(am__append_71) \
-@MONOLITHIC_TRUE@ $(am__append_73) $(am__append_76) \
-@MONOLITHIC_TRUE@ $(am__append_78) $(am__append_80) \
+@MONOLITHIC_TRUE@ $(am__append_67) $(am__append_69) \
+@MONOLITHIC_TRUE@ $(am__append_71) $(am__append_75) \
+@MONOLITHIC_TRUE@ $(am__append_77) $(am__append_80) \
@MONOLITHIC_TRUE@ $(am__append_82) $(am__append_84) \
@MONOLITHIC_TRUE@ $(am__append_86) $(am__append_88) \
@MONOLITHIC_TRUE@ $(am__append_90) $(am__append_92) \
@@ -1137,7 +1177,9 @@ EXTRA_DIST = Android.mk
@MONOLITHIC_TRUE@ $(am__append_118) $(am__append_120) \
@MONOLITHIC_TRUE@ $(am__append_122) $(am__append_124) \
@MONOLITHIC_TRUE@ $(am__append_126) $(am__append_128) \
-@MONOLITHIC_TRUE@ $(am__append_130)
+@MONOLITHIC_TRUE@ $(am__append_130) $(am__append_132) \
+@MONOLITHIC_TRUE@ $(am__append_134) $(am__append_136) \
+@MONOLITHIC_TRUE@ $(am__append_138) . tests
all: all-recursive
.SUFFIXES:
@@ -1207,6 +1249,18 @@ clean-ipseclibLTLIBRARIES:
echo rm -f $${locs}; \
rm -f $${locs}; \
}
+attributes/$(am__dirstamp):
+ @$(MKDIR_P) attributes
+ @: > attributes/$(am__dirstamp)
+attributes/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) attributes/$(DEPDIR)
+ @: > attributes/$(DEPDIR)/$(am__dirstamp)
+attributes/attributes.lo: attributes/$(am__dirstamp) \
+ attributes/$(DEPDIR)/$(am__dirstamp)
+attributes/attribute_manager.lo: attributes/$(am__dirstamp) \
+ attributes/$(DEPDIR)/$(am__dirstamp)
+attributes/mem_pool.lo: attributes/$(am__dirstamp) \
+ attributes/$(DEPDIR)/$(am__dirstamp)
bus/$(am__dirstamp):
@$(MKDIR_P) bus
@: > bus/$(am__dirstamp)
@@ -1389,6 +1443,9 @@ processing/jobs/update_sa_job.lo: processing/jobs/$(am__dirstamp) \
processing/jobs/$(DEPDIR)/$(am__dirstamp)
processing/jobs/inactivity_job.lo: processing/jobs/$(am__dirstamp) \
processing/jobs/$(DEPDIR)/$(am__dirstamp)
+processing/jobs/initiate_tasks_job.lo: \
+ processing/jobs/$(am__dirstamp) \
+ processing/jobs/$(DEPDIR)/$(am__dirstamp)
sa/eap/$(am__dirstamp):
@$(MKDIR_P) sa/eap
@: > sa/eap/$(am__dirstamp)
@@ -1421,6 +1478,8 @@ sa/ike_sa.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
sa/ike_sa_id.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
sa/keymat.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
sa/ike_sa_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
+sa/child_sa_manager.lo: sa/$(am__dirstamp) \
+ sa/$(DEPDIR)/$(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)
@@ -1484,6 +1543,8 @@ sa/ikev2/tasks/ike_rekey.lo: sa/ikev2/tasks/$(am__dirstamp) \
sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp)
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_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) \
@@ -1574,6 +1635,8 @@ libcharon.la: $(libcharon_la_OBJECTS) $(libcharon_la_DEPENDENCIES) $(EXTRA_libch
mostlyclean-compile:
-rm -f *.$(OBJEXT)
+ -rm -f attributes/*.$(OBJEXT)
+ -rm -f attributes/*.lo
-rm -f bus/*.$(OBJEXT)
-rm -f bus/*.lo
-rm -f bus/listeners/*.$(OBJEXT)
@@ -1615,6 +1678,9 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/daemon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/attribute_manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/attributes.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/mem_pool.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@bus/$(DEPDIR)/bus.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@bus/listeners/$(DEPDIR)/file_logger.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@bus/listeners/$(DEPDIR)/sys_logger.Plo@am__quote@
@@ -1665,6 +1731,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/dpd_timeout_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/inactivity_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/initiate_mediation_job.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/initiate_tasks_job.Plo@am__quote@
@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@
@@ -1679,6 +1746,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/update_sa_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/authenticator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/child_sa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/child_sa_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/ike_sa.Plo@am__quote@
@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@
@@ -1730,6 +1798,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_mobike.Plo@am__quote@
@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_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/xauth/$(DEPDIR)/xauth_manager.Plo@am__quote@
@@ -1764,6 +1833,7 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
+ -rm -rf attributes/.libs attributes/_libs
-rm -rf bus/.libs bus/_libs
-rm -rf bus/listeners/.libs bus/listeners/_libs
-rm -rf config/.libs config/_libs
@@ -1971,6 +2041,8 @@ 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 attributes/$(DEPDIR)/$(am__dirstamp)
+ -rm -f attributes/$(am__dirstamp)
-rm -f bus/$(DEPDIR)/$(am__dirstamp)
-rm -f bus/$(am__dirstamp)
-rm -f bus/listeners/$(DEPDIR)/$(am__dirstamp)
@@ -2017,7 +2089,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-recursive
- -rm -rf ./$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) attributes/$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -2063,7 +2135,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
- -rm -rf ./$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) attributes/$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/src/libcharon/attributes/attribute_handler.h b/src/libcharon/attributes/attribute_handler.h
new file mode 100644
index 000000000..3c14323a3
--- /dev/null
+++ b/src/libcharon/attributes/attribute_handler.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attribute_handler attribute_handler
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTE_HANDLER_H_
+#define ATTRIBUTE_HANDLER_H_
+
+typedef struct attribute_handler_t attribute_handler_t;
+
+#include <sa/ike_sa.h>
+#include <utils/chunk.h>
+#include <collections/linked_list.h>
+
+#include "attributes.h"
+
+/**
+ * Interface to handle configuration payload attributes.
+ */
+struct attribute_handler_t {
+
+ /**
+ * Handle a configuration attribute.
+ *
+ * After receiving a configuration attriubte, it is passed to each
+ * attribute handler until it is handled.
+ *
+ * @param ike_sa IKE_SA under which attribute is received
+ * @param type type of configuration attribute to handle
+ * @param data associated attribute data
+ * @return TRUE if attribute handled
+ */
+ bool (*handle)(attribute_handler_t *this, ike_sa_t *ike_sa,
+ configuration_attribute_type_t type, chunk_t data);
+
+ /**
+ * Release an attribute handled during handle().
+ *
+ * A handler that handle()d an attribute gets a call to release() when the
+ * connection gets closed. Depending on the implementation, this is required
+ * to remove the attribute.
+ *
+ * @param ike_sa IKE_SA which releases attribute
+ * @param type type of configuration attribute to release
+ * @param data associated attribute data
+ */
+ void (*release)(attribute_handler_t *this, ike_sa_t *ike_sa,
+ configuration_attribute_type_t type, chunk_t data);
+
+ /**
+ * Enumerate attributes to request from a server.
+ *
+ * @param ike_sa IKE_SA to request attributes for
+ * @param vips list of virtual IPs (host_t*) we are requesting
+ * @return enumerator (configuration_attribute_type_t, chunk_t)
+ */
+ enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this,
+ ike_sa_t *ike_sa, linked_list_t *vips);
+};
+
+#endif /** ATTRIBUTE_HANDLER_H_ @}*/
diff --git a/src/libcharon/attributes/attribute_manager.c b/src/libcharon/attributes/attribute_manager.c
new file mode 100644
index 000000000..2ab7ed118
--- /dev/null
+++ b/src/libcharon/attributes/attribute_manager.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "attribute_manager.h"
+
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_attribute_manager_t private_attribute_manager_t;
+
+/**
+ * private data of attribute_manager
+ */
+struct private_attribute_manager_t {
+
+ /**
+ * public functions
+ */
+ attribute_manager_t public;
+
+ /**
+ * list of registered providers
+ */
+ linked_list_t *providers;
+
+ /**
+ * list of registered handlers
+ */
+ linked_list_t *handlers;
+
+ /**
+ * rwlock provider list
+ */
+ rwlock_t *lock;
+};
+
+/**
+ * Data to pass to enumerator filters
+ */
+typedef struct {
+ /** attribute group pools */
+ linked_list_t *pools;
+ /** associated IKE_SA */
+ ike_sa_t *ike_sa;
+ /** requesting/assigned virtual IPs */
+ linked_list_t *vips;
+} enum_data_t;
+
+METHOD(attribute_manager_t, acquire_address, host_t*,
+ private_attribute_manager_t *this, linked_list_t *pools,
+ ike_sa_t *ike_sa, host_t *requested)
+{
+ enumerator_t *enumerator;
+ attribute_provider_t *current;
+ host_t *host = NULL;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->providers->create_enumerator(this->providers);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ host = current->acquire_address(current, pools, ike_sa, requested);
+ if (host)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
+ return host;
+}
+
+METHOD(attribute_manager_t, release_address, bool,
+ private_attribute_manager_t *this, linked_list_t *pools, host_t *address,
+ ike_sa_t *ike_sa)
+{
+ enumerator_t *enumerator;
+ attribute_provider_t *current;
+ bool found = FALSE;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->providers->create_enumerator(this->providers);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (current->release_address(current, pools, address, ike_sa))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
+ return found;
+}
+
+/**
+ * inner enumerator constructor for responder attributes
+ */
+static enumerator_t *responder_enum_create(attribute_provider_t *provider,
+ enum_data_t *data)
+{
+ return provider->create_attribute_enumerator(provider, data->pools,
+ data->ike_sa, data->vips);
+}
+
+METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*,
+ private_attribute_manager_t *this, linked_list_t *pools,
+ ike_sa_t *ike_sa, linked_list_t *vips)
+{
+ enum_data_t *data;
+
+ INIT(data,
+ .pools = pools,
+ .ike_sa = ike_sa,
+ .vips = vips,
+ );
+ this->lock->read_lock(this->lock);
+ return enumerator_create_cleaner(
+ enumerator_create_nested(
+ this->providers->create_enumerator(this->providers),
+ (void*)responder_enum_create, data, free),
+ (void*)this->lock->unlock, this->lock);
+}
+
+METHOD(attribute_manager_t, add_provider, void,
+ private_attribute_manager_t *this, attribute_provider_t *provider)
+{
+ this->lock->write_lock(this->lock);
+ this->providers->insert_last(this->providers, provider);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(attribute_manager_t, remove_provider, void,
+ private_attribute_manager_t *this, attribute_provider_t *provider)
+{
+ this->lock->write_lock(this->lock);
+ this->providers->remove(this->providers, provider, NULL);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(attribute_manager_t, handle, attribute_handler_t*,
+ private_attribute_manager_t *this, ike_sa_t *ike_sa,
+ attribute_handler_t *handler, configuration_attribute_type_t type,
+ chunk_t data)
+{
+ enumerator_t *enumerator;
+ attribute_handler_t *current, *handled = NULL;
+
+ this->lock->read_lock(this->lock);
+
+ /* try to find the passed handler */
+ enumerator = this->handlers->create_enumerator(this->handlers);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (current == handler && current->handle(current, ike_sa, type, data))
+ {
+ handled = current;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!handled)
+ { /* handler requesting this attribute not found, try any other */
+ enumerator = this->handlers->create_enumerator(this->handlers);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (current->handle(current, ike_sa, type, data))
+ {
+ handled = current;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ this->lock->unlock(this->lock);
+
+ if (!handled)
+ {
+ DBG1(DBG_CFG, "handling %N attribute failed",
+ configuration_attribute_type_names, type);
+ }
+ return handled;
+}
+
+METHOD(attribute_manager_t, release, void,
+ private_attribute_manager_t *this, attribute_handler_t *handler,
+ ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data)
+{
+ enumerator_t *enumerator;
+ attribute_handler_t *current;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->handlers->create_enumerator(this->handlers);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (current == handler)
+ {
+ current->release(current, ike_sa, type, data);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+}
+
+/**
+ * Enumerator implementation to enumerate nested initiator attributes
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** back ref */
+ private_attribute_manager_t *this;
+ /** currently processing handler */
+ attribute_handler_t *handler;
+ /** outer enumerator over handlers */
+ enumerator_t *outer;
+ /** inner enumerator over current handlers attributes */
+ enumerator_t *inner;
+ /** IKE_SA to request attributes for */
+ ike_sa_t *ike_sa;
+ /** virtual IPs we are requesting along with attriubutes */
+ linked_list_t *vips;
+} initiator_enumerator_t;
+
+/**
+ * Enumerator implementation for initiator attributes
+ */
+static bool initiator_enumerate(initiator_enumerator_t *this,
+ attribute_handler_t **handler,
+ configuration_attribute_type_t *type,
+ chunk_t *value)
+{
+ /* enumerate inner attributes using outer handler enumerator */
+ while (!this->inner || !this->inner->enumerate(this->inner, type, value))
+ {
+ if (!this->outer->enumerate(this->outer, &this->handler))
+ {
+ return FALSE;
+ }
+ DESTROY_IF(this->inner);
+ this->inner = this->handler->create_attribute_enumerator(this->handler,
+ this->ike_sa, this->vips);
+ }
+ /* inject the handler as additional attribute */
+ *handler = this->handler;
+ return TRUE;
+}
+
+/**
+ * Cleanup function of initiator attribute enumerator
+ */
+static void initiator_destroy(initiator_enumerator_t *this)
+{
+ this->this->lock->unlock(this->this->lock);
+ this->outer->destroy(this->outer);
+ DESTROY_IF(this->inner);
+ free(this);
+}
+
+METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*,
+ private_attribute_manager_t *this, ike_sa_t *ike_sa, linked_list_t *vips)
+{
+ initiator_enumerator_t *enumerator;
+
+ this->lock->read_lock(this->lock);
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)initiator_enumerate,
+ .destroy = (void*)initiator_destroy,
+ },
+ .this = this,
+ .ike_sa = ike_sa,
+ .vips = vips,
+ .outer = this->handlers->create_enumerator(this->handlers),
+ );
+ return &enumerator->public;
+}
+
+METHOD(attribute_manager_t, add_handler, void,
+ private_attribute_manager_t *this, attribute_handler_t *handler)
+{
+ this->lock->write_lock(this->lock);
+ this->handlers->insert_last(this->handlers, handler);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(attribute_manager_t, remove_handler, void,
+ private_attribute_manager_t *this, attribute_handler_t *handler)
+{
+ this->lock->write_lock(this->lock);
+ this->handlers->remove(this->handlers, handler, NULL);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(attribute_manager_t, destroy, void,
+ private_attribute_manager_t *this)
+{
+ this->providers->destroy(this->providers);
+ this->handlers->destroy(this->handlers);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+attribute_manager_t *attribute_manager_create()
+{
+ private_attribute_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .acquire_address = _acquire_address,
+ .release_address = _release_address,
+ .create_responder_enumerator = _create_responder_enumerator,
+ .add_provider = _add_provider,
+ .remove_provider = _remove_provider,
+ .handle = _handle,
+ .release = _release,
+ .create_initiator_enumerator = _create_initiator_enumerator,
+ .add_handler = _add_handler,
+ .remove_handler = _remove_handler,
+ .destroy = _destroy,
+ },
+ .providers = linked_list_create(),
+ .handlers = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/attributes/attribute_manager.h b/src/libcharon/attributes/attribute_manager.h
new file mode 100644
index 000000000..6db664968
--- /dev/null
+++ b/src/libcharon/attributes/attribute_manager.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008-2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attribute_manager attribute_manager
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTE_MANAGER_H_
+#define ATTRIBUTE_MANAGER_H_
+
+#include "attribute_provider.h"
+#include "attribute_handler.h"
+
+#include <sa/ike_sa.h>
+
+typedef struct attribute_manager_t attribute_manager_t;
+
+/**
+ * The attribute manager hands out attributes or handles them.
+ *
+ * The attribute manager manages both, attribute providers and attribute
+ * handlers. Attribute providers are responsible to hand out attributes if
+ * a connecting peer requests them. Handlers handle such attributes if they
+ * are received on the requesting peer.
+ */
+struct attribute_manager_t {
+
+ /**
+ * Acquire a virtual IP address to assign to a peer.
+ *
+ * @param pools list of pool names (char*) to acquire from
+ * @param ike_sa associated IKE_SA for which an address is requested
+ * @param requested IP in configuration request
+ * @return allocated address, NULL to serve none
+ */
+ host_t* (*acquire_address)(attribute_manager_t *this,
+ linked_list_t *pool, ike_sa_t *ike_sa,
+ host_t *requested);
+
+ /**
+ * Release a previously acquired address.
+ *
+ * @param pools list of pool names (char*) to release to
+ * @param address address to release
+ * @param ike_sa associated IKE_SA for which an address is released
+ * @return TRUE if address released to pool
+ */
+ bool (*release_address)(attribute_manager_t *this,
+ linked_list_t *pools, host_t *address,
+ ike_sa_t *ike_sa);
+
+ /**
+ * Create an enumerator over attributes to hand out to a peer.
+ *
+ * @param pool list of pools names (char*) to query attributes from
+ * @param ike_sa associated IKE_SA for which attributes are requested
+ * @param vip list of virtual IPs (host_t*) to assign to peer
+ * @return enumerator (configuration_attribute_type_t, chunk_t)
+ */
+ enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this,
+ linked_list_t *pool, ike_sa_t *ike_sa,
+ linked_list_t *vips);
+
+ /**
+ * Register an attribute provider to the manager.
+ *
+ * @param provider attribute provider to register
+ */
+ void (*add_provider)(attribute_manager_t *this,
+ attribute_provider_t *provider);
+ /**
+ * Unregister an attribute provider from the manager.
+ *
+ * @param provider attribute provider to unregister
+ */
+ void (*remove_provider)(attribute_manager_t *this,
+ attribute_provider_t *provider);
+
+ /**
+ * Handle a configuration attribute by passing them to the handlers.
+ *
+ * @param ike_sa associated IKE_SA to handle an attribute for
+ * @param handler handler we requested the attribute for, if any
+ * @param type type of configuration attribute
+ * @param data associated attribute data
+ * @return handler which handled this attribute, NULL if none
+ */
+ attribute_handler_t* (*handle)(attribute_manager_t *this,
+ ike_sa_t *ike_sa, attribute_handler_t *handler,
+ configuration_attribute_type_t type, chunk_t data);
+
+ /**
+ * Release an attribute previously handle()d by a handler.
+ *
+ * @param ike_sa associated IKE_SA to release an attribute for
+ * @param server server from which the attribute was received
+ * @param type type of attribute to release
+ * @param data associated attribute data
+ */
+ void (*release)(attribute_manager_t *this, attribute_handler_t *handler,
+ ike_sa_t *ike_sa, configuration_attribute_type_t type,
+ chunk_t data);
+
+ /**
+ * Create an enumerator over attributes to request from server.
+ *
+ * @param ike_sa associated IKE_SA to request attributes for
+ * @param vip list of virtual IPs (host_t*) going to request
+ * @return enumerator (attribute_handler_t, ca_type_t, chunk_t)
+ */
+ enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this,
+ ike_sa_t *ike_sa, linked_list_t *vips);
+
+ /**
+ * Register an attribute handler to the manager.
+ *
+ * @param handler attribute handler to register
+ */
+ void (*add_handler)(attribute_manager_t *this,
+ attribute_handler_t *handler);
+
+ /**
+ * Unregister an attribute handler from the manager.
+ *
+ * @param handler attribute handler to unregister
+ */
+ void (*remove_handler)(attribute_manager_t *this,
+ attribute_handler_t *handler);
+
+ /**
+ * Destroy a attribute_manager instance.
+ */
+ void (*destroy)(attribute_manager_t *this);
+};
+
+/**
+ * Create a attribute_manager instance.
+ */
+attribute_manager_t *attribute_manager_create();
+
+#endif /** ATTRIBUTE_MANAGER_H_ @}*/
diff --git a/src/libcharon/attributes/attribute_provider.h b/src/libcharon/attributes/attribute_provider.h
new file mode 100644
index 000000000..57453c2a0
--- /dev/null
+++ b/src/libcharon/attributes/attribute_provider.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attribute_provider attribute_provider
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTE_PROVIDER_H_
+#define ATTRIBUTE_PROVIDER_H_
+
+#include <sa/ike_sa.h>
+#include <networking/host.h>
+#include <collections/linked_list.h>
+
+typedef struct attribute_provider_t attribute_provider_t;
+
+/**
+ * Interface to provide attributes to peers through attribute manager.
+ */
+struct attribute_provider_t {
+
+ /**
+ * Acquire a virtual IP address to assign to a peer.
+ *
+ * @param pools list of pool names (char*) to acquire from
+ * @param ike_sa associated IKE_SA to assign address over
+ * @param requested IP in configuration request
+ * @return allocated address, NULL to serve none
+ */
+ host_t* (*acquire_address)(attribute_provider_t *this,
+ linked_list_t *pools, ike_sa_t *ike_sa,
+ host_t *requested);
+ /**
+ * Release a previously acquired address.
+ *
+ * @param pools list of pool names (char*) to release to
+ * @param address address to release
+ * @param ike_sa IKE_SA to release address for
+ * @return TRUE if the address has been released by the provider
+ */
+ bool (*release_address)(attribute_provider_t *this,
+ linked_list_t *pools, host_t *address,
+ ike_sa_t *ike_sa);
+
+ /**
+ * Create an enumerator over attributes to hand out to a peer.
+ *
+ * @param pool list of pools names (char*) to query attributes from
+ * @param ike_sa IKE_SA to request attributes for
+ * @param vip list of virtual IPs (host_t*) to assign to peer
+ * @return enumerator (configuration_attribute_type_t, chunk_t)
+ */
+ enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this,
+ linked_list_t *pools, ike_sa_t *ike_sa,
+ linked_list_t *vips);
+};
+
+#endif /** ATTRIBUTE_PROVIDER_H_ @}*/
diff --git a/src/libcharon/attributes/attributes.c b/src/libcharon/attributes/attributes.c
new file mode 100644
index 000000000..9fabcf4e4
--- /dev/null
+++ b/src/libcharon/attributes/attributes.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+
+#include "attributes.h"
+
+ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, HOME_AGENT_ADDRESS,
+ "INTERNAL_IP4_ADDRESS",
+ "INTERNAL_IP4_NETMASK",
+ "INTERNAL_IP4_DNS",
+ "INTERNAL_IP4_NBNS",
+ "INTERNAL_ADDRESS_EXPIRY",
+ "INTERNAL_IP4_DHCP",
+ "APPLICATION_VERSION",
+ "INTERNAL_IP6_ADDRESS",
+ "INTERNAL_IP6_NETMASK",
+ "INTERNAL_IP6_DNS",
+ "INTERNAL_IP6_NBNS",
+ "INTERNAL_IP6_DHCP",
+ "INTERNAL_IP4_SUBNET",
+ "SUPPORTED_ATTRIBUTES",
+ "INTERNAL_IP6_SUBNET",
+ "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,
+ "XAUTH_TYPE",
+ "XAUTH_USER_NAME",
+ "XAUTH_USER_PASSWORD",
+ "XAUTH_PASSCODE",
+ "XAUTH_MESSAGE",
+ "XAUTH_CHALLENGE",
+ "XAUTH_DOMAIN",
+ "XAUTH_STATUS",
+ "XAUTH_NEXT_PIN",
+ "XAUTH_ANSWER");
+ENUM_NEXT(configuration_attribute_type_names, INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, XAUTH_ANSWER,
+ "INTERNAL_IP4_SERVER",
+ "INTERNAL_IP6_SERVER");
+ENUM_NEXT(configuration_attribute_type_names, UNITY_BANNER, UNITY_DDNS_HOSTNAME, INTERNAL_IP6_SERVER,
+ "UNITY_BANNER",
+ "UNITY_SAVE_PASSWD",
+ "UNITY_DEF_DOMAIN",
+ "UNITY_SPLITDNS_NAME",
+ "UNITY_SPLIT_INCLUDE",
+ "UNITY_NATT_PORT",
+ "UNITY_LOCAL_LAN",
+ "UNITY_PFS",
+ "UNITY_FW_TYPE",
+ "UNITY_BACKUP_SERVERS",
+ "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,
+ "ADDR",
+ "MASK",
+ "DNS",
+ "NBNS",
+ "EXP",
+ "DHCP",
+ "VER",
+ "ADDR6",
+ "MASK6",
+ "DNS6",
+ "NBNS6",
+ "DHCP6",
+ "SUBNET",
+ "SUP",
+ "SUBNET6",
+ "MIP6HPFX",
+ "LINK6",
+ "PFX6",
+ "HOA");
+ENUM_NEXT(configuration_attribute_type_short_names, XAUTH_TYPE, XAUTH_ANSWER, HOME_AGENT_ADDRESS,
+ "X_TYPE",
+ "X_USER",
+ "X_PWD",
+ "X_CODE",
+ "X_MSG",
+ "X_CHALL",
+ "X_DOMAIN",
+ "X_STATUS",
+ "X_PIN",
+ "X_ANSWER");
+ENUM_NEXT(configuration_attribute_type_short_names, INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, XAUTH_ANSWER,
+ "SRV",
+ "SRV6");
+ENUM_NEXT(configuration_attribute_type_short_names, UNITY_BANNER, UNITY_DDNS_HOSTNAME, INTERNAL_IP6_SERVER,
+ "U_BANNER",
+ "U_SAVEPWD",
+ "U_DEFDOM",
+ "U_SPLITDNS",
+ "U_SPLITINC",
+ "U_NATTPORT",
+ "U_LOCALLAN",
+ "U_PFS",
+ "U_FWTYPE",
+ "U_BKPSRV",
+ "U_DDNSHOST");
+ENUM_END(configuration_attribute_type_short_names, UNITY_DDNS_HOSTNAME);
diff --git a/src/libcharon/attributes/attributes.h b/src/libcharon/attributes/attributes.h
new file mode 100644
index 000000000..5d1e9f9ba
--- /dev/null
+++ b/src/libcharon/attributes/attributes.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attributes_g attributes
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTES_H_
+#define ATTRIBUTES_H_
+
+typedef enum configuration_attribute_type_t configuration_attribute_type_t;
+
+#include <utils/utils.h>
+
+/**
+ * Type of the attribute, as in IKEv2 RFC 3.15.1 or IKEv1 ModeConfig.
+ */
+enum configuration_attribute_type_t {
+ INTERNAL_IP4_ADDRESS = 1,
+ INTERNAL_IP4_NETMASK = 2,
+ INTERNAL_IP4_DNS = 3,
+ INTERNAL_IP4_NBNS = 4,
+ INTERNAL_ADDRESS_EXPIRY = 5,
+ INTERNAL_IP4_DHCP = 6,
+ APPLICATION_VERSION = 7,
+ INTERNAL_IP6_ADDRESS = 8,
+ INTERNAL_IP6_NETMASK = 9,
+ INTERNAL_IP6_DNS = 10,
+ INTERNAL_IP6_NBNS = 11,
+ INTERNAL_IP6_DHCP = 12,
+ INTERNAL_IP4_SUBNET = 13,
+ SUPPORTED_ATTRIBUTES = 14,
+ INTERNAL_IP6_SUBNET = 15,
+ MIP6_HOME_PREFIX = 16,
+ INTERNAL_IP6_LINK = 17,
+ INTERNAL_IP6_PREFIX = 18,
+ HOME_AGENT_ADDRESS = 19,
+ /* XAUTH attributes */
+ XAUTH_TYPE = 16520,
+ XAUTH_USER_NAME = 16521,
+ XAUTH_USER_PASSWORD = 16522,
+ XAUTH_PASSCODE = 16523,
+ XAUTH_MESSAGE = 16524,
+ XAUTH_CHALLENGE = 16525,
+ XAUTH_DOMAIN = 16526,
+ XAUTH_STATUS = 16527,
+ XAUTH_NEXT_PIN = 16528,
+ XAUTH_ANSWER = 16529,
+ /* proprietary Microsoft attributes */
+ INTERNAL_IP4_SERVER = 23456,
+ INTERNAL_IP6_SERVER = 23457,
+ /* proprietary Cisco Unity attributes */
+ UNITY_BANNER = 28672,
+ UNITY_SAVE_PASSWD = 28673,
+ UNITY_DEF_DOMAIN = 28674,
+ UNITY_SPLITDNS_NAME = 28675,
+ UNITY_SPLIT_INCLUDE = 28676,
+ UNITY_NATT_PORT = 28677,
+ UNITY_LOCAL_LAN = 28678,
+ UNITY_PFS = 28679,
+ UNITY_FW_TYPE = 28680,
+ UNITY_BACKUP_SERVERS = 28681,
+ UNITY_DDNS_HOSTNAME = 28682
+};
+
+/**
+ * enum names for configuration_attribute_type_t.
+ */
+extern enum_name_t *configuration_attribute_type_names;
+
+/**
+ * Short enum names for configuration_attribute_type_t.
+ */
+extern enum_name_t *configuration_attribute_type_short_names;
+
+
+#endif /** ATTRIBUTES_H_ @}*/
diff --git a/src/libcharon/attributes/mem_pool.c b/src/libcharon/attributes/mem_pool.c
new file mode 100644
index 000000000..279668249
--- /dev/null
+++ b/src/libcharon/attributes/mem_pool.c
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 2008-2010 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "mem_pool.h"
+
+#include <library.h>
+#include <hydra.h>
+#include <utils/debug.h>
+#include <collections/hashtable.h>
+#include <collections/array.h>
+#include <threading/mutex.h>
+
+#define POOL_LIMIT (sizeof(u_int)*8 - 1)
+
+typedef struct private_mem_pool_t private_mem_pool_t;
+
+/**
+ * private data of mem_pool_t
+ */
+struct private_mem_pool_t {
+ /**
+ * public interface
+ */
+ mem_pool_t public;
+
+ /**
+ * name of the pool
+ */
+ char *name;
+
+ /**
+ * base address of the pool
+ */
+ host_t *base;
+
+ /**
+ * whether base is the network id of the subnet on which the pool is based
+ */
+ bool base_is_network_id;
+
+ /**
+ * size of the pool
+ */
+ u_int size;
+
+ /**
+ * next unused address
+ */
+ u_int unused;
+
+ /**
+ * lease hashtable [identity => entry]
+ */
+ hashtable_t *leases;
+
+ /**
+ * lock to safely access the pool
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * A unique lease address offset, with a hash of the peer host address
+ */
+typedef struct {
+ /** lease, as offset */
+ u_int offset;
+ /** hash of remote address, to allow duplicates */
+ u_int hash;
+} unique_lease_t;
+
+/**
+ * Lease entry.
+ */
+typedef struct {
+ /* identitiy reference */
+ identification_t *id;
+ /* array of online leases, as unique_lease_t */
+ array_t *online;
+ /* array of offline leases, as u_int offset */
+ array_t *offline;
+} entry_t;
+
+/**
+ * Create a new entry
+ */
+static entry_t* entry_create(identification_t *id)
+{
+ entry_t *entry;
+
+ INIT(entry,
+ .id = id->clone(id),
+ .online = array_create(sizeof(unique_lease_t), 0),
+ .offline = array_create(sizeof(u_int), 0),
+ );
+ return entry;
+}
+
+/**
+ * Destroy an entry
+ */
+static void entry_destroy(entry_t *this)
+{
+ this->id->destroy(this->id);
+ array_destroy(this->online);
+ array_destroy(this->offline);
+ free(this);
+}
+
+/**
+ * hashtable hash function for identities
+ */
+static u_int id_hash(identification_t *id)
+{
+ return chunk_hash(id->get_encoding(id));
+}
+
+/**
+ * hashtable equals function for identities
+ */
+static bool id_equals(identification_t *a, identification_t *b)
+{
+ return a->equals(a, b);
+}
+
+/**
+ * convert a pool offset to an address
+ */
+static host_t* offset2host(private_mem_pool_t *pool, int offset)
+{
+ chunk_t addr;
+ host_t *host;
+ u_int32_t *pos;
+
+ offset--;
+ if (offset > pool->size)
+ {
+ return NULL;
+ }
+
+ addr = chunk_clone(pool->base->get_address(pool->base));
+ if (pool->base->get_family(pool->base) == AF_INET6)
+ {
+ pos = (u_int32_t*)(addr.ptr + 12);
+ }
+ else
+ {
+ pos = (u_int32_t*)addr.ptr;
+ }
+ *pos = htonl(offset + ntohl(*pos));
+ host = host_create_from_chunk(pool->base->get_family(pool->base), addr, 0);
+ free(addr.ptr);
+ return host;
+}
+
+/**
+ * convert a host to a pool offset
+ */
+static int host2offset(private_mem_pool_t *pool, host_t *addr)
+{
+ chunk_t host, base;
+ u_int32_t hosti, basei;
+
+ if (addr->get_family(addr) != pool->base->get_family(pool->base))
+ {
+ return -1;
+ }
+ host = addr->get_address(addr);
+ base = pool->base->get_address(pool->base);
+ if (addr->get_family(addr) == AF_INET6)
+ {
+ /* only look at last /32 block */
+ if (!memeq(host.ptr, base.ptr, 12))
+ {
+ return -1;
+ }
+ host = chunk_skip(host, 12);
+ base = chunk_skip(base, 12);
+ }
+ hosti = ntohl(*(u_int32_t*)(host.ptr));
+ basei = ntohl(*(u_int32_t*)(base.ptr));
+ if (hosti > basei + pool->size)
+ {
+ return -1;
+ }
+ return hosti - basei + 1;
+}
+
+METHOD(mem_pool_t, get_name, const char*,
+ private_mem_pool_t *this)
+{
+ return this->name;
+}
+
+METHOD(mem_pool_t, get_base, host_t*,
+ private_mem_pool_t *this)
+{
+ return this->base;
+}
+
+METHOD(mem_pool_t, get_size, u_int,
+ private_mem_pool_t *this)
+{
+ return this->size;
+}
+
+METHOD(mem_pool_t, get_online, u_int,
+ private_mem_pool_t *this)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ u_int count = 0;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->leases->create_enumerator(this->leases);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ count += array_count(entry->online);
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+
+ return count;
+}
+
+METHOD(mem_pool_t, get_offline, u_int,
+ private_mem_pool_t *this)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ u_int count = 0;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->leases->create_enumerator(this->leases);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ count += array_count(entry->offline);
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+
+ return count;
+}
+
+/**
+ * Create a unique hash for a remote address
+ */
+static u_int hash_addr(host_t *addr)
+{
+ if (addr)
+ {
+ return chunk_hash_inc(addr->get_address(addr), addr->get_port(addr));
+ }
+ return 0;
+}
+
+/**
+ * Get an existing lease for id
+ */
+static int get_existing(private_mem_pool_t *this, identification_t *id,
+ host_t *requested, host_t *peer)
+{
+ enumerator_t *enumerator;
+ unique_lease_t *lease, reassign;
+ u_int *current;
+ entry_t *entry;
+ int offset = 0;
+
+ entry = this->leases->get(this->leases, id);
+ if (!entry)
+ {
+ return 0;
+ }
+
+ /* check for a valid offline lease, refresh */
+ enumerator = array_create_enumerator(entry->offline);
+ if (enumerator->enumerate(enumerator, &current))
+ {
+ reassign.offset = offset = *current;
+ reassign.hash = hash_addr(peer);
+ array_insert(entry->online, ARRAY_TAIL, &reassign);
+ array_remove_at(entry->offline, enumerator);
+ }
+ enumerator->destroy(enumerator);
+ if (offset)
+ {
+ DBG1(DBG_CFG, "reassigning offline lease to '%Y'", id);
+ return offset;
+ }
+ if (!peer)
+ {
+ return 0;
+ }
+ /* check for a valid online lease to reassign */
+ enumerator = array_create_enumerator(entry->online);
+ while (enumerator->enumerate(enumerator, &lease))
+ {
+ if (lease->offset == host2offset(this, requested) &&
+ lease->hash == hash_addr(peer))
+ {
+ offset = lease->offset;
+ /* add an additional "online" entry */
+ array_insert(entry->online, ARRAY_TAIL, lease);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (offset)
+ {
+ DBG1(DBG_CFG, "reassigning online lease to '%Y'", id);
+ }
+ return offset;
+}
+
+/**
+ * Get a new lease for id
+ */
+static int get_new(private_mem_pool_t *this, identification_t *id, host_t *peer)
+{
+ entry_t *entry;
+ unique_lease_t lease = {};
+
+ if (this->unused < this->size)
+ {
+ entry = this->leases->get(this->leases, id);
+ if (!entry)
+ {
+ entry = entry_create(id);
+ this->leases->put(this->leases, entry->id, entry);
+ }
+ /* assigning offset, starting by 1 */
+ lease.offset = ++this->unused + (this->base_is_network_id ? 1 : 0);
+ lease.hash = hash_addr(peer);
+ array_insert(entry->online, ARRAY_TAIL, &lease);
+ DBG1(DBG_CFG, "assigning new lease to '%Y'", id);
+ }
+ return lease.offset;
+}
+
+/**
+ * Get a reassigned lease for id in case the pool is full
+ */
+static int get_reassigned(private_mem_pool_t *this, identification_t *id,
+ host_t *peer)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ u_int current;
+ unique_lease_t lease = {};
+
+ enumerator = this->leases->create_enumerator(this->leases);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ if (array_remove(entry->offline, ARRAY_HEAD, &current))
+ {
+ lease.offset = current;
+ DBG1(DBG_CFG, "reassigning existing offline lease by '%Y' "
+ "to '%Y'", entry->id, id);
+ }
+ if (!array_count(entry->online) && !array_count(entry->offline))
+ {
+ this->leases->remove_at(this->leases, enumerator);
+ entry_destroy(entry);
+ }
+ if (lease.offset)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (lease.offset)
+ {
+ entry = this->leases->get(this->leases, id);
+ if (!entry)
+ {
+ entry = entry_create(id);
+ this->leases->put(this->leases, entry->id, entry);
+ }
+ lease.hash = hash_addr(peer);
+ array_insert(entry->online, ARRAY_TAIL, &lease);
+ }
+ return lease.offset;
+}
+
+METHOD(mem_pool_t, acquire_address, host_t*,
+ private_mem_pool_t *this, identification_t *id, host_t *requested,
+ mem_pool_op_t operation, host_t *peer)
+{
+ int offset = 0;
+
+ /* if the pool is empty (e.g. in the %config case) we simply return the
+ * requested address */
+ if (this->size == 0)
+ {
+ return requested->clone(requested);
+ }
+
+ if (requested->get_family(requested) !=
+ this->base->get_family(this->base))
+ {
+ return NULL;
+ }
+
+ this->mutex->lock(this->mutex);
+ switch (operation)
+ {
+ case MEM_POOL_EXISTING:
+ offset = get_existing(this, id, requested, peer);
+ break;
+ case MEM_POOL_NEW:
+ offset = get_new(this, id, peer);
+ break;
+ case MEM_POOL_REASSIGN:
+ offset = get_reassigned(this, id, peer);
+ if (!offset)
+ {
+ DBG1(DBG_CFG, "pool '%s' is full, unable to assign address",
+ this->name);
+ }
+ break;
+ default:
+ break;
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (offset)
+ {
+ return offset2host(this, offset);
+ }
+ return NULL;
+}
+
+METHOD(mem_pool_t, release_address, bool,
+ private_mem_pool_t *this, host_t *address, identification_t *id)
+{
+ enumerator_t *enumerator;
+ bool found = FALSE, more = FALSE;
+ entry_t *entry;
+ u_int offset;
+ unique_lease_t *current;
+
+ if (this->size != 0)
+ {
+ this->mutex->lock(this->mutex);
+ entry = this->leases->get(this->leases, id);
+ if (entry)
+ {
+ offset = host2offset(this, address);
+
+ enumerator = array_create_enumerator(entry->online);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (current->offset == offset)
+ {
+ if (!found)
+ { /* remove the first entry only */
+ array_remove_at(entry->online, enumerator);
+ found = TRUE;
+ }
+ else
+ { /* but check for more entries */
+ more = TRUE;
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (found && !more)
+ {
+ /* no tunnels are online anymore for this lease, make offline */
+ array_insert(entry->offline, ARRAY_TAIL, &offset);
+ DBG1(DBG_CFG, "lease %H by '%Y' went offline", address, id);
+ }
+ }
+ this->mutex->unlock(this->mutex);
+ }
+ return found;
+}
+
+/**
+ * lease enumerator
+ */
+typedef struct {
+ /** implemented enumerator interface */
+ enumerator_t public;
+ /** hash-table enumerator */
+ enumerator_t *entries;
+ /** online enumerator */
+ enumerator_t *online;
+ /** offline enumerator */
+ enumerator_t *offline;
+ /** enumerated pool */
+ private_mem_pool_t *pool;
+ /** currently enumerated entry */
+ entry_t *entry;
+ /** currently enumerated lease address */
+ host_t *addr;
+} lease_enumerator_t;
+
+METHOD(enumerator_t, lease_enumerate, bool,
+ lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online)
+{
+ u_int *offset;
+ unique_lease_t *lease;
+
+ DESTROY_IF(this->addr);
+ this->addr = NULL;
+
+ while (TRUE)
+ {
+ if (this->entry)
+ {
+ if (this->online->enumerate(this->online, &lease))
+ {
+ *id = this->entry->id;
+ *addr = this->addr = offset2host(this->pool, lease->offset);
+ *online = TRUE;
+ return TRUE;
+ }
+ if (this->offline->enumerate(this->offline, &offset))
+ {
+ *id = this->entry->id;
+ *addr = this->addr = offset2host(this->pool, *offset);
+ *online = FALSE;
+ return TRUE;
+ }
+ this->online->destroy(this->online);
+ this->offline->destroy(this->offline);
+ this->online = this->offline = NULL;
+ }
+ if (!this->entries->enumerate(this->entries, NULL, &this->entry))
+ {
+ return FALSE;
+ }
+ this->online = array_create_enumerator(this->entry->online);
+ this->offline = array_create_enumerator(this->entry->offline);
+ }
+}
+
+METHOD(enumerator_t, lease_enumerator_destroy, void,
+ lease_enumerator_t *this)
+{
+ DESTROY_IF(this->addr);
+ DESTROY_IF(this->online);
+ DESTROY_IF(this->offline);
+ this->entries->destroy(this->entries);
+ this->pool->mutex->unlock(this->pool->mutex);
+ free(this);
+}
+
+METHOD(mem_pool_t, create_lease_enumerator, enumerator_t*,
+ private_mem_pool_t *this)
+{
+ lease_enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_lease_enumerate,
+ .destroy = _lease_enumerator_destroy,
+ },
+ .pool = this,
+ .entries = this->leases->create_enumerator(this->leases),
+ );
+ return &enumerator->public;
+}
+
+METHOD(mem_pool_t, destroy, void,
+ private_mem_pool_t *this)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ enumerator = this->leases->create_enumerator(this->leases);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ entry_destroy(entry);
+ }
+ enumerator->destroy(enumerator);
+
+ this->leases->destroy(this->leases);
+ this->mutex->destroy(this->mutex);
+ DESTROY_IF(this->base);
+ free(this->name);
+ free(this);
+}
+
+/**
+ * Generic constructor
+ */
+static private_mem_pool_t *create_generic(char *name)
+{
+ private_mem_pool_t *this;
+
+ INIT(this,
+ .public = {
+ .get_name = _get_name,
+ .get_base = _get_base,
+ .get_size = _get_size,
+ .get_online = _get_online,
+ .get_offline = _get_offline,
+ .acquire_address = _acquire_address,
+ .release_address = _release_address,
+ .create_lease_enumerator = _create_lease_enumerator,
+ .destroy = _destroy,
+ },
+ .name = strdup(name),
+ .leases = hashtable_create((hashtable_hash_t)id_hash,
+ (hashtable_equals_t)id_equals, 16),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
+
+ return this;
+}
+
+/**
+ * Check if the given host is the network ID of a subnet, that is, if hostbits
+ * are zero. Since we limit pools to 2^31 addresses we only have to check the
+ * last 4 bytes.
+ */
+static u_int network_id_diff(host_t *host, int hostbits)
+{
+ u_int32_t last;
+ chunk_t addr;
+
+ if (!hostbits)
+ {
+ return 0;
+ }
+ addr = host->get_address(host);
+ last = untoh32(addr.ptr + addr.len - sizeof(last));
+ hostbits = sizeof(last) * 8 - hostbits;
+ return (last << hostbits) >> hostbits;
+}
+
+/**
+ * Described in header
+ */
+mem_pool_t *mem_pool_create(char *name, host_t *base, int bits)
+{
+ private_mem_pool_t *this;
+ u_int diff;
+ int addr_bits;
+
+ this = create_generic(name);
+ if (base)
+ {
+ addr_bits = base->get_family(base) == AF_INET ? 32 : 128;
+ bits = max(0, min(bits, addr_bits));
+ /* net bits -> host bits */
+ bits = addr_bits - bits;
+ if (bits > POOL_LIMIT)
+ {
+ bits = POOL_LIMIT;
+ DBG1(DBG_CFG, "virtual IP pool too large, limiting to %H/%d",
+ base, addr_bits - bits);
+ }
+ this->size = 1 << bits;
+ this->base = base->clone(base);
+
+ if (this->size > 2)
+ {
+ /* if base is the network id we later skip the first address,
+ * otherwise adjust the size to represent the actual number
+ * of assignable addresses */
+ diff = network_id_diff(base, bits);
+ if (!diff)
+ {
+ this->base_is_network_id = TRUE;
+ this->size--;
+ }
+ else
+ {
+ this->size -= diff;
+ }
+ /* skip the last address (broadcast) of the subnet */
+ this->size--;
+ }
+ else if (network_id_diff(base, bits))
+ { /* only serve the second address of the subnet */
+ this->size--;
+ }
+ }
+ return &this->public;
+}
+
+/**
+ * Described in header
+ */
+mem_pool_t *mem_pool_create_range(char *name, host_t *from, host_t *to)
+{
+ private_mem_pool_t *this;
+ chunk_t fromaddr, toaddr;
+ u_int32_t diff;
+
+ fromaddr = from->get_address(from);
+ toaddr = to->get_address(to);
+
+ if (from->get_family(from) != to->get_family(to) ||
+ fromaddr.len != toaddr.len || fromaddr.len < sizeof(diff) ||
+ memcmp(fromaddr.ptr, toaddr.ptr, toaddr.len) > 0)
+ {
+ DBG1(DBG_CFG, "invalid IP address range: %H-%H", from, to);
+ return NULL;
+ }
+ if (fromaddr.len > sizeof(diff) &&
+ !chunk_equals(chunk_create(fromaddr.ptr, fromaddr.len - sizeof(diff)),
+ chunk_create(toaddr.ptr, toaddr.len - sizeof(diff))))
+ {
+ DBG1(DBG_CFG, "IP address range too large: %H-%H", from, to);
+ return NULL;
+ }
+ this = create_generic(name);
+ this->base = from->clone(from);
+ diff = untoh32(toaddr.ptr + toaddr.len - sizeof(diff)) -
+ untoh32(fromaddr.ptr + fromaddr.len - sizeof(diff));
+ this->size = diff + 1;
+
+ return &this->public;
+}
diff --git a/src/libcharon/attributes/mem_pool.h b/src/libcharon/attributes/mem_pool.h
new file mode 100644
index 000000000..3ee1dd37d
--- /dev/null
+++ b/src/libcharon/attributes/mem_pool.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup mem_pool mem_pool
+ * @{ @ingroup attributes
+ */
+
+#ifndef MEM_POOL_H
+#define MEM_POOL_H
+
+typedef struct mem_pool_t mem_pool_t;
+typedef enum mem_pool_op_t mem_pool_op_t;
+
+#include <networking/host.h>
+#include <utils/identification.h>
+
+/**
+ * In-memory IP pool acquire operation.
+ */
+enum mem_pool_op_t {
+ /** Check for an exsiting lease */
+ MEM_POOL_EXISTING,
+ /** Get a new lease */
+ MEM_POOL_NEW,
+ /** Replace an existing offline lease of another ID */
+ MEM_POOL_REASSIGN,
+};
+
+/**
+ * An in-memory IP address pool.
+ */
+struct mem_pool_t {
+
+ /**
+ * Get the name of this pool.
+ *
+ * @return the name of this pool
+ */
+ const char* (*get_name)(mem_pool_t *this);
+
+ /**
+ * Get the base (first) address of this pool.
+ *
+ * @return base address, internal host
+ */
+ host_t* (*get_base)(mem_pool_t *this);
+
+ /**
+ * Get the size (i.e. number of addresses) of this pool.
+ *
+ * @return the size of this pool
+ */
+ u_int (*get_size)(mem_pool_t *this);
+
+ /**
+ * Get the number of online leases.
+ *
+ * @return the number of offline leases
+ */
+ u_int (*get_online)(mem_pool_t *this);
+
+ /**
+ * Get the number of offline leases.
+ *
+ * @return the number of online leases
+ */
+ u_int (*get_offline)(mem_pool_t *this);
+
+ /**
+ * Acquire an address for the given id from this pool.
+ *
+ * This call is usually invoked several times: The first time to find an
+ * existing lease (MEM_POOL_EXISTING), if none found a second time to
+ * acquire a new lease (MEM_POOL_NEW), and if the pool is full once again
+ * to assign an existing offline lease (MEM_POOL_REASSIGN).
+ *
+ * If the same identity requests a virtual IP that is already assigned to
+ * it, the peer address and port is used to check if it is the same client
+ * instance that is connecting. If this is true, the request is considered
+ * a request for a reauthentication attempt, and the same virtual IP gets
+ * assigned to the peer.
+ *
+ * @param id the id to acquire an address for
+ * @param requested acquire this address, if possible
+ * @param operation acquire operation to perform, see above
+ * @param peer optional remote IKE address and port
+ * @return the acquired address
+ */
+ host_t* (*acquire_address)(mem_pool_t *this, identification_t *id,
+ host_t *requested, mem_pool_op_t operation,
+ host_t *peer);
+
+ /**
+ * Release a previously acquired address.
+ *
+ * @param address the address to release
+ * @param id the id the address was assigned to
+ * @return TRUE, if the lease was found
+ */
+ bool (*release_address)(mem_pool_t *this, host_t *address,
+ identification_t *id);
+
+ /**
+ * Create an enumerator over the leases of this pool.
+ *
+ * Enumerator enumerates over
+ * identification_t *id, host_t *address, bool online
+ *
+ * @return enumerator
+ */
+ enumerator_t* (*create_lease_enumerator)(mem_pool_t *this);
+
+ /**
+ * Destroy a mem_pool_t instance.
+ */
+ void (*destroy)(mem_pool_t *this);
+};
+
+/**
+ * Create an in-memory IP address pool.
+ *
+ * An empty pool just returns the requested address.
+ *
+ * @param name name of this pool
+ * @param base base address of this pool, NULL to create an empty pool
+ * @param bits number of non-network bits in base, as in CIDR notation
+ * @return memory pool instance
+ */
+mem_pool_t *mem_pool_create(char *name, host_t *base, int bits);
+
+/**
+ * Create an in-memory IP address from a range.
+ *
+ * @param name name of this pool
+ * @param from start of ranged pool
+ * @param to end of ranged pool
+ * @return memory pool instance, NULL if range invalid
+ */
+mem_pool_t *mem_pool_create_range(char *name, host_t *from, host_t *to);
+
+#endif /** MEM_POOL_H_ @} */
diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c
index cb59f976b..7938f46cc 100644
--- a/src/libcharon/bus/bus.c
+++ b/src/libcharon/bus/bus.c
@@ -755,6 +755,33 @@ METHOD(bus_t, ike_rekey, void,
this->mutex->unlock(this->mutex);
}
+METHOD(bus_t, ike_update, void,
+ private_bus_t *this, ike_sa_t *ike_sa, bool local, host_t *new)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ bool keep;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->ike_update)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->ike_update(entry->listener, ike_sa, local, new);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
METHOD(bus_t, ike_reestablish_pre, void,
private_bus_t *this, ike_sa_t *old, ike_sa_t *new)
{
@@ -1006,6 +1033,7 @@ bus_t *bus_create()
.child_keys = _child_keys,
.ike_updown = _ike_updown,
.ike_rekey = _ike_rekey,
+ .ike_update = _ike_update,
.ike_reestablish_pre = _ike_reestablish_pre,
.ike_reestablish_post = _ike_reestablish_post,
.child_updown = _child_updown,
diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h
index e1d221ca5..051c429f9 100644
--- a/src/libcharon/bus/bus.h
+++ b/src/libcharon/bus/bus.h
@@ -382,6 +382,15 @@ struct bus_t {
void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new);
/**
+ * IKE_SA peer endpoint update hook.
+ *
+ * @param ike_sa updated IKE_SA, having old endpoints set
+ * @param local TRUE if local endpoint gets updated, FALSE for remote
+ * @param new new endpoint address and port
+ */
+ void (*ike_update)(bus_t *this, ike_sa_t *ike_sa, bool local, host_t *new);
+
+ /**
* IKE_SA reestablishing hook (before resolving hosts).
*
* @param old reestablished and obsolete IKE_SA
diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h
index 0910cb361..3447d8f99 100644
--- a/src/libcharon/bus/listeners/listener.h
+++ b/src/libcharon/bus/listeners/listener.h
@@ -128,6 +128,17 @@ struct listener_t {
bool (*ike_rekey)(listener_t *this, ike_sa_t *old, ike_sa_t *new);
/**
+ * Hook called for IKE_SA peer endpoint updates.
+ *
+ * @param ike_sa updated IKE_SA, having old endpoints set
+ * @param local TRUE if local endpoint gets updated, FALSE for remote
+ * @param new new endpoint address and port
+ * @return TRUE to stay registered, FALSE to unregister
+ */
+ bool (*ike_update)(listener_t *this, ike_sa_t *ike_sa,
+ bool local, host_t *new);
+
+ /**
* Hook called when an initiator reestablishes an IKE_SA.
*
* This is invoked right after creating the new IKE_SA and setting the
diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c
index 42a3e9057..9464ceb5d 100644
--- a/src/libcharon/config/ike_cfg.c
+++ b/src/libcharon/config/ike_cfg.c
@@ -459,25 +459,10 @@ static traffic_selector_t* make_range(char *str)
{
traffic_selector_t *ts;
ts_type_t type;
- char *pos;
host_t *from, *to;
- pos = strchr(str, '-');
- if (!pos)
- {
- return NULL;
- }
- to = host_create_from_string(pos + 1, 0);
- if (!to)
- {
- return NULL;
- }
- str = strndup(str, pos - str);
- from = host_create_from_string_and_family(str, to->get_family(to), 0);
- free(str);
- if (!from)
+ if (!host_create_from_range(str, &from, &to))
{
- to->destroy(to);
return NULL;
}
if (to->get_family(to) == AF_INET)
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 50d3c6f66..e59dcd9ec 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -399,10 +399,12 @@ static const struct {
pseudo_random_function_t prf;
} integ_prf_map[] = {
{AUTH_HMAC_SHA1_96, PRF_HMAC_SHA1 },
+ {AUTH_HMAC_SHA1_160, PRF_HMAC_SHA1 },
{AUTH_HMAC_SHA2_256_128, PRF_HMAC_SHA2_256 },
{AUTH_HMAC_SHA2_384_192, PRF_HMAC_SHA2_384 },
{AUTH_HMAC_SHA2_512_256, PRF_HMAC_SHA2_512 },
{AUTH_HMAC_MD5_96, PRF_HMAC_MD5 },
+ {AUTH_HMAC_MD5_128, PRF_HMAC_MD5 },
{AUTH_AES_XCBC_96, PRF_AES128_XCBC },
{AUTH_CAMELLIA_XCBC_96, PRF_CAMELLIA128_XCBC },
{AUTH_AES_CMAC_96, PRF_AES128_CMAC },
diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c
index 25667e532..fd8349e2f 100644
--- a/src/libcharon/control/controller.c
+++ b/src/libcharon/control/controller.c
@@ -303,6 +303,18 @@ METHOD(listener_t, child_state_change, bool,
/* proper delete */
this->status = SUCCESS;
break;
+ case CHILD_RETRYING:
+ /* retrying with a different DH group; survive another
+ * initiation round */
+ this->status = NEED_MORE;
+ return TRUE;
+ case CHILD_CREATED:
+ if (this->status == NEED_MORE)
+ {
+ this->status = FAILED;
+ return TRUE;
+ }
+ break;
default:
break;
}
@@ -437,7 +449,7 @@ METHOD(job_t, terminate_ike_execute, job_requeue_t,
ike_sa_t *ike_sa;
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- unique_id, FALSE);
+ unique_id);
if (!ike_sa)
{
DBG1(DBG_IKE, "unable to terminate IKE_SA: ID %d not found", unique_id);
@@ -522,17 +534,15 @@ METHOD(job_t, terminate_child_execute, job_requeue_t,
interface_job_t *job)
{
interface_listener_t *listener = &job->listener;
- u_int32_t reqid = listener->id;
- enumerator_t *enumerator;
+ u_int32_t id = listener->id;
child_sa_t *child_sa;
ike_sa_t *ike_sa;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- reqid, TRUE);
+ ike_sa = charon->child_sa_manager->checkout_by_id(charon->child_sa_manager,
+ id, &child_sa);
if (!ike_sa)
{
- DBG1(DBG_IKE, "unable to terminate, CHILD_SA with ID %d not found",
- reqid);
+ DBG1(DBG_IKE, "unable to terminate, CHILD_SA with ID %d not found", id);
listener->status = NOT_FOUND;
/* release listener */
listener_done(listener);
@@ -542,22 +552,10 @@ METHOD(job_t, terminate_child_execute, job_requeue_t,
listener->ike_sa = ike_sa;
listener->lock->unlock(listener->lock);
- enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
- while (enumerator->enumerate(enumerator, (void**)&child_sa))
- {
- if (child_sa->get_state(child_sa) != CHILD_ROUTED &&
- child_sa->get_reqid(child_sa) == reqid)
- {
- break;
- }
- child_sa = NULL;
- }
- enumerator->destroy(enumerator);
-
- if (!child_sa)
+ if (child_sa->get_state(child_sa) == CHILD_ROUTED)
{
DBG1(DBG_IKE, "unable to terminate, established "
- "CHILD_SA with ID %d not found", reqid);
+ "CHILD_SA with ID %d not found", id);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
listener->status = NOT_FOUND;
/* release listener */
@@ -584,7 +582,7 @@ METHOD(job_t, terminate_child_execute, job_requeue_t,
}
METHOD(controller_t, terminate_child, status_t,
- controller_t *this, u_int32_t reqid,
+ controller_t *this, u_int32_t unique_id,
controller_cb_t callback, void *param, u_int timeout)
{
interface_job_t *job;
@@ -605,7 +603,7 @@ METHOD(controller_t, terminate_child, status_t,
.param = param,
},
.status = FAILED,
- .id = reqid,
+ .id = unique_id,
.lock = spinlock_create(),
},
.public = {
diff --git a/src/libcharon/control/controller.h b/src/libcharon/control/controller.h
index 222285cde..02f4ebb2b 100644
--- a/src/libcharon/control/controller.h
+++ b/src/libcharon/control/controller.h
@@ -118,7 +118,7 @@ struct controller_t {
* If a callback is provided the function is synchronous and thus blocks
* until the CHILD_SA is properly deleted, or the call timed out.
*
- * @param reqid reqid of the CHILD_SA to terminate
+ * @param unique_id CHILD_SA unique ID to terminate
* @param cb logging callback
* @param param parameter to include in each call of cb
* @param timeout timeout in ms to wait for callbacks, 0 to disable
@@ -128,7 +128,7 @@ struct controller_t {
* - NEED_MORE, if callback returned FALSE
* - OUT_OF_RES if timed out
*/
- status_t (*terminate_child)(controller_t *this, u_int32_t reqid,
+ status_t (*terminate_child)(controller_t *this, u_int32_t unique_id,
controller_cb_t callback, void *param,
u_int timeout);
diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c
index 3ae7c4e6f..b1b8f57f0 100644
--- a/src/libcharon/daemon.c
+++ b/src/libcharon/daemon.c
@@ -474,12 +474,15 @@ static void destroy(private_daemon_t *this)
DESTROY_IF(this->public.connect_manager);
DESTROY_IF(this->public.mediation_manager);
#endif /* ME */
- /* make sure the cache is clear before unloading plugins */
+ /* make sure the cache and scheduler are clear before unloading plugins */
lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
+ lib->scheduler->flush(lib->scheduler);
lib->plugins->unload(lib->plugins);
+ DESTROY_IF(this->public.attributes);
DESTROY_IF(this->kernel_handler);
DESTROY_IF(this->public.traps);
DESTROY_IF(this->public.shunts);
+ DESTROY_IF(this->public.child_sa_manager);
DESTROY_IF(this->public.ike_sa_manager);
DESTROY_IF(this->public.controller);
DESTROY_IF(this->public.eap);
@@ -606,6 +609,7 @@ METHOD(daemon_t, initialize, bool,
{
return FALSE;
}
+ this->public.child_sa_manager = child_sa_manager_create();
/* Queue start_action job */
lib->processor->queue_job(lib->processor, (job_t*)start_action_job_create());
@@ -642,6 +646,7 @@ private_daemon_t *daemon_create()
.ref = 1,
);
charon = &this->public;
+ this->public.attributes = attribute_manager_create();
this->public.controller = controller_create();
this->public.eap = eap_manager_create();
this->public.xauth = xauth_manager_create();
diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h
index 36242bb04..d16bf1ddb 100644
--- a/src/libcharon/daemon.h
+++ b/src/libcharon/daemon.h
@@ -19,6 +19,9 @@
/**
* @defgroup libcharon libcharon
*
+ * @defgroup attributes attributes
+ * @ingroup libcharon
+ *
* @defgroup bus bus
* @ingroup libcharon
*
@@ -152,12 +155,14 @@
typedef struct daemon_t daemon_t;
+#include <attributes/attribute_manager.h>
#include <network/sender.h>
#include <network/receiver.h>
#include <network/socket_manager.h>
#include <control/controller.h>
#include <bus/bus.h>
#include <sa/ike_sa_manager.h>
+#include <sa/child_sa_manager.h>
#include <sa/trap_manager.h>
#include <sa/shunt_manager.h>
#include <config/backend_manager.h>
@@ -215,6 +220,11 @@ struct daemon_t {
ike_sa_manager_t *ike_sa_manager;
/**
+ * A child_sa_manager_t instance.
+ */
+ child_sa_manager_t *child_sa_manager;
+
+ /**
* Manager for triggering policies, called traps
*/
trap_manager_t *traps;
@@ -240,6 +250,11 @@ struct daemon_t {
receiver_t *receiver;
/**
+ * Manager for IKE configuration attributes
+ */
+ attribute_manager_t *attributes;
+
+ /**
* The signaling bus.
*/
bus_t *bus;
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c
index cb6c97f25..0a596ffb0 100644
--- a/src/libcharon/encoding/message.c
+++ b/src/libcharon/encoding/message.c
@@ -180,6 +180,7 @@ static payload_order_t ike_sa_init_r_order[] = {
*/
static payload_rule_t ike_auth_i_rules[] = {
/* payload type min max encr suff */
+ {PLV2_FRAGMENT, 0, 1, TRUE, TRUE},
{PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{PLV2_EAP, 0, 1, TRUE, TRUE},
{PLV2_AUTH, 0, 1, TRUE, TRUE},
@@ -227,6 +228,7 @@ static payload_order_t ike_auth_i_order[] = {
{PLV2_NOTIFY, NO_ADDITIONAL_ADDRESSES},
{PLV2_NOTIFY, 0},
{PLV2_VENDOR_ID, 0},
+ {PLV2_FRAGMENT, 0},
};
/**
@@ -234,6 +236,7 @@ static payload_order_t ike_auth_i_order[] = {
*/
static payload_rule_t ike_auth_r_rules[] = {
/* payload type min max encr suff */
+ {PLV2_FRAGMENT, 0, 1, TRUE, TRUE},
{PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
{PLV2_EAP, 0, 1, TRUE, TRUE},
{PLV2_AUTH, 0, 1, TRUE, TRUE},
@@ -270,6 +273,7 @@ static payload_order_t ike_auth_r_order[] = {
{PLV2_NOTIFY, NO_ADDITIONAL_ADDRESSES},
{PLV2_NOTIFY, 0},
{PLV2_VENDOR_ID, 0},
+ {PLV2_FRAGMENT, 0},
};
/**
@@ -277,6 +281,7 @@ static payload_order_t ike_auth_r_order[] = {
*/
static payload_rule_t informational_i_rules[] = {
/* payload type min max encr suff */
+ {PLV2_FRAGMENT, 0, 1, TRUE, TRUE},
{PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{PLV2_CONFIGURATION, 0, 1, TRUE, FALSE},
{PLV2_DELETE, 0, MAX_DELETE_PAYLOADS, TRUE, FALSE},
@@ -295,6 +300,7 @@ static payload_order_t informational_i_order[] = {
{PLV2_NOTIFY, 0},
{PLV2_DELETE, 0},
{PLV2_CONFIGURATION, 0},
+ {PLV2_FRAGMENT, 0},
};
/**
@@ -302,6 +308,7 @@ static payload_order_t informational_i_order[] = {
*/
static payload_rule_t informational_r_rules[] = {
/* payload type min max encr suff */
+ {PLV2_FRAGMENT, 0, 1, TRUE, TRUE},
{PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{PLV2_CONFIGURATION, 0, 1, TRUE, FALSE},
{PLV2_DELETE, 0, MAX_DELETE_PAYLOADS, TRUE, FALSE},
@@ -320,6 +327,7 @@ static payload_order_t informational_r_order[] = {
{PLV2_NOTIFY, 0},
{PLV2_DELETE, 0},
{PLV2_CONFIGURATION, 0},
+ {PLV2_FRAGMENT, 0},
};
/**
@@ -327,6 +335,7 @@ static payload_order_t informational_r_order[] = {
*/
static payload_rule_t create_child_sa_i_rules[] = {
/* payload type min max encr suff */
+ {PLV2_FRAGMENT, 0, 1, TRUE, TRUE},
{PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{PLV2_SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE},
{PLV2_NONCE, 1, 1, TRUE, FALSE},
@@ -353,6 +362,7 @@ static payload_order_t create_child_sa_i_order[] = {
{PLV2_TS_INITIATOR, 0},
{PLV2_TS_RESPONDER, 0},
{PLV2_NOTIFY, 0},
+ {PLV2_FRAGMENT, 0},
};
/**
@@ -360,6 +370,7 @@ static payload_order_t create_child_sa_i_order[] = {
*/
static payload_rule_t create_child_sa_r_rules[] = {
/* payload type min max encr suff */
+ {PLV2_FRAGMENT, 0, 1, TRUE, TRUE},
{PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
{PLV2_SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE},
{PLV2_NONCE, 1, 1, TRUE, FALSE},
@@ -386,6 +397,7 @@ static payload_order_t create_child_sa_r_order[] = {
{PLV2_TS_RESPONDER, 0},
{PLV2_NOTIFY, ADDITIONAL_TS_POSSIBLE},
{PLV2_NOTIFY, 0},
+ {PLV2_FRAGMENT, 0},
};
#ifdef ME
@@ -2143,6 +2155,8 @@ METHOD(message_t, parse_header, status_t,
}
ike_header->destroy(ike_header);
+ this->parser->set_major_version(this->parser, this->major_version);
+
DBG2(DBG_ENC, "parsed a %N %s header", exchange_type_names,
this->exchange_type, this->major_version == IKEV1_MAJOR_VERSION ?
"message" : (this->is_request ? "request" : "response"));
@@ -2463,7 +2477,7 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat)
was_encrypted = "encrypted fragment payload";
}
- if (payload_is_known(type) && !was_encrypted &&
+ if (payload_is_known(type, this->major_version) && !was_encrypted &&
!is_connectivity_check(this, payload) &&
this->exchange_type != AGGRESSIVE)
{
diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c
index d6240fde2..f8340367e 100644
--- a/src/libcharon/encoding/parser.c
+++ b/src/libcharon/encoding/parser.c
@@ -59,6 +59,11 @@ struct private_parser_t {
parser_t public;
/**
+ * major IKE version
+ */
+ u_int8_t major_version;
+
+ /**
* Current bit for reading in input data.
*/
u_int8_t bit_pos;
@@ -369,7 +374,14 @@ METHOD(parser_t, parse_payload, status_t,
encoding_rule_t *rule;
/* create instance of the payload to parse */
- pld = payload_create(payload_type);
+ if (payload_is_known(payload_type, this->major_version))
+ {
+ pld = payload_create(payload_type);
+ }
+ else
+ {
+ pld = (payload_t*)unknown_payload_create(payload_type);
+ }
DBG2(DBG_ENC, "parsing %N payload, %d bytes left",
payload_type_names, payload_type, this->input_roof - this->byte_pos);
@@ -629,6 +641,12 @@ METHOD(parser_t, reset_context, void,
this->bit_pos = 0;
}
+METHOD(parser_t, set_major_version, void,
+ private_parser_t *this, u_int8_t major_version)
+{
+ this->major_version = major_version;
+}
+
METHOD(parser_t, destroy, void,
private_parser_t *this)
{
@@ -646,6 +664,7 @@ parser_t *parser_create(chunk_t data)
.public = {
.parse_payload = _parse_payload,
.reset_context = _reset_context,
+ .set_major_version = _set_major_version,
.get_remaining_byte_count = _get_remaining_byte_count,
.destroy = _destroy,
},
diff --git a/src/libcharon/encoding/parser.h b/src/libcharon/encoding/parser.h
index 27c5f03fe..5fd3e86ee 100644
--- a/src/libcharon/encoding/parser.h
+++ b/src/libcharon/encoding/parser.h
@@ -29,7 +29,7 @@ typedef struct parser_t parser_t;
#include <encoding/payloads/payload.h>
/**
- * A parser_t class to parse IKEv2 payloads.
+ * A parser_t class to parse IKE payloads.
*
* A parser is used for parsing one chunk of data. Multiple
* payloads can be parsed out of the chunk using parse_payload.
@@ -50,7 +50,8 @@ struct parser_t {
* - SUCCESSFUL if succeeded,
* - PARSE_ERROR if corrupted/invalid data found
*/
- status_t (*parse_payload) (parser_t *this, payload_type_t payload_type, payload_t **payload);
+ status_t (*parse_payload) (parser_t *this, payload_type_t payload_type,
+ payload_t **payload);
/**
* Gets the remaining byte count which is not currently parsed.
@@ -63,6 +64,13 @@ struct parser_t {
void (*reset_context) (parser_t *this);
/**
+ * Set the major IKE version.
+ *
+ * @param major_version the major IKE version
+ */
+ void (*set_major_version) (parser_t *this, u_int8_t major_version);
+
+ /**
* Destroys a parser_t object.
*/
void (*destroy) (parser_t *this);
diff --git a/src/libcharon/encoding/payloads/delete_payload.c b/src/libcharon/encoding/payloads/delete_payload.c
index c2ab3b951..f11ea485c 100644
--- a/src/libcharon/encoding/payloads/delete_payload.c
+++ b/src/libcharon/encoding/payloads/delete_payload.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2010 revosec AG
* Copyright (C) 2005 Jan Hutter
@@ -281,6 +282,19 @@ METHOD(delete_payload_t, set_ike_spi, void,
this->payload_length = get_header_length(this) + this->spi_size;
}
+METHOD(delete_payload_t, get_ike_spi, bool,
+ private_delete_payload_t *this, u_int64_t *spi_i, u_int64_t *spi_r)
+{
+ if (this->protocol_id != PROTO_IKE ||
+ this->spis.len < 2 * sizeof(u_int64_t))
+ {
+ return FALSE;
+ }
+ memcpy(spi_i, this->spis.ptr, sizeof(u_int64_t));
+ memcpy(spi_r, this->spis.ptr + sizeof(u_int64_t), sizeof(u_int64_t));
+ return TRUE;
+}
+
/**
* SPI enumerator implementation
*/
@@ -352,6 +366,7 @@ delete_payload_t *delete_payload_create(payload_type_t type,
.get_protocol_id = _get_protocol_id,
.add_spi = _add_spi,
.set_ike_spi = _set_ike_spi,
+ .get_ike_spi = _get_ike_spi,
.create_spi_enumerator = _create_spi_enumerator,
.destroy = _destroy,
},
diff --git a/src/libcharon/encoding/payloads/delete_payload.h b/src/libcharon/encoding/payloads/delete_payload.h
index 46a89eab6..6728718cd 100644
--- a/src/libcharon/encoding/payloads/delete_payload.h
+++ b/src/libcharon/encoding/payloads/delete_payload.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -61,6 +62,15 @@ struct delete_payload_t {
void (*set_ike_spi)(delete_payload_t *this, u_int64_t spi_i, u_int64_t spi_r);
/**
+ * Get the IKE SPIs from an IKEv1 delete.
+ *
+ * @param spi_i initiator SPI
+ * @param spi_r responder SPI
+ * @return TRUE if SPIs extracted successfully
+ */
+ bool (*get_ike_spi)(delete_payload_t *this, u_int64_t *spi_i, u_int64_t *spi_r);
+
+ /**
* Get an enumerator over the SPIs in network order.
*
* @return enumerator over SPIs, u_int32_t
diff --git a/src/libcharon/encoding/payloads/encrypted_payload.c b/src/libcharon/encoding/payloads/encrypted_payload.c
index 5c574c34d..04372fdf0 100644
--- a/src/libcharon/encoding/payloads/encrypted_payload.c
+++ b/src/libcharon/encoding/payloads/encrypted_payload.c
@@ -561,6 +561,7 @@ static status_t parse(private_encrypted_payload_t *this, chunk_t plain)
payload_type_t type;
parser = parser_create(plain);
+ parser->set_major_version(parser, this->type == PLV1_ENCRYPTED ? 1 : 2);
type = this->next_payload;
while (type != PL_NONE)
{
diff --git a/src/libcharon/encoding/payloads/id_payload.c b/src/libcharon/encoding/payloads/id_payload.c
index a002a8f21..bb8aab748 100644
--- a/src/libcharon/encoding/payloads/id_payload.c
+++ b/src/libcharon/encoding/payloads/id_payload.c
@@ -258,17 +258,20 @@ static traffic_selector_t *get_ts_from_range(private_id_payload_t *this,
static traffic_selector_t *get_ts_from_subnet(private_id_payload_t *this,
ts_type_t type)
{
+ traffic_selector_t *ts;
chunk_t net, netmask;
int i;
net = chunk_create(this->id_data.ptr, this->id_data.len / 2);
- netmask = chunk_skip(this->id_data, this->id_data.len / 2);
+ netmask = chunk_clone(chunk_skip(this->id_data, this->id_data.len / 2));
for (i = 0; i < net.len; i++)
{
netmask.ptr[i] = (netmask.ptr[i] ^ 0xFF) | net.ptr[i];
}
- return traffic_selector_create_from_bytes(this->protocol_id, type,
+ ts = traffic_selector_create_from_bytes(this->protocol_id, type,
net, this->port, netmask, this->port ?: 65535);
+ chunk_free(&netmask);
+ return ts;
}
/**
diff --git a/src/libcharon/encoding/payloads/ke_payload.c b/src/libcharon/encoding/payloads/ke_payload.c
index 4f552d6ac..50fd73f90 100644
--- a/src/libcharon/encoding/payloads/ke_payload.c
+++ b/src/libcharon/encoding/payloads/ke_payload.c
@@ -247,9 +247,15 @@ ke_payload_t *ke_payload_create(payload_type_t type)
ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type,
diffie_hellman_t *dh)
{
- private_ke_payload_t *this = (private_ke_payload_t*)ke_payload_create(type);
+ private_ke_payload_t *this;
+ chunk_t value;
- dh->get_my_public_value(dh, &this->key_exchange_data);
+ if (!dh->get_my_public_value(dh, &value))
+ {
+ return NULL;
+ }
+ this = (private_ke_payload_t*)ke_payload_create(type);
+ this->key_exchange_data = value;
this->dh_group_number = dh->get_dh_group(dh);
this->payload_length += this->key_exchange_data.len;
diff --git a/src/libcharon/encoding/payloads/ke_payload.h b/src/libcharon/encoding/payloads/ke_payload.h
index dfc6308b4..96c5096a5 100644
--- a/src/libcharon/encoding/payloads/ke_payload.h
+++ b/src/libcharon/encoding/payloads/ke_payload.h
@@ -73,7 +73,7 @@ ke_payload_t *ke_payload_create(payload_type_t type);
*
* @param type PLV2_KEY_EXCHANGE or PLV1_KEY_EXCHANGE
* @param dh diffie hellman object containing group and key
- * @return ke_payload_t object
+ * @return ke_payload_t object, NULL on error
*/
ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type,
diffie_hellman_t *dh);
diff --git a/src/libcharon/encoding/payloads/notify_payload.c b/src/libcharon/encoding/payloads/notify_payload.c
index 94723ddd7..f32a1273f 100644
--- a/src/libcharon/encoding/payloads/notify_payload.c
+++ b/src/libcharon/encoding/payloads/notify_payload.c
@@ -65,7 +65,7 @@ ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_
"ME_CONNECT_FAILED");
ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
"MS_NOTIFY_STATUS");
-ENUM_NEXT(notify_type_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY_STATUS,
+ENUM_NEXT(notify_type_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
"INITIAL_CONTACT",
"SET_WINDOW_SIZE",
"ADDITIONAL_TS_POSSIBLE",
@@ -112,8 +112,9 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY
"ERX_SUPPORTED",
"IFOM_CAPABILITY",
"SENDER_REQUEST_ID",
- "FRAGMENTATION_SUPPORTED");
-ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, FRAGMENTATION_SUPPORTED,
+ "FRAGMENTATION_SUPPORTED",
+ "SIGNATURE_HASH_ALGORITHMS");
+ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, SIGNATURE_HASH_ALGORITHMS,
"INITIAL_CONTACT");
ENUM_NEXT(notify_type_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
"DPD_R_U_THERE",
@@ -174,7 +175,7 @@ ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_S
"ME_CONN_FAIL");
ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
"MS_STATUS");
-ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY_STATUS,
+ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
"INIT_CONTACT",
"SET_WINSIZE",
"ADD_TS_POSS",
@@ -221,8 +222,9 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_
"ERX_SUP",
"IFOM_CAP",
"SENDER_REQ_ID",
- "FRAG_SUP");
-ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, FRAGMENTATION_SUPPORTED,
+ "FRAG_SUP",
+ "HASH_ALG");
+ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, SIGNATURE_HASH_ALGORITHMS,
"INITIAL_CONTACT");
ENUM_NEXT(notify_type_short_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
"DPD",
@@ -473,6 +475,14 @@ METHOD(payload_t, verify, status_t,
}
break;
}
+ case SIGNATURE_HASH_ALGORITHMS:
+ {
+ if (this->notify_data.len % 2)
+ {
+ bad_length = TRUE;
+ }
+ break;
+ }
case AUTH_LIFETIME:
{
if (this->notify_data.len != 4)
diff --git a/src/libcharon/encoding/payloads/notify_payload.h b/src/libcharon/encoding/payloads/notify_payload.h
index 25521c2bb..690757383 100644
--- a/src/libcharon/encoding/payloads/notify_payload.h
+++ b/src/libcharon/encoding/payloads/notify_payload.h
@@ -151,6 +151,8 @@ enum notify_type_t {
SENDER_REQUEST_ID = 16429,
/* IKEv2 fragmentation supported, RFC 7383 */
FRAGMENTATION_SUPPORTED = 16430,
+ /* Signature Hash Algorithms, RFC 7427 */
+ SIGNATURE_HASH_ALGORITHMS = 16431,
/* IKEv1 initial contact */
INITIAL_CONTACT_IKEV1 = 24578,
/* IKEv1 DPD */
diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c
index 600b6dd68..a1cd2f945 100644
--- a/src/libcharon/encoding/payloads/payload.c
+++ b/src/libcharon/encoding/payloads/payload.c
@@ -266,37 +266,51 @@ payload_t *payload_create(payload_type_t type)
/**
* See header.
*/
-bool payload_is_known(payload_type_t type)
+bool payload_is_known(payload_type_t type, u_int8_t maj_ver)
{
- if (type == PL_HEADER)
+ if (type >= PL_HEADER)
{
return TRUE;
}
- if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION)
+ switch (maj_ver)
{
- return TRUE;
- }
- if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA)
- {
- return TRUE;
- }
- if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP)
- {
- return TRUE;
- }
- if (type == PLV2_FRAGMENT)
- {
- return TRUE;
- }
+ case 0:
+ case IKEV1_MAJOR_VERSION:
+ if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION)
+ {
+ return TRUE;
+ }
+ if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA)
+ {
+ return TRUE;
+ }
+ if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT)
+ {
+ return TRUE;
+ }
+ if (maj_ver)
+ {
+ break;
+ }
+ /* fall-through */
+ case IKEV2_MAJOR_VERSION:
+ if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP)
+ {
+ return TRUE;
+ }
+ if (type == PLV2_FRAGMENT)
+ {
+ return TRUE;
+ }
#ifdef ME
- if (type == PLV2_ID_PEER)
- {
- return TRUE;
- }
+ if (type == PLV2_ID_PEER)
+ {
+ return TRUE;
+ }
#endif
- if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT)
- {
- return TRUE;
+ break;
+ default:
+ break;
}
return FALSE;
}
diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h
index 036cd422d..920779bd1 100644
--- a/src/libcharon/encoding/payloads/payload.h
+++ b/src/libcharon/encoding/payloads/payload.h
@@ -405,9 +405,10 @@ payload_t *payload_create(payload_type_t type);
* Check if a specific payload is implemented, or handled as unknown payload.
*
* @param type type of the payload to check
+ * @param maj_ver major IKE version (use 0 to skip version check)
* @return FALSE if payload type handled as unknown payload
*/
-bool payload_is_known(payload_type_t type);
+bool payload_is_known(payload_type_t type, u_int8_t maj_ver);
/**
* Get the value field in a payload using encoding rules.
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index 53e8cf3ad..48dcfeb24 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2014 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -224,26 +224,7 @@ typedef enum {
/* FreeS/WAN proprietary */
IKEV1_ESP_ENCR_SERPENT = 252,
IKEV1_ESP_ENCR_TWOFISH = 253,
-} ikev1_esp_encr_transid_t;
-
-/**
- * IKEv1 Transform ID ESP authentication algorithm.
- */
-typedef enum {
- IKEV1_ESP_AUTH_HMAC_MD5 = 1,
- IKEV1_ESP_AUTH_HMAC_SHA = 2,
- IKEV1_ESP_AUTH_DES_MAC = 3,
- IKEV1_ESP_AUTH_KPDK = 4,
- IKEV1_ESP_AUTH_HMAC_SHA2_256 = 5,
- IKEV1_ESP_AUTH_HMAC_SHA2_384 = 6,
- IKEV1_ESP_AUTH_HMAC_SHA2_512 = 7,
- IKEV1_ESP_AUTH_HMAC_RIPEMD = 8,
- IKEV1_ESP_AUTH_AES_XCBC_MAC = 9,
- IKEV1_ESP_AUTH_SIG_RSA = 10,
- IKEV1_ESP_AUTH_AES_128_GMAC = 11,
- IKEV1_ESP_AUTH_AES_192_GMAC = 12,
- IKEV1_ESP_AUTH_AES_256_GMAC = 13,
-} ikev1_esp_auth_transid_it;
+} ikev1_esp_transid_t;
/**
* IKEv1 Transform ID AH authentication algorithm.
@@ -264,6 +245,25 @@ typedef enum {
} ikev1_ah_transid_t;
/**
+ * IKEv1 authentication algorithm.
+ */
+typedef enum {
+ IKEV1_AUTH_HMAC_MD5 = 1,
+ IKEV1_AUTH_HMAC_SHA = 2,
+ IKEV1_AUTH_DES_MAC = 3,
+ IKEV1_AUTH_KPDK = 4,
+ IKEV1_AUTH_HMAC_SHA2_256 = 5,
+ IKEV1_AUTH_HMAC_SHA2_384 = 6,
+ IKEV1_AUTH_HMAC_SHA2_512 = 7,
+ IKEV1_AUTH_HMAC_RIPEMD = 8,
+ IKEV1_AUTH_AES_XCBC_MAC = 9,
+ IKEV1_AUTH_SIG_RSA = 10,
+ IKEV1_AUTH_AES_128_GMAC = 11,
+ IKEV1_AUTH_AES_192_GMAC = 12,
+ IKEV1_AUTH_AES_256_GMAC = 13,
+} ikev1_auth_algo_t;
+
+/**
* IKEv1 ESP Encapsulation mode.
*/
typedef enum {
@@ -345,7 +345,7 @@ METHOD(payload_t, verify, status_t,
switch (this->protocol_id)
{
case PROTO_IPCOMP:
- if (this->spi.len != 2)
+ if (this->spi.len != 2 && this->spi.len != 4)
{
DBG1(DBG_ENC, "invalid CPI length in IPCOMP proposal");
return FAILED;
@@ -536,7 +536,7 @@ METHOD(proposal_substructure_t, get_cpi, bool,
{
if (cpi)
{
- *cpi = *((u_int16_t*)this->spi.ptr);
+ *cpi = htons(untoh16(this->spi.ptr + this->spi.len - 2));
}
enumerator->destroy(enumerator);
return TRUE;
@@ -620,7 +620,7 @@ static algo_map_t map_prf[] = {
/**
* ESP encryption algorithm mapping
*/
-static algo_map_t map_esp_encr[] = {
+static algo_map_t map_esp[] = {
{ IKEV1_ESP_ENCR_DES_IV64, ENCR_DES_IV64 },
{ IKEV1_ESP_ENCR_DES, ENCR_DES },
{ IKEV1_ESP_ENCR_3DES, ENCR_3DES },
@@ -646,23 +646,6 @@ static algo_map_t map_esp_encr[] = {
};
/**
- * ESP authentication algorithm mapping
- */
-static algo_map_t map_esp_auth[] = {
- { IKEV1_ESP_AUTH_HMAC_MD5, AUTH_HMAC_MD5_96 },
- { IKEV1_ESP_AUTH_HMAC_SHA, AUTH_HMAC_SHA1_96 },
- { IKEV1_ESP_AUTH_DES_MAC, AUTH_DES_MAC },
- { IKEV1_ESP_AUTH_KPDK, AUTH_KPDK_MD5 },
- { IKEV1_ESP_AUTH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 },
- { IKEV1_ESP_AUTH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 },
- { IKEV1_ESP_AUTH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 },
- { IKEV1_ESP_AUTH_AES_XCBC_MAC, AUTH_AES_XCBC_96 },
- { IKEV1_ESP_AUTH_AES_128_GMAC, AUTH_AES_128_GMAC },
- { IKEV1_ESP_AUTH_AES_192_GMAC, AUTH_AES_192_GMAC },
- { IKEV1_ESP_AUTH_AES_256_GMAC, AUTH_AES_256_GMAC },
-};
-
-/**
* AH authentication algorithm mapping
*/
static algo_map_t map_ah[] = {
@@ -679,34 +662,30 @@ static algo_map_t map_ah[] = {
};
/**
- * Get IKEv2 algorithm from IKEv1 identifier
+ * ESP/AH authentication algorithm mapping
*/
-static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
+static algo_map_t map_auth[] = {
+ { IKEV1_AUTH_HMAC_MD5, AUTH_HMAC_MD5_96 },
+ { IKEV1_AUTH_HMAC_SHA, AUTH_HMAC_SHA1_96 },
+ { IKEV1_AUTH_DES_MAC, AUTH_DES_MAC },
+ { IKEV1_AUTH_KPDK, AUTH_KPDK_MD5 },
+ { IKEV1_AUTH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 },
+ { IKEV1_AUTH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 },
+ { IKEV1_AUTH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 },
+ { IKEV1_AUTH_AES_XCBC_MAC, AUTH_AES_XCBC_96 },
+ { IKEV1_AUTH_AES_128_GMAC, AUTH_AES_128_GMAC },
+ { IKEV1_AUTH_AES_192_GMAC, AUTH_AES_192_GMAC },
+ { IKEV1_AUTH_AES_256_GMAC, AUTH_AES_256_GMAC },
+};
+
+/**
+ * Map an IKEv1 to an IKEv2 identifier
+ */
+static u_int16_t ikev2_from_ikev1(algo_map_t *map, int count, u_int16_t def,
+ u_int16_t value)
{
- algo_map_t *map;
- u_int16_t def;
- int i, count;
+ int i;
- switch (type)
- {
- case ENCRYPTION_ALGORITHM:
- map = map_encr;
- count = countof(map_encr);
- def = ENCR_UNDEFINED;
- break;
- case INTEGRITY_ALGORITHM:
- map = map_integ;
- count = countof(map_integ);
- def = AUTH_UNDEFINED;
- break;
- case PSEUDO_RANDOM_FUNCTION:
- map = map_prf;
- count = countof(map_prf);
- def = PRF_UNDEFINED;
- break;
- default:
- return 0;
- }
for (i = 0; i < count; i++)
{
if (map[i].ikev1 == value)
@@ -718,30 +697,12 @@ static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
}
/**
- * Get IKEv1 algorithm from IKEv2 identifier
+ * Map an IKEv2 to an IKEv1 identifier
*/
-static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
+static u_int16_t ikev1_from_ikev2(algo_map_t *map, int count, u_int16_t value)
{
- algo_map_t *map;
- int i, count;
+ int i;
- switch (type)
- {
- case ENCRYPTION_ALGORITHM:
- map = map_encr;
- count = countof(map_encr);
- break;
- case INTEGRITY_ALGORITHM:
- map = map_integ;
- count = countof(map_integ);
- break;
- case PSEUDO_RANDOM_FUNCTION:
- map = map_prf;
- count = countof(map_prf);
- break;
- default:
- return 0;
- }
for (i = 0; i < count; i++)
{
if (map[i].ikev2 == value)
@@ -753,87 +714,96 @@ static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
}
/**
- * Get IKEv2 algorithm from IKEv1 ESP transaction ID
+ * Get IKEv2 algorithm from IKEv1 identifier
*/
-static u_int16_t get_alg_from_ikev1_transid(protocol_id_t proto,
- transform_type_t type, u_int16_t value)
+static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
{
- algo_map_t *map;
- u_int16_t def;
- int i, count;
-
switch (type)
{
case ENCRYPTION_ALGORITHM:
- map = map_esp_encr;
- count = countof(map_esp_encr);
- def = ENCR_UNDEFINED;
- break;
+ return ikev2_from_ikev1(map_encr, countof(map_encr),
+ ENCR_UNDEFINED, value);
case INTEGRITY_ALGORITHM:
- if (proto == PROTO_ESP)
- {
- map = map_esp_auth;
- count = countof(map_esp_auth);
- }
- else
- {
- map = map_ah;
- count = countof(map_ah);
- }
- def = AUTH_UNDEFINED;
- break;
+ return ikev2_from_ikev1(map_integ, countof(map_integ),
+ AUTH_UNDEFINED, value);
+ case PSEUDO_RANDOM_FUNCTION:
+ return ikev2_from_ikev1(map_prf, countof(map_prf),
+ PRF_UNDEFINED, value);
default:
return 0;
}
- for (i = 0; i < count; i++)
+}
+
+/**
+ * Get IKEv1 algorithm from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
+{
+ switch (type)
{
- if (map[i].ikev1 == value)
- {
- return map[i].ikev2;
- }
+ case ENCRYPTION_ALGORITHM:
+ return ikev1_from_ikev2(map_encr, countof(map_encr), value);
+ case INTEGRITY_ALGORITHM:
+ return ikev1_from_ikev2(map_integ, countof(map_integ), value);
+ case PSEUDO_RANDOM_FUNCTION:
+ return ikev1_from_ikev2(map_prf, countof(map_prf), value);
+ default:
+ return 0;
}
- return def;
}
/**
- * Get IKEv1 ESP/AH transaction ID from IKEv2 identifier
+ * Get IKEv2 algorithm from IKEv1 ESP/AH transform ID
*/
-static u_int16_t get_ikev1_transid_from_alg(protocol_id_t proto,
- transform_type_t type, u_int16_t value)
+static u_int16_t get_alg_from_ikev1_transid(transform_type_t type,
+ u_int16_t value)
{
- algo_map_t *map;
- int i, count;
-
switch (type)
{
case ENCRYPTION_ALGORITHM:
- map = map_esp_encr;
- count = countof(map_esp_encr);
- break;
+ return ikev2_from_ikev1(map_esp, countof(map_esp),
+ ENCR_UNDEFINED, value);
case INTEGRITY_ALGORITHM:
- if (proto == PROTO_ESP)
- {
- map = map_esp_auth;
- count = countof(map_esp_auth);
- }
- else
- {
- map = map_ah;
- count = countof(map_ah);
- }
- break;
+ return ikev2_from_ikev1(map_ah, countof(map_ah),
+ AUTH_UNDEFINED, value);
default:
return 0;
}
- for (i = 0; i < count; i++)
+}
+
+/**
+ * Get IKEv1 ESP/AH transform ID from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_transid_from_alg(transform_type_t type,
+ u_int16_t value)
+{
+ switch (type)
{
- if (map[i].ikev2 == value)
- {
- return map[i].ikev1;
- }
+ case ENCRYPTION_ALGORITHM:
+ return ikev1_from_ikev2(map_esp, countof(map_esp), value);
+ case INTEGRITY_ALGORITHM:
+ return ikev1_from_ikev2(map_ah, countof(map_ah), value);
+ default:
+ return 0;
}
- return 0;
}
+
+/**
+ * Get IKEv1 authentication algorithm from IKEv2 identifier
+ */
+static u_int16_t get_alg_from_ikev1_auth(u_int16_t value)
+{
+ return ikev2_from_ikev1(map_auth, countof(map_auth), AUTH_UNDEFINED, value);
+}
+
+/**
+ * Get IKEv1 authentication algorithm from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_auth_from_alg(u_int16_t value)
+{
+ return ikev1_from_ikev2(map_auth, countof(map_auth), value);
+}
+
/**
* Get IKEv1 authentication attribute from auth_method_t
*/
@@ -971,8 +941,7 @@ static void add_to_proposal_v1(proposal_t *proposal,
break;
case TATTR_PH2_AUTH_ALGORITHM:
proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM,
- get_alg_from_ikev1_transid(proto, INTEGRITY_ALGORITHM,
- value), 0);
+ get_alg_from_ikev1_auth(value), 0);
break;
case TATTR_PH2_GROUP:
proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
@@ -989,7 +958,7 @@ static void add_to_proposal_v1(proposal_t *proposal,
NO_EXT_SEQ_NUMBERS, 0);
if (proto == PROTO_ESP)
{
- encr = get_alg_from_ikev1_transid(proto, ENCRYPTION_ALGORITHM,
+ encr = get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM,
transform->get_transform_id(transform));
if (encr)
{
@@ -1354,19 +1323,17 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this,
ipsec_mode_t mode, encap_t udp, int number)
{
transform_substructure_t *transform = NULL;
- u_int16_t alg, key_size;
+ u_int16_t alg, transid, key_size;
enumerator_t *enumerator;
- protocol_id_t proto;
- proto = proposal->get_protocol(proposal);
enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
if (enumerator->enumerate(enumerator, &alg, &key_size))
{
- alg = get_ikev1_transid_from_alg(proto, ENCRYPTION_ALGORITHM, alg);
- if (alg)
+ transid = get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM, alg);
+ if (transid)
{
transform = transform_substructure_create_type(
- PLV1_TRANSFORM_SUBSTRUCTURE, number, alg);
+ PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
if (key_size)
{
transform->add_transform_attribute(transform,
@@ -1380,13 +1347,14 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this,
enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM);
if (enumerator->enumerate(enumerator, &alg, &key_size))
{
- alg = get_ikev1_transid_from_alg(proto, INTEGRITY_ALGORITHM, alg);
- if (alg)
+ transid = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg);
+ alg = get_ikev1_auth_from_alg(alg);
+ if (transid && alg)
{
if (!transform)
{
transform = transform_substructure_create_type(
- PLV1_TRANSFORM_SUBSTRUCTURE, number, alg);
+ PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
}
transform->add_transform_attribute(transform,
transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c
index 059124e35..9c0e2602b 100644
--- a/src/libcharon/kernel/kernel_handler.c
+++ b/src/libcharon/kernel/kernel_handler.c
@@ -72,36 +72,39 @@ METHOD(kernel_listener_t, acquire, bool,
}
METHOD(kernel_listener_t, expire, bool,
- private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol,
- u_int32_t spi, bool hard)
+ private_kernel_handler_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard)
{
protocol_id_t proto = proto_ip2ike(protocol);
- DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}",
- hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), reqid);
+ DBG1(DBG_KNL, "creating %s job for CHILD_SA %N/0x%08x/%H",
+ hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), dst);
if (hard)
{
lib->processor->queue_job(lib->processor,
- (job_t*)delete_child_sa_job_create(reqid, proto, spi, hard));
+ (job_t*)delete_child_sa_job_create(proto, spi, dst, hard));
}
else
{
lib->processor->queue_job(lib->processor,
- (job_t*)rekey_child_sa_job_create(reqid, proto, spi));
+ (job_t*)rekey_child_sa_job_create(proto, spi, dst));
}
return TRUE;
}
METHOD(kernel_listener_t, mapping, bool,
- private_kernel_handler_t *this, u_int32_t reqid, u_int32_t spi,
- host_t *remote)
+ private_kernel_handler_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, host_t *remote)
{
- DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and reqid {%u} "
- "changed, queuing update job", ntohl(spi), reqid);
+ protocol_id_t proto = proto_ip2ike(protocol);
+
+ DBG1(DBG_KNL, "NAT mappings of CHILD_SA %N/0x%08x/%H changed to %#H, "
+ "queuing update job", protocol_id_names, proto, ntohl(spi), dst,
+ remote);
lib->processor->queue_job(lib->processor,
- (job_t*)update_sa_job_create(reqid, remote));
+ (job_t*)update_sa_job_create(proto, spi, dst, remote));
return TRUE;
}
diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in
index c3b014c3c..0554465b9 100644
--- a/src/libcharon/plugins/addrblock/Makefile.in
+++ b/src/libcharon/plugins/addrblock/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/android_dns/Makefile.in b/src/libcharon/plugins/android_dns/Makefile.in
index 50594a452..58cf97b6e 100644
--- a/src/libcharon/plugins/android_dns/Makefile.in
+++ b/src/libcharon/plugins/android_dns/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/android_dns/android_dns_handler.c b/src/libcharon/plugins/android_dns/android_dns_handler.c
index 526810355..160a145d3 100644
--- a/src/libcharon/plugins/android_dns/android_dns_handler.c
+++ b/src/libcharon/plugins/android_dns/android_dns_handler.c
@@ -128,7 +128,7 @@ static bool set_dns_server(private_android_dns_handler_t *this, int index,
}
METHOD(attribute_handler_t, handle, bool,
- private_android_dns_handler_t *this, identification_t *id,
+ private_android_dns_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
switch (type)
@@ -158,7 +158,7 @@ METHOD(attribute_handler_t, handle, bool,
}
METHOD(attribute_handler_t, release, void,
- private_android_dns_handler_t *this, identification_t *server,
+ private_android_dns_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
if (type == INTERNAL_IP4_DNS)
@@ -192,7 +192,7 @@ METHOD(enumerator_t, enumerate_dns, bool,
}
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
- private_android_dns_handler_t *this, identification_t *id,
+ private_android_dns_handler_t *this, ike_sa_t *ike_sa,
linked_list_t *vips)
{
enumerator_t *enumerator;
@@ -232,4 +232,3 @@ android_dns_handler_t *android_dns_handler_create()
return &this->public;
}
-
diff --git a/src/libcharon/plugins/android_dns/android_dns_plugin.c b/src/libcharon/plugins/android_dns/android_dns_plugin.c
index b8eb11b57..9b6ec0dba 100644
--- a/src/libcharon/plugins/android_dns/android_dns_plugin.c
+++ b/src/libcharon/plugins/android_dns/android_dns_plugin.c
@@ -16,7 +16,6 @@
#include "android_dns_plugin.h"
#include "android_dns_handler.h"
-#include <hydra.h>
#include <daemon.h>
typedef struct private_android_dns_plugin_t private_android_dns_plugin_t;
@@ -51,13 +50,13 @@ static bool plugin_cb(private_android_dns_plugin_t *this,
{
if (reg)
{
- hydra->attributes->add_handler(hydra->attributes,
- &this->handler->handler);
+ charon->attributes->add_handler(charon->attributes,
+ &this->handler->handler);
}
else
{
- hydra->attributes->remove_handler(hydra->attributes,
- &this->handler->handler);
+ charon->attributes->remove_handler(charon->attributes,
+ &this->handler->handler);
}
return TRUE;
}
diff --git a/src/libcharon/plugins/android_log/Makefile.in b/src/libcharon/plugins/android_log/Makefile.in
index 700a4219c..8ce92e577 100644
--- a/src/libcharon/plugins/android_log/Makefile.in
+++ b/src/libcharon/plugins/android_log/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/attr/Makefile.am b/src/libcharon/plugins/attr/Makefile.am
new file mode 100644
index 000000000..6bc7e77d8
--- /dev/null
+++ b/src/libcharon/plugins/attr/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-attr.la
+else
+plugin_LTLIBRARIES = libstrongswan-attr.la
+endif
+
+libstrongswan_attr_la_SOURCES = \
+ attr_plugin.h attr_plugin.c \
+ attr_provider.h attr_provider.c
+
+libstrongswan_attr_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/attr/Makefile.in b/src/libcharon/plugins/attr/Makefile.in
new file mode 100644
index 000000000..486b3c0b0
--- /dev/null
+++ b/src/libcharon/plugins/attr/Makefile.in
@@ -0,0 +1,777 @@
+# 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/attr
+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_attr_la_LIBADD =
+am_libstrongswan_attr_la_OBJECTS = attr_plugin.lo attr_provider.lo
+libstrongswan_attr_la_OBJECTS = $(am_libstrongswan_attr_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_attr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_attr_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_attr_la_rpath = -rpath $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_attr_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_attr_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_attr_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_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-attr.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-attr.la
+libstrongswan_attr_la_SOURCES = \
+ attr_plugin.h attr_plugin.c \
+ attr_provider.h attr_provider.c
+
+libstrongswan_attr_la_LDFLAGS = -module -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/attr/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/attr/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-attr.la: $(libstrongswan_attr_la_OBJECTS) $(libstrongswan_attr_la_DEPENDENCIES) $(EXTRA_libstrongswan_attr_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_attr_la_LINK) $(am_libstrongswan_attr_la_rpath) $(libstrongswan_attr_la_OBJECTS) $(libstrongswan_attr_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_provider.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/attr/attr_plugin.c b/src/libcharon/plugins/attr/attr_plugin.c
new file mode 100644
index 000000000..9b15c3cc9
--- /dev/null
+++ b/src/libcharon/plugins/attr/attr_plugin.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "attr_plugin.h"
+#include "attr_provider.h"
+
+#include <daemon.h>
+
+typedef struct private_attr_plugin_t private_attr_plugin_t;
+
+/**
+ * private data of attr plugin
+ */
+struct private_attr_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ attr_plugin_t public;
+
+ /**
+ * CFG attributes provider
+ */
+ attr_provider_t *provider;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_attr_plugin_t *this)
+{
+ return "attr";
+}
+
+/**
+ * Register provider
+ */
+static bool plugin_cb(private_attr_plugin_t *this,
+ plugin_feature_t *feature, bool reg, void *cb_data)
+{
+ if (reg)
+ {
+ charon->attributes->add_provider(charon->attributes,
+ &this->provider->provider);
+ }
+ else
+ {
+ charon->attributes->remove_provider(charon->attributes,
+ &this->provider->provider);
+ }
+ return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_attr_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "attr"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, reload, bool,
+ private_attr_plugin_t *this)
+{
+ this->provider->reload(this->provider);
+ return TRUE;
+}
+
+METHOD(plugin_t, destroy, void,
+ private_attr_plugin_t *this)
+{
+ this->provider->destroy(this->provider);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *attr_plugin_create()
+{
+ private_attr_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .reload = _reload,
+ .destroy = _destroy,
+ },
+ },
+ .provider = attr_provider_create(),
+ );
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/unit_tester/tests.h b/src/libcharon/plugins/attr/attr_plugin.h
index 169292e9b..0c6eebfa7 100644
--- a/src/libcharon/plugins/unit_tester/tests.h
+++ b/src/libcharon/plugins/attr/attr_plugin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,17 +14,29 @@
*/
/**
- * @defgroup tests tests
- * @{ @ingroup unit_tester
+ * @defgroup attr attr
+ * @ingroup cplugins
+ *
+ * @defgroup attr_plugin attr_plugin
+ * @{ @ingroup attr
+ */
+
+#ifndef ATTR_PLUGIN_H_
+#define ATTR_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct attr_plugin_t attr_plugin_t;
+
+/**
+ * Plugin providing configuration attribute through strongswan.conf.
*/
+struct attr_plugin_t {
-DEFINE_TEST("auth cfg", test_auth_cfg, FALSE)
-DEFINE_TEST("CURL get", test_curl_get, FALSE)
-DEFINE_TEST("MySQL operations", test_mysql, FALSE)
-DEFINE_TEST("SQLite operations", test_sqlite, FALSE)
-DEFINE_TEST("X509 certificate", test_cert_x509, FALSE)
-DEFINE_TEST("Mediation database key fetch", test_med_db, FALSE)
-DEFINE_TEST("IP pool", test_pool, FALSE)
-DEFINE_TEST("SSH agent", test_agent, FALSE)
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
-/** @}*/
+#endif /** ATTR_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/attr/attr_provider.c b/src/libcharon/plugins/attr/attr_provider.c
new file mode 100644
index 000000000..cac0ae4bf
--- /dev/null
+++ b/src/libcharon/plugins/attr/attr_provider.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "attr_provider.h"
+
+#include <time.h>
+
+#include <daemon.h>
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+#include <threading/rwlock.h>
+
+#define SERVER_MAX 2
+
+typedef struct private_attr_provider_t private_attr_provider_t;
+typedef struct attribute_entry_t attribute_entry_t;
+
+/**
+ * private data of attr_provider
+ */
+struct private_attr_provider_t {
+
+ /**
+ * public functions
+ */
+ attr_provider_t public;
+
+ /**
+ * List of attributes, attribute_entry_t
+ */
+ linked_list_t *attributes;
+
+ /**
+ * Lock for attribute list
+ */
+ rwlock_t *lock;
+};
+
+struct attribute_entry_t {
+ /** type of attribute */
+ configuration_attribute_type_t type;
+ /** attribute value */
+ chunk_t value;
+};
+
+/**
+ * Destroy an entry
+ */
+static void attribute_destroy(attribute_entry_t *this)
+{
+ free(this->value.ptr);
+ free(this);
+}
+
+/**
+ * convert enumerator value from attribute_entry
+ */
+static bool attr_enum_filter(void *null, attribute_entry_t **in,
+ configuration_attribute_type_t *type, void* none, chunk_t *value)
+{
+ *type = (*in)->type;
+ *value = (*in)->value;
+ return TRUE;
+}
+
+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)
+{
+ if (vips->get_count(vips))
+ {
+ 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);
+ }
+ return enumerator_create_empty();
+}
+
+METHOD(attr_provider_t, destroy, void,
+ private_attr_provider_t *this)
+{
+ this->attributes->destroy_function(this->attributes,
+ (void*)attribute_destroy);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/**
+ * Add an attribute entry to the list
+ */
+static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
+ configuration_attribute_type_t type)
+{
+ attribute_entry_t *entry;
+ host_t *host;
+ char *str;
+
+ str = lib->settings->get_str(lib->settings, "%s.%s%d", NULL, lib->ns,
+ key, nr);
+ if (str)
+ {
+ host = host_create_from_string(str, 0);
+ if (host)
+ {
+ entry = malloc_thing(attribute_entry_t);
+
+ if (host->get_family(host) == AF_INET6)
+ {
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ type = INTERNAL_IP6_DNS;
+ break;
+ case INTERNAL_IP4_NBNS:
+ type = INTERNAL_IP6_NBNS;
+ break;
+ default:
+ break;
+ }
+ }
+ entry->type = type;
+ entry->value = chunk_clone(host->get_address(host));
+ host->destroy(host);
+ DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
+ configuration_attribute_type_names, entry->type, &entry->value);
+ this->attributes->insert_last(this->attributes, entry);
+ }
+ }
+}
+
+/**
+ * Key to attribute type mappings, for v4 and v6 attributes
+ */
+typedef struct {
+ char *name;
+ configuration_attribute_type_t v4;
+ configuration_attribute_type_t v6;
+} 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},
+};
+
+/**
+ * Load (numerical) entries from the plugins.attr namespace
+ */
+static void load_entries(private_attr_provider_t *this)
+{
+ enumerator_t *enumerator, *tokens;
+ char *key, *value, *token;
+ int i;
+
+ for (i = 1; i <= SERVER_MAX; i++)
+ {
+ add_legacy_entry(this, "dns", i, INTERNAL_IP4_DNS);
+ add_legacy_entry(this, "nbns", i, INTERNAL_IP4_NBNS);
+ }
+
+ enumerator = lib->settings->create_key_value_enumerator(lib->settings,
+ "%s.plugins.attr", lib->ns);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ configuration_attribute_type_t type;
+ attribute_type_key_t *mapped = NULL;
+ attribute_entry_t *entry;
+ chunk_t data;
+ host_t *host;
+ char *pos;
+ int i, mask = -1, family;
+
+ if (streq(key, "load"))
+ {
+ continue;
+ }
+ type = atoi(key);
+ if (!type)
+ {
+ for (i = 0; i < countof(keys); i++)
+ {
+ if (streq(key, keys[i].name))
+ {
+ mapped = &keys[i];
+ break;
+ }
+ }
+ if (!mapped)
+ {
+ DBG1(DBG_CFG, "mapping attribute type %s failed", key);
+ continue;
+ }
+ }
+ tokens = enumerator_create_token(value, ",", " ");
+ while (tokens->enumerate(tokens, &token))
+ {
+ pos = strchr(token, '/');
+ if (pos)
+ {
+ *(pos++) = '\0';
+ mask = atoi(pos);
+ }
+ host = host_create_from_string(token, 0);
+ if (!host)
+ {
+ if (mapped)
+ {
+ DBG1(DBG_CFG, "invalid host in key %s: %s", key, token);
+ continue;
+ }
+ /* store numeric attributes that are no IP addresses as strings */
+ data = chunk_clone(chunk_from_str(token));
+ }
+ else
+ {
+ family = host->get_family(host);
+ if (mask == -1)
+ {
+ data = chunk_clone(host->get_address(host));
+ }
+ else
+ {
+ if (family == AF_INET)
+ { /* IPv4 attributes contain a subnet mask */
+ u_int32_t netmask = 0;
+
+ if (mask)
+ { /* shifting u_int32_t by 32 or more is undefined */
+ mask = 32 - mask;
+ netmask = htonl((0xFFFFFFFF >> mask) << mask);
+ }
+ data = chunk_cat("cc", host->get_address(host),
+ chunk_from_thing(netmask));
+ }
+ else
+ { /* IPv6 addresses the prefix only */
+ data = chunk_cat("cc", host->get_address(host),
+ chunk_from_chars(mask));
+ }
+ }
+ host->destroy(host);
+ if (mapped)
+ {
+ switch (family)
+ {
+ case AF_INET:
+ type = mapped->v4;
+ break;
+ case AF_INET6:
+ type = mapped->v6;
+ break;
+ }
+ }
+ }
+ INIT(entry,
+ .type = type,
+ .value = data,
+ );
+ DBG2(DBG_CFG, "loaded attribute %N: %#B",
+ configuration_attribute_type_names, entry->type, &entry->value);
+ this->attributes->insert_last(this->attributes, entry);
+ }
+ tokens->destroy(tokens);
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(attr_provider_t, reload, void,
+ private_attr_provider_t *this)
+{
+ this->lock->write_lock(this->lock);
+
+ this->attributes->destroy_function(this->attributes, (void*)attribute_destroy);
+ this->attributes = linked_list_create();
+
+ load_entries(this);
+
+ DBG1(DBG_CFG, "loaded %d entr%s for attr plugin configuration",
+ this->attributes->get_count(this->attributes),
+ this->attributes->get_count(this->attributes) == 1 ? "y" : "ies");
+
+ this->lock->unlock(this->lock);
+}
+
+/*
+ * see header file
+ */
+attr_provider_t *attr_provider_create(database_t *db)
+{
+ private_attr_provider_t *this;
+
+ INIT(this,
+ .public = {
+ .provider = {
+ .acquire_address = (void*)return_null,
+ .release_address = (void*)return_false,
+ .create_attribute_enumerator = _create_attribute_enumerator,
+ },
+ .reload = _reload,
+ .destroy = _destroy,
+ },
+ .attributes = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ load_entries(this);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/attr/attr_provider.h b/src/libcharon/plugins/attr/attr_provider.h
new file mode 100644
index 000000000..17db30408
--- /dev/null
+++ b/src/libcharon/plugins/attr/attr_provider.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attr_provider attr_provider
+ * @{ @ingroup attr
+ */
+
+#ifndef ATTR_PROVIDER_H_
+#define ATTR_PROVIDER_H_
+
+#include <attributes/attribute_provider.h>
+
+typedef struct attr_provider_t attr_provider_t;
+
+/**
+ * Provide configuration attributes through static strongswan.conf definition.
+ */
+struct attr_provider_t {
+
+ /**
+ * Implements attribute provider interface
+ */
+ attribute_provider_t provider;
+
+ /**
+ * Reload configuration from strongswan.conf.
+ */
+ void (*reload)(attr_provider_t *this);
+
+ /**
+ * Destroy a attr_provider instance.
+ */
+ void (*destroy)(attr_provider_t *this);
+};
+
+/**
+ * Create a attr_provider instance.
+ */
+attr_provider_t *attr_provider_create();
+
+#endif /** ATTR_PROVIDER @}*/
diff --git a/src/libcharon/plugins/attr_sql/Makefile.am b/src/libcharon/plugins/attr_sql/Makefile.am
new file mode 100644
index 000000000..366c902f7
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/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-attr-sql.la
+else
+plugin_LTLIBRARIES = libstrongswan-attr-sql.la
+endif
+
+libstrongswan_attr_sql_la_SOURCES = \
+ attr_sql_plugin.h attr_sql_plugin.c \
+ attr_sql_provider.h attr_sql_provider.c
+
+libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/attr_sql/Makefile.in
index 1aca319c7..8f1b3c0ff 100644
--- a/src/libcharon/plugins/unit_tester/Makefile.in
+++ b/src/libcharon/plugins/attr_sql/Makefile.in
@@ -78,7 +78,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/libcharon/plugins/unit_tester
+subdir = src/libcharon/plugins/attr_sql
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -127,25 +127,22 @@ am__uninstall_files_from_dir = { \
}
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_unit_tester_la_LIBADD =
-am__dirstamp = $(am__leading_dot)dirstamp
-am_libstrongswan_unit_tester_la_OBJECTS = unit_tester.lo \
- tests/test_auth_info.lo tests/test_curl.lo tests/test_mysql.lo \
- tests/test_sqlite.lo tests/test_cert.lo tests/test_med_db.lo \
- tests/test_pool.lo tests/test_agent.lo
-libstrongswan_unit_tester_la_OBJECTS = \
- $(am_libstrongswan_unit_tester_la_OBJECTS)
+libstrongswan_attr_sql_la_LIBADD =
+am_libstrongswan_attr_sql_la_OBJECTS = attr_sql_plugin.lo \
+ attr_sql_provider.lo
+libstrongswan_attr_sql_la_OBJECTS = \
+ $(am_libstrongswan_attr_sql_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_unit_tester_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+libstrongswan_attr_sql_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_unit_tester_la_LDFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_attr_sql_la_LDFLAGS) \
$(LDFLAGS) -o $@
-@MONOLITHIC_FALSE@am_libstrongswan_unit_tester_la_rpath = -rpath \
+@MONOLITHIC_FALSE@am_libstrongswan_attr_sql_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
-@MONOLITHIC_TRUE@am_libstrongswan_unit_tester_la_rpath =
+@MONOLITHIC_TRUE@am_libstrongswan_attr_sql_la_rpath =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -180,8 +177,8 @@ 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_unit_tester_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_unit_tester_la_SOURCES)
+SOURCES = $(libstrongswan_attr_sql_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_attr_sql_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -232,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -292,10 +290,12 @@ 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@
@@ -369,6 +369,8 @@ 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@
@@ -435,20 +437,13 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
$(PLUGIN_CFLAGS)
-@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-unit-tester.la
-@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-unit-tester.la
-libstrongswan_unit_tester_la_SOURCES = \
- unit_tester.c unit_tester.h tests.h \
- tests/test_auth_info.c \
- tests/test_curl.c \
- tests/test_mysql.c \
- tests/test_sqlite.c \
- tests/test_cert.c \
- tests/test_med_db.c \
- tests/test_pool.c \
- tests/test_agent.c
-
-libstrongswan_unit_tester_la_LDFLAGS = -module -avoid-version
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-attr-sql.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-attr-sql.la
+libstrongswan_attr_sql_la_SOURCES = \
+ attr_sql_plugin.h attr_sql_plugin.c \
+ attr_sql_provider.h attr_sql_provider.c
+
+libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version
all: all-am
.SUFFIXES:
@@ -462,9 +457,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/unit_tester/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/attr_sql/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libcharon/plugins/unit_tester/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/attr_sql/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -529,49 +524,18 @@ clean-pluginLTLIBRARIES:
echo rm -f $${locs}; \
rm -f $${locs}; \
}
-tests/$(am__dirstamp):
- @$(MKDIR_P) tests
- @: > tests/$(am__dirstamp)
-tests/$(DEPDIR)/$(am__dirstamp):
- @$(MKDIR_P) tests/$(DEPDIR)
- @: > tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_auth_info.lo: tests/$(am__dirstamp) \
- tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_curl.lo: tests/$(am__dirstamp) \
- tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_mysql.lo: tests/$(am__dirstamp) \
- tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_sqlite.lo: tests/$(am__dirstamp) \
- tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_cert.lo: tests/$(am__dirstamp) \
- tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_med_db.lo: tests/$(am__dirstamp) \
- tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_pool.lo: tests/$(am__dirstamp) \
- tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_agent.lo: tests/$(am__dirstamp) \
- tests/$(DEPDIR)/$(am__dirstamp)
-
-libstrongswan-unit-tester.la: $(libstrongswan_unit_tester_la_OBJECTS) $(libstrongswan_unit_tester_la_DEPENDENCIES) $(EXTRA_libstrongswan_unit_tester_la_DEPENDENCIES)
- $(AM_V_CCLD)$(libstrongswan_unit_tester_la_LINK) $(am_libstrongswan_unit_tester_la_rpath) $(libstrongswan_unit_tester_la_OBJECTS) $(libstrongswan_unit_tester_la_LIBADD) $(LIBS)
+
+libstrongswan-attr-sql.la: $(libstrongswan_attr_sql_la_OBJECTS) $(libstrongswan_attr_sql_la_DEPENDENCIES) $(EXTRA_libstrongswan_attr_sql_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_attr_sql_la_LINK) $(am_libstrongswan_attr_sql_la_rpath) $(libstrongswan_attr_sql_la_OBJECTS) $(libstrongswan_attr_sql_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
- -rm -f tests/*.$(OBJEXT)
- -rm -f tests/*.lo
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit_tester.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_agent.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_auth_info.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_cert.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_curl.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_med_db.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_mysql.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_pool.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_sqlite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_sql_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_sql_provider.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -602,7 +566,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
- -rm -rf tests/.libs tests/_libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
@@ -719,8 +682,6 @@ 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 tests/$(DEPDIR)/$(am__dirstamp)
- -rm -f tests/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -731,7 +692,7 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-pluginLTLIBRARIES mostlyclean-am
distclean: distclean-am
- -rm -rf ./$(DEPDIR) tests/$(DEPDIR)
+ -rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -777,7 +738,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR) tests/$(DEPDIR)
+ -rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/src/libcharon/plugins/attr_sql/attr_sql_plugin.c b/src/libcharon/plugins/attr_sql/attr_sql_plugin.c
new file mode 100644
index 000000000..908877514
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/attr_sql_plugin.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <daemon.h>
+#include <utils/debug.h>
+#include <plugins/plugin_feature.h>
+
+#include "attr_sql_plugin.h"
+#include "attr_sql_provider.h"
+
+typedef struct private_attr_sql_plugin_t private_attr_sql_plugin_t;
+
+/**
+ * private data of attr_sql plugin
+ */
+struct private_attr_sql_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ attr_sql_plugin_t public;
+
+ /**
+ * database connection instance
+ */
+ database_t *db;
+
+ /**
+ * configuration attributes
+ */
+ attr_sql_provider_t *attribute;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_attr_sql_plugin_t *this)
+{
+ return "attr-sql";
+}
+
+/**
+ * Connect to database
+ */
+static bool open_database(private_attr_sql_plugin_t *this,
+ plugin_feature_t *feature, bool reg, void *cb_data)
+{
+ if (reg)
+ {
+ char *uri;
+
+ uri = lib->settings->get_str(lib->settings,
+ "%s.plugins.attr-sql.database", NULL, lib->ns);
+ if (!uri)
+ {
+ DBG1(DBG_CFG, "attr-sql plugin: database URI not set");
+ return FALSE;
+ }
+
+ this->db = lib->db->create(lib->db, uri);
+ if (!this->db)
+ {
+ DBG1(DBG_CFG, "attr-sql plugin failed to connect to database");
+ return FALSE;
+ }
+ this->attribute = attr_sql_provider_create(this->db);
+ charon->attributes->add_provider(charon->attributes,
+ &this->attribute->provider);
+ }
+ else
+ {
+ charon->attributes->remove_provider(charon->attributes,
+ &this->attribute->provider);
+ this->attribute->destroy(this->attribute);
+ this->db->destroy(this->db);
+ }
+ return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_attr_sql_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((plugin_feature_callback_t)open_database, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "attr-sql"),
+ PLUGIN_DEPENDS(DATABASE, DB_ANY),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_attr_sql_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *attr_sql_plugin_create()
+{
+ private_attr_sql_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ );
+ lib->settings->add_fallback(lib->settings, "%s.plugins.attr-sql",
+ "libhydra.plugins.attr-sql", lib->ns);
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/unit_tester/unit_tester.h b/src/libcharon/plugins/attr_sql/attr_sql_plugin.h
index 08784f6f4..b6b04ccc0 100644
--- a/src/libcharon/plugins/unit_tester/unit_tester.h
+++ b/src/libcharon/plugins/attr_sql/attr_sql_plugin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,31 +14,29 @@
*/
/**
- * @defgroup unit_tester unit_tester
- * @{ @ingroup cplugins
+ * @defgroup attr_sql attr_sql
+ * @ingroup cplugins
+ *
+ * @defgroup attr_sql_plugin attr_sql_plugin
+ * @{ @ingroup attr_sql
*/
-#ifndef UNIT_TESTER_H_
-#define UNIT_TESTER_H_
+#ifndef ATTR_SQL_PLUGIN_H_
+#define ATTR_SQL_PLUGIN_H_
#include <plugins/plugin.h>
-typedef struct unit_tester_t unit_tester_t;
+typedef struct attr_sql_plugin_t attr_sql_plugin_t;
/**
- * Unit testing plugin.
- *
- * The unit testing plugin runs tests on plugin initialization. Tests are
- * defined in tests.h using the DEFINE_TEST macro. Implementation of the
- * tests is done in the tests folder. Each test has uses a function which
- * returns TRUE for success or FALSE for failure.
+ * SQL database attribute configuration plugin
*/
-struct unit_tester_t {
+struct attr_sql_plugin_t {
/**
- * Implements the plugin interface.
+ * implements plugin interface
*/
plugin_t plugin;
};
-#endif /** UNIT_TESTER_H_ @}*/
+#endif /** ATTR_SQL_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/attr_sql/attr_sql_provider.c b/src/libcharon/plugins/attr_sql/attr_sql_provider.c
new file mode 100644
index 000000000..c2410705d
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <time.h>
+
+#include <utils/debug.h>
+#include <library.h>
+
+#include "attr_sql_provider.h"
+
+typedef struct private_attr_sql_provider_t private_attr_sql_provider_t;
+
+/**
+ * private data of attr_sql_provider
+ */
+struct private_attr_sql_provider_t {
+
+ /**
+ * public functions
+ */
+ attr_sql_provider_t public;
+
+ /**
+ * database connection
+ */
+ database_t *db;
+
+ /**
+ * whether to record lease history in lease table
+ */
+ bool history;
+};
+
+/**
+ * lookup/insert an identity
+ */
+static u_int get_identity(private_attr_sql_provider_t *this, ike_sa_t *ike_sa)
+{
+ identification_t *id;
+ enumerator_t *e;
+ u_int row;
+
+ id = ike_sa->get_other_eap_id(ike_sa);
+
+ this->db->transaction(this->db, TRUE);
+ /* look for peer identity in the identities table */
+ e = this->db->query(this->db,
+ "SELECT id FROM identities WHERE type = ? AND data = ?",
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
+ DB_UINT);
+ if (e && e->enumerate(e, &row))
+ {
+ e->destroy(e);
+ this->db->commit(this->db);
+ return row;
+ }
+ DESTROY_IF(e);
+ /* not found, insert new one */
+ if (this->db->execute(this->db, &row,
+ "INSERT INTO identities (type, data) VALUES (?, ?)",
+ DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id)) == 1)
+ {
+ this->db->commit(this->db);
+ return row;
+ }
+ this->db->rollback(this->db);
+ return 0;
+}
+
+/**
+ * Lookup an attribute pool by name
+ */
+static u_int get_attr_pool(private_attr_sql_provider_t *this, char *name)
+{
+ enumerator_t *e;
+ u_int row = 0;
+
+ e = this->db->query(this->db,
+ "SELECT id FROM attribute_pools WHERE name = ?",
+ DB_TEXT, name, DB_UINT);
+ if (e)
+ {
+ e->enumerate(e, &row);
+ }
+ DESTROY_IF(e);
+
+ return row;
+}
+
+/**
+ * Lookup pool by name and address family
+ */
+static u_int get_pool(private_attr_sql_provider_t *this, char *name, int family,
+ u_int *timeout)
+{
+ enumerator_t *e;
+ chunk_t start;
+ u_int pool;
+
+ e = this->db->query(this->db,
+ "SELECT id, start, timeout FROM pools WHERE name = ?",
+ DB_TEXT, name, DB_UINT, DB_BLOB, DB_UINT);
+ if (e && e->enumerate(e, &pool, &start, timeout))
+ {
+ if ((family == AF_INET && start.len == 4) ||
+ (family == AF_INET6 && start.len == 16))
+ {
+ e->destroy(e);
+ return pool;
+ }
+ }
+ DESTROY_IF(e);
+ return 0;
+}
+
+/**
+ * Look up an existing lease
+ */
+static host_t* check_lease(private_attr_sql_provider_t *this, char *name,
+ u_int pool, u_int identity)
+{
+ while (TRUE)
+ {
+ u_int id;
+ chunk_t address;
+ enumerator_t *e;
+ time_t now = time(NULL);
+
+ e = this->db->query(this->db,
+ "SELECT id, address FROM addresses "
+ "WHERE pool = ? AND identity = ? AND released != 0 LIMIT 1",
+ DB_UINT, pool, DB_UINT, identity, DB_UINT, DB_BLOB);
+ if (!e || !e->enumerate(e, &id, &address))
+ {
+ DESTROY_IF(e);
+ break;
+ }
+ address = chunk_clonea(address);
+ e->destroy(e);
+
+ if (this->db->execute(this->db, NULL,
+ "UPDATE addresses SET acquired = ?, released = 0 "
+ "WHERE id = ? AND identity = ? AND released != 0",
+ DB_UINT, now, DB_UINT, id, DB_UINT, identity) > 0)
+ {
+ host_t *host;
+
+ host = host_create_from_chunk(AF_UNSPEC, address, 0);
+ if (host)
+ {
+ DBG1(DBG_CFG, "acquired existing lease for address %H in"
+ " pool '%s'", host, name);
+ return host;
+ }
+ }
+ }
+ return NULL;
+}
+
+/**
+ * We check for unallocated addresses or expired leases. First we select an
+ * address as a candidate, but double check later on if it is still available
+ * during the update operation. This allows us to work without locking.
+ */
+static host_t* get_lease(private_attr_sql_provider_t *this, char *name,
+ u_int pool, u_int timeout, u_int identity)
+{
+ while (TRUE)
+ {
+ u_int id;
+ chunk_t address;
+ enumerator_t *e;
+ time_t now = time(NULL);
+ int hits;
+
+ if (timeout)
+ {
+ /* check for an expired lease */
+ e = this->db->query(this->db,
+ "SELECT id, address FROM addresses "
+ "WHERE pool = ? AND released != 0 AND released < ? LIMIT 1",
+ DB_UINT, pool, DB_UINT, now - timeout, DB_UINT, DB_BLOB);
+ }
+ else
+ {
+ /* with static leases, check for an unallocated address */
+ e = this->db->query(this->db,
+ "SELECT id, address FROM addresses "
+ "WHERE pool = ? AND identity = 0 LIMIT 1",
+ DB_UINT, pool, DB_UINT, DB_BLOB);
+
+ }
+
+ if (!e || !e->enumerate(e, &id, &address))
+ {
+ DESTROY_IF(e);
+ break;
+ }
+ address = chunk_clonea(address);
+ e->destroy(e);
+
+ if (timeout)
+ {
+ hits = this->db->execute(this->db, NULL,
+ "UPDATE addresses SET "
+ "acquired = ?, released = 0, identity = ? "
+ "WHERE id = ? AND released != 0 AND released < ?",
+ DB_UINT, now, DB_UINT, identity,
+ DB_UINT, id, DB_UINT, now - timeout);
+ }
+ else
+ {
+ hits = this->db->execute(this->db, NULL,
+ "UPDATE addresses SET "
+ "acquired = ?, released = 0, identity = ? "
+ "WHERE id = ? AND identity = 0",
+ DB_UINT, now, DB_UINT, identity, DB_UINT, id);
+ }
+ if (hits > 0)
+ {
+ host_t *host;
+
+ host = host_create_from_chunk(AF_UNSPEC, address, 0);
+ if (host)
+ {
+ DBG1(DBG_CFG, "acquired new lease for address %H in pool '%s'",
+ host, name);
+ return host;
+ }
+ }
+ }
+ DBG1(DBG_CFG, "no available address found in pool '%s'", name);
+ return NULL;
+}
+
+METHOD(attribute_provider_t, acquire_address, host_t*,
+ private_attr_sql_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
+ host_t *requested)
+{
+ enumerator_t *enumerator;
+ host_t *address = NULL;
+ u_int identity, pool, timeout;
+ char *name;
+ int family;
+
+ identity = get_identity(this, ike_sa);
+ if (identity)
+ {
+ family = requested->get_family(requested);
+ /* check for an existing lease in all pools */
+ enumerator = pools->create_enumerator(pools);
+ while (enumerator->enumerate(enumerator, &name))
+ {
+ pool = get_pool(this, name, family, &timeout);
+ if (pool)
+ {
+ address = check_lease(this, name, pool, identity);
+ if (address)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!address)
+ {
+ /* get an unallocated address or expired lease */
+ enumerator = pools->create_enumerator(pools);
+ while (enumerator->enumerate(enumerator, &name))
+ {
+ pool = get_pool(this, name, family, &timeout);
+ if (pool)
+ {
+ address = get_lease(this, name, pool, timeout, identity);
+ if (address)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ }
+ return address;
+}
+
+METHOD(attribute_provider_t, release_address, bool,
+ private_attr_sql_provider_t *this, linked_list_t *pools, host_t *address,
+ ike_sa_t *ike_sa)
+{
+ enumerator_t *enumerator;
+ u_int pool, timeout;
+ time_t now = time(NULL);
+ bool found = FALSE;
+ char *name;
+ int family;
+
+ family = address->get_family(address);
+ enumerator = pools->create_enumerator(pools);
+ while (enumerator->enumerate(enumerator, &name))
+ {
+ pool = get_pool(this, name, family, &timeout);
+ if (!pool)
+ {
+ continue;
+ }
+ if (this->db->execute(this->db, NULL,
+ "UPDATE addresses SET released = ? WHERE "
+ "pool = ? AND address = ?", DB_UINT, time(NULL),
+ DB_UINT, pool, DB_BLOB, address->get_address(address)) > 0)
+ {
+ if (this->history)
+ {
+ this->db->execute(this->db, NULL,
+ "INSERT INTO leases (address, identity, acquired, released)"
+ " SELECT id, identity, acquired, ? FROM addresses "
+ " WHERE pool = ? AND address = ?",
+ DB_UINT, now, DB_UINT, pool,
+ DB_BLOB, address->get_address(address));
+ }
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
+METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
+ private_attr_sql_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
+ linked_list_t *vips)
+{
+ enumerator_t *attr_enumerator = NULL;
+
+ if (vips->get_count(vips))
+ {
+ enumerator_t *pool_enumerator;
+ u_int count;
+ char *name;
+
+ /* in a first step check for attributes that match name and id */
+ if (ike_sa)
+ {
+ u_int identity = get_identity(this, ike_sa);
+
+ pool_enumerator = pools->create_enumerator(pools);
+ while (pool_enumerator->enumerate(pool_enumerator, &name))
+ {
+ u_int attr_pool = get_attr_pool(this, name);
+ if (!attr_pool)
+ {
+ continue;
+ }
+
+ attr_enumerator = this->db->query(this->db,
+ "SELECT count(*) FROM attributes "
+ "WHERE pool = ? AND identity = ?",
+ DB_UINT, attr_pool, DB_UINT, identity, DB_UINT);
+
+ if (attr_enumerator &&
+ attr_enumerator->enumerate(attr_enumerator, &count) &&
+ count != 0)
+ {
+ attr_enumerator->destroy(attr_enumerator);
+ attr_enumerator = this->db->query(this->db,
+ "SELECT type, value FROM attributes "
+ "WHERE pool = ? AND identity = ?", DB_UINT,
+ attr_pool, DB_UINT, identity, DB_INT, DB_BLOB);
+ break;
+ }
+ DESTROY_IF(attr_enumerator);
+ attr_enumerator = NULL;
+ }
+ pool_enumerator->destroy(pool_enumerator);
+ }
+
+ /* in a second step check for attributes that match name */
+ if (!attr_enumerator)
+ {
+ pool_enumerator = pools->create_enumerator(pools);
+ while (pool_enumerator->enumerate(pool_enumerator, &name))
+ {
+ u_int attr_pool = get_attr_pool(this, name);
+ if (!attr_pool)
+ {
+ continue;
+ }
+
+ attr_enumerator = this->db->query(this->db,
+ "SELECT count(*) FROM attributes "
+ "WHERE pool = ? AND identity = 0",
+ DB_UINT, attr_pool, DB_UINT);
+
+ if (attr_enumerator &&
+ attr_enumerator->enumerate(attr_enumerator, &count) &&
+ count != 0)
+ {
+ attr_enumerator->destroy(attr_enumerator);
+ attr_enumerator = this->db->query(this->db,
+ "SELECT type, value FROM attributes "
+ "WHERE pool = ? AND identity = 0",
+ DB_UINT, attr_pool, DB_INT, DB_BLOB);
+ break;
+ }
+ DESTROY_IF(attr_enumerator);
+ attr_enumerator = NULL;
+ }
+ pool_enumerator->destroy(pool_enumerator);
+ }
+
+ /* lastly try to find global attributes */
+ if (!attr_enumerator)
+ {
+ attr_enumerator = this->db->query(this->db,
+ "SELECT type, value FROM attributes "
+ "WHERE pool = 0 AND identity = 0",
+ DB_INT, DB_BLOB);
+ }
+ }
+
+ return (attr_enumerator ? attr_enumerator : enumerator_create_empty());
+}
+
+METHOD(attr_sql_provider_t, destroy, void,
+ private_attr_sql_provider_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+attr_sql_provider_t *attr_sql_provider_create(database_t *db)
+{
+ private_attr_sql_provider_t *this;
+ time_t now = time(NULL);
+
+ INIT(this,
+ .public = {
+ .provider = {
+ .acquire_address = _acquire_address,
+ .release_address = _release_address,
+ .create_attribute_enumerator = _create_attribute_enumerator,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ .history = lib->settings->get_bool(lib->settings,
+ "%s.plugins.attr-sql.lease_history", TRUE, lib->ns),
+ );
+
+ /* close any "online" leases in the case we crashed */
+ if (this->history)
+ {
+ this->db->execute(this->db, NULL,
+ "INSERT INTO leases (address, identity, acquired, released)"
+ " SELECT id, identity, acquired, ? FROM addresses "
+ " WHERE released = 0", DB_UINT, now);
+ }
+ this->db->execute(this->db, NULL,
+ "UPDATE addresses SET released = ? WHERE released = 0",
+ DB_UINT, now);
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/attr_sql/attr_sql_provider.h b/src/libcharon/plugins/attr_sql/attr_sql_provider.h
new file mode 100644
index 000000000..a9b037bf5
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attr_sql_provider attr_sql_provider
+ * @{ @ingroup attr_sql
+ */
+
+#ifndef ATTR_SQL_PROVIDER_H_
+#define ATTR_SQL_PROVIDER_H_
+
+#include <attributes/attribute_provider.h>
+#include <database/database.h>
+
+typedef struct attr_sql_provider_t attr_sql_provider_t;
+
+/**
+ * SQL database based IKEv2 cfg attribute provider.
+ */
+struct attr_sql_provider_t {
+
+ /**
+ * Implements attribute provider interface
+ */
+ attribute_provider_t provider;
+
+ /**
+ * Destroy a attr_sql_provider instance.
+ */
+ void (*destroy)(attr_sql_provider_t *this);
+};
+
+/**
+ * Create a attr_sql_provider instance.
+ */
+attr_sql_provider_t *attr_sql_provider_create(database_t *db);
+
+#endif /** ATTR_SQL_PROVIDER_H_ @}*/
diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in
index 08101d51d..f946d73c1 100644
--- a/src/libcharon/plugins/certexpire/Makefile.in
+++ b/src/libcharon/plugins/certexpire/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/connmark/Makefile.am b/src/libcharon/plugins/connmark/Makefile.am
new file mode 100644
index 000000000..cc4d0ec8d
--- /dev/null
+++ b/src/libcharon/plugins/connmark/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS) $(libiptc_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-connmark.la
+else
+plugin_LTLIBRARIES = libstrongswan-connmark.la
+endif
+
+libstrongswan_connmark_la_SOURCES = \
+ connmark_listener.h connmark_listener.c \
+ connmark_plugin.h connmark_plugin.c
+
+libstrongswan_connmark_la_LDFLAGS = -module -avoid-version
+libstrongswan_connmark_la_LIBADD = $(libiptc_LIBS)
diff --git a/src/libcharon/plugins/connmark/Makefile.in b/src/libcharon/plugins/connmark/Makefile.in
new file mode 100644
index 000000000..65f53fde9
--- /dev/null
+++ b/src/libcharon/plugins/connmark/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/connmark
+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)
+am__DEPENDENCIES_1 =
+libstrongswan_connmark_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_connmark_la_OBJECTS = connmark_listener.lo \
+ connmark_plugin.lo
+libstrongswan_connmark_la_OBJECTS = \
+ $(am_libstrongswan_connmark_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_connmark_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_connmark_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_connmark_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_connmark_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_connmark_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_connmark_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_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) $(libiptc_CFLAGS)
+
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-connmark.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-connmark.la
+libstrongswan_connmark_la_SOURCES = \
+ connmark_listener.h connmark_listener.c \
+ connmark_plugin.h connmark_plugin.c
+
+libstrongswan_connmark_la_LDFLAGS = -module -avoid-version
+libstrongswan_connmark_la_LIBADD = $(libiptc_LIBS)
+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/connmark/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/connmark/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-connmark.la: $(libstrongswan_connmark_la_OBJECTS) $(libstrongswan_connmark_la_DEPENDENCIES) $(EXTRA_libstrongswan_connmark_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_connmark_la_LINK) $(am_libstrongswan_connmark_la_rpath) $(libstrongswan_connmark_la_OBJECTS) $(libstrongswan_connmark_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connmark_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connmark_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/connmark/connmark_listener.c b/src/libcharon/plugins/connmark/connmark_listener.c
new file mode 100644
index 000000000..23df690e8
--- /dev/null
+++ b/src/libcharon/plugins/connmark/connmark_listener.c
@@ -0,0 +1,538 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "connmark_listener.h"
+
+#include <daemon.h>
+
+#include <errno.h>
+#include <libiptc/libiptc.h>
+#include <linux/netfilter/xt_esp.h>
+#include <linux/netfilter/xt_tcpudp.h>
+#include <linux/netfilter/xt_MARK.h>
+#include <linux/netfilter/xt_policy.h>
+#include <linux/netfilter/xt_CONNMARK.h>
+
+
+typedef struct private_connmark_listener_t private_connmark_listener_t;
+
+/**
+ * Private data of an connmark_listener_t object.
+ */
+struct private_connmark_listener_t {
+
+ /**
+ * Public connmark_listener_t interface.
+ */
+ connmark_listener_t public;
+};
+
+/**
+ * Convert an (IPv4) traffic selector to an address and mask
+ */
+static bool ts2in(traffic_selector_t *ts,
+ struct in_addr *addr, struct in_addr *mask)
+{
+ u_int8_t bits;
+ host_t *net;
+
+ if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE &&
+ ts->to_subnet(ts, &net, &bits))
+ {
+ memcpy(&addr->s_addr, net->get_address(net).ptr, 4);
+ net->destroy(net);
+ mask->s_addr = htonl(0xffffffffU << (32 - bits));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Convert an (IPv4) host to an address with mask
+ */
+static bool host2in(host_t *host, struct in_addr *addr, struct in_addr *mask)
+{
+ if (host->get_family(host) == AF_INET)
+ {
+ memcpy(&addr->s_addr, host->get_address(host).ptr, 4);
+ mask->s_addr = ~0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Add or remove a rule to/from the specified chain
+ */
+static bool manage_rule(struct iptc_handle *ipth, const char *chain,
+ bool add, struct ipt_entry *e)
+{
+ if (add)
+ {
+ if (!iptc_insert_entry(chain, e, 0, ipth))
+ {
+ DBG1(DBG_CFG, "appending %s rule failed: %s",
+ chain, iptc_strerror(errno));
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!iptc_delete_entry(chain, e, "", ipth))
+ {
+ DBG1(DBG_CFG, "deleting %s rule failed: %s",
+ chain, iptc_strerror(errno));
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Add rule marking UDP-encapsulated ESP packets to match the correct policy
+ */
+static bool manage_pre_esp_in_udp(private_connmark_listener_t *this,
+ struct iptc_handle *ipth, bool add,
+ 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,
+ },
+ },
+ .m = {
+ .u = {
+ .user = {
+ .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)),
+ .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,
+ },
+ },
+ },
+ .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 rule marking non-encapsulated ESP packets to match the correct policy
+ */
+static bool manage_pre_esp(private_connmark_listener_t *this,
+ struct iptc_handle *ipth, bool add,
+ 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,
+ },
+ },
+ .m = {
+ .u = {
+ .user = {
+ .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)),
+ .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,
+ },
+ },
+ },
+ .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 rule marking ESP packets to match the correct policy
+ */
+static bool manage_pre(private_connmark_listener_t *this,
+ struct iptc_handle *ipth, bool add,
+ u_int mark, u_int32_t spi, bool encap,
+ host_t *dst, host_t *src)
+{
+ if (encap)
+ {
+ return manage_pre_esp_in_udp(this, ipth, add, mark, spi, dst, src);
+ }
+ return manage_pre_esp(this, ipth, add, mark, spi, dst, src);
+}
+
+/**
+ * Add inbound rule applying CONNMARK to matching traffic
+ */
+static bool manage_in(private_connmark_listener_t *this,
+ struct iptc_handle *ipth, bool add,
+ 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",
+ },
+ },
+ },
+ .p = {
+ .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,
+ },
+ },
+ },
+ .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 outbund rule restoring CONNMARK on matching traffic
+ */
+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))
+ {
+ return FALSE;
+ }
+ return manage_rule(ipth, "OUTPUT", add, &ipt.e);
+}
+
+/**
+ * Initialize iptables handle, log error
+ */
+static struct iptc_handle* init_handle()
+{
+ struct iptc_handle *ipth;
+
+ ipth = iptc_init("mangle");
+ if (ipth)
+ {
+ return ipth;
+ }
+ DBG1(DBG_CFG, "initializing iptables failed: %s", iptc_strerror(errno));
+ return NULL;
+}
+
+/**
+ * Commit iptables rules, log error
+ */
+static bool commit_handle(struct iptc_handle *ipth)
+{
+ if (iptc_commit(ipth))
+ {
+ return TRUE;
+ }
+ DBG1(DBG_CFG, "forecast iptables commit failed: %s", iptc_strerror(errno));
+ return FALSE;
+}
+
+/**
+ * Add/Remove policies for a CHILD_SA using a iptables handle
+ */
+static bool manage_policies(private_connmark_listener_t *this,
+ struct iptc_handle *ipth, host_t *dst, host_t *src,
+ bool encap, child_sa_t *child_sa, bool add)
+{
+ traffic_selector_t *local, *remote;
+ enumerator_t *enumerator;
+ u_int32_t spi;
+ u_int mark;
+ bool done = TRUE;
+
+ spi = child_sa->get_spi(child_sa, TRUE);
+ mark = child_sa->get_mark(child_sa, TRUE).value;
+
+ enumerator = child_sa->create_policy_enumerator(child_sa);
+ while (enumerator->enumerate(enumerator, &local, &remote))
+ {
+ if (!manage_pre(this, ipth, add, mark, spi, encap, dst, src) ||
+ !manage_in(this, ipth, add, mark, spi, local, remote) ||
+ !manage_out(this, ipth, add, remote, local))
+ {
+ done = FALSE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return done;
+}
+
+/**
+ * Check if rules should be installed for given CHILD_SA
+ */
+static bool handle_sa(child_sa_t *child_sa)
+{
+ return child_sa->get_mark(child_sa, TRUE).value &&
+ child_sa->get_mark(child_sa, FALSE).value &&
+ child_sa->get_mode(child_sa) == MODE_TRANSPORT &&
+ child_sa->get_protocol(child_sa) == PROTO_ESP;
+}
+
+METHOD(listener_t, child_updown, bool,
+ private_connmark_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ bool up)
+{
+ struct iptc_handle *ipth;
+ host_t *dst, *src;
+ bool encap;
+
+ dst = ike_sa->get_my_host(ike_sa);
+ src = ike_sa->get_other_host(ike_sa);
+ encap = child_sa->has_encap(child_sa);
+
+ if (handle_sa(child_sa))
+ {
+ ipth = init_handle();
+ if (ipth)
+ {
+ if (manage_policies(this, ipth, dst, src, encap, child_sa, up))
+ {
+ commit_handle(ipth);
+ }
+ iptc_free(ipth);
+ }
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, child_rekey, bool,
+ private_connmark_listener_t *this, ike_sa_t *ike_sa,
+ child_sa_t *old, child_sa_t *new)
+{
+ struct iptc_handle *ipth;
+ host_t *dst, *src;
+ bool oldencap, newencap;
+
+ dst = ike_sa->get_my_host(ike_sa);
+ src = ike_sa->get_other_host(ike_sa);
+ oldencap = old->has_encap(old);
+ newencap = new->has_encap(new);
+
+ if (handle_sa(old))
+ {
+ ipth = init_handle();
+ if (ipth)
+ {
+ if (manage_policies(this, ipth, dst, src, oldencap, old, FALSE) &&
+ manage_policies(this, ipth, dst, src, newencap, new, TRUE))
+ {
+ commit_handle(ipth);
+ }
+ iptc_free(ipth);
+ }
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, ike_update, bool,
+ private_connmark_listener_t *this, ike_sa_t *ike_sa,
+ bool local, host_t *new)
+{
+ struct iptc_handle *ipth;
+ enumerator_t *enumerator;
+ child_sa_t *child_sa;
+ host_t *dst, *src;
+ bool oldencap, newencap;
+
+ if (local)
+ {
+ dst = new;
+ src = ike_sa->get_other_host(ike_sa);
+ }
+ else
+ {
+ dst = ike_sa->get_my_host(ike_sa);
+ src = new;
+ }
+ /* during ike_update(), has_encap() on the CHILD_SA has not yet been
+ * updated, but shows the old state. */
+ newencap = ike_sa->has_condition(ike_sa, COND_NAT_ANY);
+
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, &child_sa))
+ {
+ if (handle_sa(child_sa))
+ {
+ oldencap = child_sa->has_encap(child_sa);
+ ipth = init_handle();
+ if (ipth)
+ {
+ if (manage_policies(this, ipth, dst, src, oldencap,
+ child_sa, FALSE) &&
+ manage_policies(this, ipth, dst, src, newencap,
+ child_sa, TRUE))
+ {
+ commit_handle(ipth);
+ }
+ iptc_free(ipth);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return TRUE;
+}
+
+METHOD(connmark_listener_t, destroy, void,
+ private_connmark_listener_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+connmark_listener_t *connmark_listener_create()
+{
+ private_connmark_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_update = _ike_update,
+ .child_updown = _child_updown,
+ .child_rekey = _child_rekey,
+ },
+ .destroy = _destroy,
+ },
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/connmark/connmark_listener.h b/src/libcharon/plugins/connmark/connmark_listener.h
new file mode 100644
index 000000000..2d4098fb6
--- /dev/null
+++ b/src/libcharon/plugins/connmark/connmark_listener.h
@@ -0,0 +1,49 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup connmark_listener connmark_listener
+ * @{ @ingroup connmark
+ */
+
+#ifndef CONNMARK_LISTENER_H_
+#define CONNMARK_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct connmark_listener_t connmark_listener_t;
+
+/**
+ * Listener to install Netfilter rules
+ */
+struct connmark_listener_t {
+
+ /**
+ * Implements listener_t interface.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a connmark_listener_t.
+ */
+ void (*destroy)(connmark_listener_t *this);
+};
+
+/**
+ * Create a connmark_listener instance.
+ */
+connmark_listener_t *connmark_listener_create();
+
+#endif /** CONNMARK_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/connmark/connmark_plugin.c b/src/libcharon/plugins/connmark/connmark_plugin.c
new file mode 100644
index 000000000..3f276f93e
--- /dev/null
+++ b/src/libcharon/plugins/connmark/connmark_plugin.c
@@ -0,0 +1,105 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "connmark_plugin.h"
+#include "connmark_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_connmark_plugin_t private_connmark_plugin_t;
+
+/**
+ * private data of connmark plugin
+ */
+struct private_connmark_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ connmark_plugin_t public;
+
+ /**
+ * Listener installing netfilter rules
+ */
+ connmark_listener_t *listener;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_connmark_plugin_t *this)
+{
+ return "connmark";
+}
+
+/**
+ * Register listener
+ */
+static bool plugin_cb(private_connmark_plugin_t *this,
+ plugin_feature_t *feature, bool reg, void *cb_data)
+{
+ if (reg)
+ {
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+ }
+ else
+ {
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ }
+ return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_connmark_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "connmark"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_connmark_plugin_t *this)
+{
+ this->listener->destroy(this->listener);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *connmark_plugin_create()
+{
+ private_connmark_plugin_t *this;
+
+ if (!lib->caps->keep(lib->caps, CAP_NET_ADMIN))
+ {
+ DBG1(DBG_NET, "connmark plugin requires CAP_NET_ADMIN capability");
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ .listener = connmark_listener_create(),
+ );
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/connmark/connmark_plugin.h b/src/libcharon/plugins/connmark/connmark_plugin.h
new file mode 100644
index 000000000..5b4ccebbe
--- /dev/null
+++ b/src/libcharon/plugins/connmark/connmark_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup connmark connmark
+ * @ingroup cplugins
+ *
+ * @defgroup connmark_plugin connmark_plugin
+ * @{ @ingroup connmark
+ */
+
+#ifndef CONNMARK_PLUGIN_H_
+#define CONNMARK_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct connmark_plugin_t connmark_plugin_t;
+
+/**
+ * Plugin using marks to select return path SA based on conntrack.
+ */
+struct connmark_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** CONNMARK_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in
index 679d2dae6..dff80c37f 100644
--- a/src/libcharon/plugins/coupling/Makefile.in
+++ b/src/libcharon/plugins/coupling/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in
index 768c2b32b..1e84f04e2 100644
--- a/src/libcharon/plugins/dhcp/Makefile.in
+++ b/src/libcharon/plugins/dhcp/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ 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@
@@ -364,6 +367,8 @@ 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@
diff --git a/src/libcharon/plugins/dhcp/dhcp_plugin.c b/src/libcharon/plugins/dhcp/dhcp_plugin.c
index c36c60d28..642e28afc 100644
--- a/src/libcharon/plugins/dhcp/dhcp_plugin.c
+++ b/src/libcharon/plugins/dhcp/dhcp_plugin.c
@@ -18,7 +18,6 @@
#include "dhcp_plugin.h"
-#include <hydra.h>
#include <daemon.h>
#include <plugins/plugin_feature.h>
@@ -69,13 +68,13 @@ static bool plugin_cb(private_dhcp_plugin_t *this,
return FALSE;
}
this->provider = dhcp_provider_create(this->socket);
- hydra->attributes->add_provider(hydra->attributes,
- &this->provider->provider);
+ charon->attributes->add_provider(charon->attributes,
+ &this->provider->provider);
}
else
{
- hydra->attributes->remove_provider(hydra->attributes,
- &this->provider->provider);
+ charon->attributes->remove_provider(charon->attributes,
+ &this->provider->provider);
this->provider->destroy(this->provider);
this->socket->destroy(this->socket);
}
diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c
index f5325b566..f0681b1da 100644
--- a/src/libcharon/plugins/dhcp/dhcp_provider.c
+++ b/src/libcharon/plugins/dhcp/dhcp_provider.c
@@ -66,10 +66,11 @@ static uintptr_t hash_transaction(dhcp_transaction_t *transaction)
METHOD(attribute_provider_t, acquire_address, host_t*,
private_dhcp_provider_t *this, linked_list_t *pools,
- identification_t *id, host_t *requested)
+ ike_sa_t *ike_sa, host_t *requested)
{
dhcp_transaction_t *transaction, *old;
enumerator_t *enumerator;
+ identification_t *id;
char *pool;
host_t *vip = NULL;
@@ -77,6 +78,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
{
return NULL;
}
+ id = ike_sa->get_other_eap_id(ike_sa);
enumerator = pools->create_enumerator(pools);
while (enumerator->enumerate(enumerator, &pool))
{
@@ -104,10 +106,11 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
METHOD(attribute_provider_t, release_address, bool,
private_dhcp_provider_t *this, linked_list_t *pools,
- host_t *address, identification_t *id)
+ host_t *address, ike_sa_t *ike_sa)
{
dhcp_transaction_t *transaction;
enumerator_t *enumerator;
+ identification_t *id;
bool found = FALSE;
char *pool;
@@ -115,6 +118,7 @@ METHOD(attribute_provider_t, release_address, bool,
{
return FALSE;
}
+ id = ike_sa->get_other_eap_id(ike_sa);
enumerator = pools->create_enumerator(pools);
while (enumerator->enumerate(enumerator, &pool))
{
@@ -139,11 +143,12 @@ METHOD(attribute_provider_t, release_address, bool,
}
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
- private_dhcp_provider_t *this, linked_list_t *pools, identification_t *id,
+ private_dhcp_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
linked_list_t *vips)
{
dhcp_transaction_t *transaction = NULL;
enumerator_t *enumerator;
+ identification_t *id;
host_t *vip;
if (pools->find_first(pools, (linked_list_match_t)streq,
@@ -152,6 +157,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
return NULL;
}
+ id = ike_sa->get_other_eap_id(ike_sa);
this->mutex->lock(this->mutex);
enumerator = vips->create_enumerator(vips);
while (enumerator->enumerate(enumerator, &vip))
diff --git a/src/libcharon/plugins/dnscert/Makefile.in b/src/libcharon/plugins/dnscert/Makefile.in
index 3484e08a3..ed873b316 100644
--- a/src/libcharon/plugins/dnscert/Makefile.in
+++ b/src/libcharon/plugins/dnscert/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in
index 381d7a119..41862cb2a 100644
--- a/src/libcharon/plugins/duplicheck/Makefile.in
+++ b/src/libcharon/plugins/duplicheck/Makefile.in
@@ -236,6 +236,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -296,10 +297,12 @@ 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@
@@ -373,6 +376,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in
index 3b0f8763c..dacddfb87 100644
--- a/src/libcharon/plugins/eap_aka/Makefile.in
+++ b/src/libcharon/plugins/eap_aka/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ 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@
@@ -367,6 +370,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
index 839a379ea..3c26b8511 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
+++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ 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@
@@ -368,6 +371,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_dynamic/Makefile.in b/src/libcharon/plugins/eap_dynamic/Makefile.in
index fdbad6234..402c7cadc 100644
--- a/src/libcharon/plugins/eap_dynamic/Makefile.in
+++ b/src/libcharon/plugins/eap_dynamic/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in
index 9675104da..2279b2514 100644
--- a/src/libcharon/plugins/eap_gtc/Makefile.in
+++ b/src/libcharon/plugins/eap_gtc/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ 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@
@@ -365,6 +368,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in
index 0610b5859..30d2c88d1 100644
--- a/src/libcharon/plugins/eap_identity/Makefile.in
+++ b/src/libcharon/plugins/eap_identity/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in
index 38c9d0b7c..14616c214 100644
--- a/src/libcharon/plugins/eap_md5/Makefile.in
+++ b/src/libcharon/plugins/eap_md5/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ 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@
@@ -365,6 +368,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in
index f5dfd6814..78dfd29e3 100644
--- a/src/libcharon/plugins/eap_mschapv2/Makefile.in
+++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in
index 5ccd58158..2f0d65d6d 100644
--- a/src/libcharon/plugins/eap_peap/Makefile.in
+++ b/src/libcharon/plugins/eap_peap/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ 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@
@@ -367,6 +370,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in
index 04cc422f5..47534372b 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.in
+++ b/src/libcharon/plugins/eap_radius/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ 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@
@@ -368,6 +371,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
index 31c96d229..ac4ecfc86 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
@@ -99,7 +99,7 @@ typedef struct {
/** IKE_SA identifier this entry is stored under */
ike_sa_id_t *id;
/** RADIUS accounting session ID */
- char sid[16];
+ char sid[24];
/** number of sent/received octets/packets */
struct {
u_int64_t sent;
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
index 1a48c07e5..6a4a0384e 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
@@ -26,7 +26,7 @@
#include <radius_client.h>
#include <radius_config.h>
-#include <hydra.h>
+#include <daemon.h>
#include <threading/rwlock.h>
#include <processing/jobs/callback_job.h>
#include <processing/jobs/delete_ike_sa_job.h>
@@ -149,19 +149,26 @@ static void load_configs(private_eap_radius_plugin_t *this)
continue;
}
nas_identifier = lib->settings->get_str(lib->settings,
- "%s.plugins.eap-radius.servers.%s.nas_identifier", "strongSwan",
+ "%s.plugins.eap-radius.servers.%s.nas_identifier",
+ lib->settings->get_str(lib->settings,
+ "%s.plugins.eap-radius.nas_identifier", "strongSwan",
+ lib->ns),
lib->ns, section);
auth_port = lib->settings->get_int(lib->settings,
"%s.plugins.eap-radius.servers.%s.auth_port",
lib->settings->get_int(lib->settings,
"%s.plugins.eap-radius.servers.%s.port",
- AUTH_PORT, lib->ns, section),
+ lib->settings->get_int(lib->settings,
+ "%s.plugins.eap-radius.port", AUTH_PORT, lib->ns),
+ lib->ns, section),
lib->ns, section);
acct_port = lib->settings->get_int(lib->settings,
"%s.plugins.eap-radius.servers.%s.acct_port", ACCT_PORT,
lib->ns, section);
sockets = lib->settings->get_int(lib->settings,
- "%s.plugins.eap-radius.servers.%s.sockets", 1,
+ "%s.plugins.eap-radius.servers.%s.sockets",
+ lib->settings->get_int(lib->settings,
+ "%s.plugins.eap-radius.sockets", 1, lib->ns),
lib->ns, section);
preference = lib->settings->get_int(lib->settings,
"%s.plugins.eap-radius.servers.%s.preference", 0,
@@ -211,13 +218,13 @@ static bool plugin_cb(private_eap_radius_plugin_t *this,
{
charon->bus->add_listener(charon->bus, &this->forward->listener);
}
- hydra->attributes->add_provider(hydra->attributes,
- &this->provider->provider);
+ charon->attributes->add_provider(charon->attributes,
+ &this->provider->provider);
}
else
{
- hydra->attributes->remove_provider(hydra->attributes,
- &this->provider->provider);
+ charon->attributes->remove_provider(charon->attributes,
+ &this->provider->provider);
if (this->forward)
{
charon->bus->remove_listener(charon->bus, &this->forward->listener);
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.c b/src/libcharon/plugins/eap_radius/eap_radius_provider.c
index 7c794616b..0cf723711 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_provider.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.c
@@ -311,19 +311,13 @@ METHOD(listener_t, ike_rekey, bool,
METHOD(attribute_provider_t, acquire_address, host_t*,
private_eap_radius_provider_t *this, linked_list_t *pools,
- identification_t *id, host_t *requested)
+ ike_sa_t *ike_sa, host_t *requested)
{
enumerator_t *enumerator;
host_t *addr = NULL;
- ike_sa_t *ike_sa;
uintptr_t sa;
char *name;
- ike_sa = charon->bus->get_sa(charon->bus);
- if (!ike_sa)
- {
- return NULL;
- }
sa = ike_sa->get_unique_id(ike_sa);
enumerator = pools->create_enumerator(pools);
@@ -348,19 +342,13 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
METHOD(attribute_provider_t, release_address, bool,
private_eap_radius_provider_t *this, linked_list_t *pools, host_t *address,
- identification_t *id)
+ ike_sa_t *ike_sa)
{
enumerator_t *enumerator;
host_t *found = NULL;
- ike_sa_t *ike_sa;
uintptr_t sa;
char *name;
- ike_sa = charon->bus->get_sa(charon->bus);
- if (!ike_sa)
- {
- return FALSE;
- }
sa = ike_sa->get_unique_id(ike_sa);
enumerator = pools->create_enumerator(pools);
@@ -428,18 +416,12 @@ METHOD(enumerator_t, attribute_destroy, void,
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_eap_radius_provider_t *this, linked_list_t *pools,
- identification_t *id, linked_list_t *vips)
+ ike_sa_t *ike_sa, linked_list_t *vips)
{
attribute_enumerator_t *enumerator;
attr_t *attr;
- ike_sa_t *ike_sa;
uintptr_t sa;
- ike_sa = charon->bus->get_sa(charon->bus);
- if (!ike_sa)
- {
- return NULL;
- }
sa = ike_sa->get_unique_id(ike_sa);
INIT(enumerator,
diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in
index 6a00ea74d..251eeeeba 100644
--- a/src/libcharon/plugins/eap_sim/Makefile.in
+++ b/src/libcharon/plugins/eap_sim/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ 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@
@@ -367,6 +370,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in
index 7a08f4e0e..bffcbc0df 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_file/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ 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@
@@ -368,6 +371,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
index a1ec7adc1..78682ce37 100644
--- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ 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@
@@ -369,6 +372,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
index bf99ab095..2a6be5fd9 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ 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@
@@ -369,6 +372,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
index ce4602365..de504d4cd 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ 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@
@@ -368,6 +371,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
index 0c0b7fd52..de3508a07 100644
--- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ 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@
@@ -367,6 +370,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in
index 25696f524..d4219b876 100644
--- a/src/libcharon/plugins/eap_tls/Makefile.in
+++ b/src/libcharon/plugins/eap_tls/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c
index dffbaf266..bc01ba5df 100644
--- a/src/libcharon/plugins/eap_tls/eap_tls.c
+++ b/src/libcharon/plugins/eap_tls/eap_tls.c
@@ -109,6 +109,12 @@ METHOD(eap_method_t, is_mutual, bool,
return TRUE;
}
+METHOD(eap_method_t, get_auth, auth_cfg_t*,
+ private_eap_tls_t *this)
+{
+ return this->tls_eap->get_auth(this->tls_eap);
+}
+
METHOD(eap_method_t, destroy, void,
private_eap_tls_t *this)
{
@@ -138,6 +144,7 @@ static eap_tls_t *eap_tls_create(identification_t *server,
.get_msk = _get_msk,
.get_identifier = _get_identifier,
.set_identifier = _set_identifier,
+ .get_auth = _get_auth,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in
index 2d5d65875..6c34ed098 100644
--- a/src/libcharon/plugins/eap_tnc/Makefile.in
+++ b/src/libcharon/plugins/eap_tnc/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ 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@
@@ -367,6 +370,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c
index 62d23d064..f70f47ef6 100644
--- a/src/libcharon/plugins/eap_tnc/eap_tnc.c
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -256,6 +256,8 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
private_eap_tnc_t *this;
int max_msg_count;
char* protocol;
+ ike_sa_t *ike_sa;
+ host_t *server_ip, *peer_ip;
tnccs_t *tnccs;
tnccs_type_t tnccs_type;
@@ -302,8 +304,29 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
free(this);
return NULL;
}
+
+ /* Determine IP addresses of server and peer */
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (!ike_sa)
+ {
+ DBG1(DBG_TNC, "%N constructor did not find IKE_SA",
+ eap_type_names, type);
+ free(this);
+ return NULL;
+ }
+ if (is_server)
+ {
+ server_ip = ike_sa->get_my_host(ike_sa);
+ peer_ip = ike_sa->get_other_host(ike_sa);
+ }
+ else
+ {
+ peer_ip = ike_sa->get_my_host(ike_sa);
+ server_ip = ike_sa->get_other_host(ike_sa);
+ }
+
tnccs = tnc->tnccs->create_instance(tnc->tnccs, tnccs_type,
- is_server, server, peer,
+ 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);
if (!tnccs)
diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in
index 38c7632ac..0babf1766 100644
--- a/src/libcharon/plugins/eap_ttls/Makefile.in
+++ b/src/libcharon/plugins/eap_ttls/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ 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@
@@ -368,6 +371,8 @@ 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@
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c
index 703cd3f29..c99d47f8d 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c
@@ -111,6 +111,12 @@ METHOD(eap_method_t, is_mutual, bool,
return TRUE;
}
+METHOD(eap_method_t, get_auth, auth_cfg_t*,
+ private_eap_ttls_t *this)
+{
+ return this->tls_eap->get_auth(this->tls_eap);
+}
+
METHOD(eap_method_t, destroy, void,
private_eap_ttls_t *this)
{
@@ -141,6 +147,7 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
.get_identifier = _get_identifier,
.set_identifier = _set_identifier,
.get_msk = _get_msk,
+ .get_auth = _get_auth,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/plugins/error_notify/Makefile.in b/src/libcharon/plugins/error_notify/Makefile.in
index d9fa454ca..0a07aa7a3 100644
--- a/src/libcharon/plugins/error_notify/Makefile.in
+++ b/src/libcharon/plugins/error_notify/Makefile.in
@@ -237,6 +237,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -297,10 +298,12 @@ 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@
@@ -374,6 +377,8 @@ 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@
diff --git a/src/libcharon/plugins/ext_auth/Makefile.in b/src/libcharon/plugins/ext_auth/Makefile.in
index a1b47dd33..d23e680aa 100644
--- a/src/libcharon/plugins/ext_auth/Makefile.in
+++ b/src/libcharon/plugins/ext_auth/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in
index 2bfd38ba1..318400fc9 100644
--- a/src/libcharon/plugins/farp/Makefile.in
+++ b/src/libcharon/plugins/farp/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ 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@
@@ -364,6 +367,8 @@ 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@
diff --git a/src/libcharon/plugins/forecast/Makefile.am b/src/libcharon/plugins/forecast/Makefile.am
new file mode 100644
index 000000000..ce573135d
--- /dev/null
+++ b/src/libcharon/plugins/forecast/Makefile.am
@@ -0,0 +1,21 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS) $(libiptc_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-forecast.la
+else
+plugin_LTLIBRARIES = libstrongswan-forecast.la
+endif
+
+libstrongswan_forecast_la_SOURCES = \
+ forecast_listener.h forecast_listener.c \
+ forecast_forwarder.h forecast_forwarder.c \
+ forecast_plugin.h forecast_plugin.c
+
+libstrongswan_forecast_la_LDFLAGS = -module -avoid-version
+libstrongswan_forecast_la_LIBADD = $(libiptc_LIBS)
diff --git a/src/libcharon/plugins/forecast/Makefile.in b/src/libcharon/plugins/forecast/Makefile.in
new file mode 100644
index 000000000..7b190ca25
--- /dev/null
+++ b/src/libcharon/plugins/forecast/Makefile.in
@@ -0,0 +1,784 @@
+# 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/forecast
+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)
+am__DEPENDENCIES_1 =
+libstrongswan_forecast_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_forecast_la_OBJECTS = forecast_listener.lo \
+ forecast_forwarder.lo forecast_plugin.lo
+libstrongswan_forecast_la_OBJECTS = \
+ $(am_libstrongswan_forecast_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_forecast_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_forecast_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_forecast_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_forecast_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_forecast_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_forecast_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_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) $(libiptc_CFLAGS)
+
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-forecast.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-forecast.la
+libstrongswan_forecast_la_SOURCES = \
+ forecast_listener.h forecast_listener.c \
+ forecast_forwarder.h forecast_forwarder.c \
+ forecast_plugin.h forecast_plugin.c
+
+libstrongswan_forecast_la_LDFLAGS = -module -avoid-version
+libstrongswan_forecast_la_LIBADD = $(libiptc_LIBS)
+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/forecast/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/forecast/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-forecast.la: $(libstrongswan_forecast_la_OBJECTS) $(libstrongswan_forecast_la_DEPENDENCIES) $(EXTRA_libstrongswan_forecast_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_forecast_la_LINK) $(am_libstrongswan_forecast_la_rpath) $(libstrongswan_forecast_la_OBJECTS) $(libstrongswan_forecast_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forecast_forwarder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forecast_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forecast_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/forecast/forecast_forwarder.c b/src/libcharon/plugins/forecast/forecast_forwarder.c
new file mode 100644
index 000000000..07a3d4953
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_forwarder.c
@@ -0,0 +1,496 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "forecast_forwarder.h"
+
+#include <errno.h>
+#include <unistd.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <linux/socket.h>
+#include <netinet/if_ether.h>
+#include <linux/if_packet.h>
+#include <linux/filter.h>
+#include <sys/ioctl.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+
+#include <hydra.h>
+#include <daemon.h>
+#include <threading/thread.h>
+#include <processing/jobs/callback_job.h>
+
+#define BOOTP_SERVER_PORT 67
+#define BOOTP_CLIENT_PORT 68
+
+typedef struct private_forecast_forwarder_t private_forecast_forwarder_t;
+typedef struct private_kernel_listener_t private_kernel_listener_t;
+
+/**
+ * Private data of registered kernel listener
+ */
+struct private_kernel_listener_t {
+
+ /**
+ * Implements kernel_listener_t
+ */
+ kernel_listener_t listener;
+
+ /**
+ * Listener that knows active addresses
+ */
+ forecast_listener_t *fc;
+
+ /**
+ * current broadcast address of internal network
+ */
+ u_int32_t broadcast;
+
+ /**
+ * LAN interface index
+ */
+ int ifindex;
+
+ /**
+ * Packet socket
+ */
+ int pkt;
+
+ /**
+ * RAW socket
+ */
+ int raw;
+};
+
+/**
+ * Private data of an forecast_forwarder_t object.
+ */
+struct private_forecast_forwarder_t {
+
+ /**
+ * Public forecast_forwarder_t interface.
+ */
+ forecast_forwarder_t public;
+
+ /**
+ * Public kernel_listener_t interface.
+ */
+ private_kernel_listener_t kernel;
+};
+
+/**
+ * Send a broadcast/multicast packet to a network
+ */
+static void send_net(private_forecast_forwarder_t *this,
+ struct sockaddr_ll *addr, void *buf, size_t len)
+{
+ if (sendto(this->kernel.pkt, buf, len, 0,
+ (struct sockaddr*)addr, sizeof(*addr)) != len)
+ {
+ DBG1(DBG_NET, "forecast send_net() failed: %s", strerror(errno));
+ }
+}
+
+/**
+ * Send a broadcast/multicast packet to a peer
+ */
+static void send_peer(private_forecast_forwarder_t *this, u_int32_t dst,
+ void *buf, size_t len, int mark)
+{
+ struct sockaddr_in addr = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = dst,
+ };
+
+ if (setsockopt(this->kernel.raw, SOL_SOCKET, SO_MARK,
+ &mark, sizeof(mark)) != 0)
+ {
+ DBG1(DBG_NET, "forecast setting SO_MARK failed: %s", strerror(errno));
+ }
+ if (sendto(this->kernel.raw, buf, len, 0,
+ (struct sockaddr*)&addr, sizeof(addr)) != len)
+ {
+ DBG1(DBG_NET, "forecast send_peer() failed: %s", strerror(errno));
+ }
+}
+
+/**
+ * Check if an IP packet is BOOTP/DHCP
+ */
+static bool is_bootp(void *buf, size_t len)
+{
+ struct __attribute__((__packed__)) {
+ struct iphdr ip;
+ struct udphdr udp;
+ } *pkt = buf;
+
+ if (len > sizeof(*pkt))
+ {
+ if (ntohs(pkt->udp.source) == BOOTP_CLIENT_PORT &&
+ ntohs(pkt->udp.dest) == BOOTP_SERVER_PORT)
+ {
+ return TRUE;
+ }
+ if (ntohs(pkt->udp.source) == BOOTP_SERVER_PORT &&
+ ntohs(pkt->udp.dest) == BOOTP_CLIENT_PORT)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Broadcast/Multicast receiver
+ */
+static bool receive_casts(private_forecast_forwarder_t *this)
+{
+ struct __attribute__((packed)) {
+ struct iphdr hdr;
+ char data[2048];
+ } buf;
+ char *type;
+ ssize_t len;
+ u_int mark, origin = 0;
+ host_t *src, *dst;
+ traffic_selector_t *ts;
+ enumerator_t *enumerator;
+ struct sockaddr_ll addr;
+ socklen_t alen = sizeof(addr);
+ bool reinject;
+
+ len = recvfrom(this->kernel.pkt, &buf, sizeof(buf), MSG_DONTWAIT,
+ (struct sockaddr*)&addr, &alen);
+ if (len < 0)
+ {
+ if (errno != EAGAIN && errno != EWOULDBLOCK)
+ {
+ DBG1(DBG_NET, "receiving from forecast socket failed: %s",
+ strerror(errno));
+ }
+ return TRUE;
+ }
+ else if (len < sizeof(struct iphdr))
+ {
+ DBG1(DBG_NET, "received short forecast packet: %zd bytes", len);
+ return TRUE;
+ }
+ if (is_bootp(&buf, len))
+ { /* don't forward DHCP broadcasts */
+ return TRUE;
+ }
+
+ src = host_create_from_chunk(AF_INET, chunk_from_thing(buf.hdr.saddr), 0);
+ dst = host_create_from_chunk(AF_INET, chunk_from_thing(buf.hdr.daddr), 0);
+
+ /* create valid broadcast/multicast MAC to send out */
+ if (IN_MULTICAST(ntohl(buf.hdr.daddr)))
+ {
+ type = "multi";
+ ETHER_MAP_IP_MULTICAST(&buf.hdr.daddr, addr.sll_addr);
+ }
+ else
+ {
+ type = "broad";
+ memset(&addr.sll_addr, 0xFF, sizeof(addr.sll_addr));
+ }
+ DBG2(DBG_NET, "forecast intercepted packet: %H to %H", src, dst);
+
+ /* find mark of originating tunnel */
+ enumerator = this->kernel.fc->create_enumerator(this->kernel.fc, FALSE);
+ while (enumerator->enumerate(enumerator, &ts, &mark, &reinject))
+ {
+ if (ts->includes(ts, src))
+ {
+ origin = mark;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ /* send packet over all tunnels, but not the packets origin */
+ enumerator = this->kernel.fc->create_enumerator(this->kernel.fc, FALSE);
+ while (enumerator->enumerate(enumerator, &ts, &mark, &reinject))
+ {
+ if (ts->includes(ts, dst))
+ {
+ if ((reinject && origin != mark) || origin == 0)
+ {
+ DBG2(DBG_NET, "forwarding a %H %scast from %H to peer %R (%u)",
+ dst, type, src, ts, mark);
+ send_peer(this, buf.hdr.daddr, &buf, len, mark);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (origin)
+ {
+ /* forward broadcast/multicast from client to network */
+ DBG2(DBG_NET, "forwarding a %H %scast from peer %H to internal network",
+ dst, type, src);
+ addr.sll_ifindex = this->kernel.ifindex;
+ send_net(this, &addr, &buf, len);
+ }
+
+ dst->destroy(dst);
+ src->destroy(src);
+
+ return TRUE;
+}
+
+/**
+ * Join a multicast group
+ */
+static void join_group(private_kernel_listener_t *this, char *group,
+ struct sockaddr *addr)
+{
+ struct sockaddr_in *in;
+ struct ip_mreqn mreq;
+ host_t *host;
+
+ host = host_create_from_string(group, 0);
+ if (host)
+ {
+ memset(&mreq, 0, sizeof(mreq));
+ memcpy(&mreq.imr_multiaddr.s_addr, host->get_address(host).ptr, 4);
+ if (addr->sa_family == AF_INET)
+ {
+ in = (struct sockaddr_in*)addr;
+ memcpy(&mreq.imr_address, &in->sin_addr.s_addr,
+ sizeof(in->sin_addr.s_addr));
+ }
+ mreq.imr_ifindex = this->ifindex;
+ if (setsockopt(this->raw, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &mreq, sizeof(mreq)) == -1)
+ {
+ if (errno != EADDRINUSE)
+ {
+ DBG1(DBG_NET, "forecast multicast join to %s failed: %s",
+ group, strerror(errno));
+ }
+ }
+ else
+ {
+ DBG2(DBG_NET, "forwarding multicast group %s", group);
+ }
+ host->destroy(host);
+ }
+}
+
+/**
+ * (Re-)Join all multicast groups we want to forward
+ */
+static void join_groups(private_kernel_listener_t *this, struct sockaddr *addr)
+{
+ enumerator_t *enumerator;
+ char *groups, *group;
+ static char *def =
+ "224.0.0.1," /* host multicast */
+ "224.0.0.22," /* IGMP */
+ "224.0.0.251," /* mDNS */
+ "224.0.0.252," /* LLMNR */
+ "239.255.255.250"; /* SSDP/WS-discovery */
+
+ groups = lib->settings->get_str(lib->settings,
+ "%s.plugins.forecast.groups", def, lib->ns);
+ DBG1(DBG_CFG, "joining forecast multicast groups: %s", groups);
+ enumerator = enumerator_create_token(groups, ",", " ");
+ while (enumerator->enumerate(enumerator, &group))
+ {
+ join_group(this, group, addr);
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Attach the socket filter to the socket
+ */
+static bool attach_filter(int fd, u_int32_t broadcast)
+{
+ struct sock_filter filter_code[] = {
+ /* destination address: is ... */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct iphdr, daddr)),
+ /* broadcast, as received from the local network */
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ntohl(broadcast), 4, 0),
+ /* broadcast, as Win7 sends them */
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xFFFFFFFF, 3, 0),
+ /* any multicast, 224.0.0.0/4 */
+ BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xF0000000),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xE0000000, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+ };
+ struct sock_fprog filter = {
+ sizeof(filter_code) / sizeof(struct sock_filter),
+ filter_code,
+ };
+
+ if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER,
+ &filter, sizeof(filter)) < 0)
+ {
+ DBG1(DBG_NET, "installing forecast PACKET socket filter failed: %s",
+ strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Get the interface index of an interface name
+ */
+static int get_ifindex(private_kernel_listener_t *this, char *ifname)
+{
+ struct ifreq ifr = {};
+
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ if (ioctl(this->raw, SIOCGIFINDEX, &ifr) == 0)
+ {
+ return ifr.ifr_ifindex;
+ }
+ return 0;
+}
+
+/**
+ * Set up the interface for broad/multicast forwarding
+ */
+static void setup_interface(private_kernel_listener_t *this)
+{
+ struct ifaddrs *addrs, *current;
+ struct sockaddr_in *in;
+ host_t *host;
+ char *name;
+
+ name = lib->settings->get_str(lib->settings,
+ "%s.plugins.forecast.interface", NULL, lib->ns);
+ if (getifaddrs(&addrs) == 0)
+ {
+ for (current = addrs; current; current = current->ifa_next)
+ {
+ if (name && !streq(name, current->ifa_name))
+ {
+ continue;
+ }
+ if (current->ifa_flags & IFF_BROADCAST &&
+ current->ifa_broadaddr &&
+ current->ifa_broadaddr->sa_family == AF_INET)
+ {
+ DBG1(DBG_NET, "using forecast interface %s", current->ifa_name);
+ this->ifindex = get_ifindex(this, current->ifa_name);
+ in = (struct sockaddr_in*)current->ifa_broadaddr;
+ attach_filter(this->pkt, in->sin_addr.s_addr);
+ join_groups(this, current->ifa_addr);
+ host = host_create_from_sockaddr(current->ifa_broadaddr);
+ if (host)
+ {
+ this->fc->set_broadcast(this->fc, host);
+ host->destroy(host);
+ }
+ break;
+ }
+ }
+ }
+ freeifaddrs(addrs);
+}
+
+METHOD(kernel_listener_t, roam, bool,
+ private_kernel_listener_t *this, bool address)
+{
+ if (address)
+ {
+ setup_interface(this);
+ }
+ return TRUE;
+}
+
+METHOD(forecast_forwarder_t, destroy, void,
+ private_forecast_forwarder_t *this)
+{
+ if (this->kernel.raw != -1)
+ {
+ close(this->kernel.raw);
+ }
+ if (this->kernel.pkt != -1)
+ {
+ lib->watcher->remove(lib->watcher, this->kernel.pkt);
+ close(this->kernel.pkt);
+ }
+ hydra->kernel_interface->remove_listener(hydra->kernel_interface,
+ &this->kernel.listener);
+ free(this);
+}
+
+/**
+ * See header
+ */
+forecast_forwarder_t *forecast_forwarder_create(forecast_listener_t *listener)
+{
+ private_forecast_forwarder_t *this;
+ int on = 1;
+
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ },
+ .kernel = {
+ .listener = {
+ .roam = _roam,
+ },
+ .raw = -1,
+ .pkt = -1,
+ .fc = listener,
+ },
+ );
+
+ this->kernel.pkt = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
+ if (this->kernel.pkt == -1)
+ {
+ DBG1(DBG_NET, "opening PACKET socket failed: %s", strerror(errno));
+ destroy(this);
+ return NULL;
+ }
+ this->kernel.raw = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+ if (this->kernel.raw == -1)
+ {
+ DBG1(DBG_NET, "opening RAW socket failed: %s", strerror(errno));
+ destroy(this);
+ return NULL;
+ }
+ if (setsockopt(this->kernel.raw, IPPROTO_IP, IP_HDRINCL,
+ &on, sizeof(on)) == -1)
+ {
+ DBG1(DBG_NET, "forecast socket HDRINCL failed: %s", strerror(errno));
+ destroy(this);
+ return NULL;
+ }
+ if (setsockopt(this->kernel.raw, SOL_SOCKET, SO_BROADCAST,
+ &on, sizeof(on)) == -1)
+ {
+ DBG1(DBG_NET, "forecast socket BROADCAST failed: %s", strerror(errno));
+ destroy(this);
+ return NULL;
+ }
+
+ setup_interface(&this->kernel);
+
+ hydra->kernel_interface->add_listener(hydra->kernel_interface,
+ &this->kernel.listener);
+
+ lib->watcher->add(lib->watcher, this->kernel.pkt, WATCHER_READ,
+ (watcher_cb_t)receive_casts, this);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/forecast/forecast_forwarder.h b/src/libcharon/plugins/forecast/forecast_forwarder.h
new file mode 100644
index 000000000..14d107361
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_forwarder.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup forecast_forwarder forecast_forwarder
+ * @{ @ingroup forecast
+ */
+
+#ifndef FORECAST_FORWARDER_H_
+#define FORECAST_FORWARDER_H_
+
+#include "forecast_listener.h"
+
+typedef struct forecast_forwarder_t forecast_forwarder_t;
+
+/**
+ * Broadcast/Multicast sniffer and forwarder.
+ */
+struct forecast_forwarder_t {
+
+ /**
+ * Destroy a forecast_forwarder_t.
+ */
+ void (*destroy)(forecast_forwarder_t *this);
+};
+
+/**
+ * Create a forecast_forwarder instance.
+ *
+ * @param listener listener to check for addresses to forward to
+ * @return forwarder instance
+ */
+forecast_forwarder_t *forecast_forwarder_create(forecast_listener_t *listener);
+
+#endif /** FORECAST_FORWARDER_H_ @}*/
diff --git a/src/libcharon/plugins/forecast/forecast_listener.c b/src/libcharon/plugins/forecast/forecast_listener.c
new file mode 100644
index 000000000..63a8cb15b
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_listener.c
@@ -0,0 +1,680 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "forecast_listener.h"
+
+#include <errno.h>
+#include <libiptc/libiptc.h>
+#include <linux/netfilter/xt_MARK.h>
+#include <linux/netfilter/xt_esp.h>
+
+#include <daemon.h>
+#include <collections/array.h>
+#include <collections/hashtable.h>
+#include <threading/rwlock.h>
+
+typedef struct private_forecast_listener_t private_forecast_listener_t;
+
+/**
+ * Private data of an forecast_listener_t object.
+ */
+struct private_forecast_listener_t {
+
+ /**
+ * Public forecast_listener_t interface.
+ */
+ forecast_listener_t public;
+
+ /**
+ * List of entries
+ */
+ linked_list_t *entries;
+
+ /**
+ * RWlock for IP list
+ */
+ rwlock_t *lock;
+
+ /**
+ * Configs we do reinjection
+ */
+ char *reinject_configs;
+
+ /**
+ * Broadcast address on LAN interface, network order
+ */
+ u_int32_t broadcast;
+};
+
+/**
+ * Hashtable entry
+ */
+typedef struct {
+ /** local traffic selectors */
+ array_t *lts;
+ /** remote traffic selectors */
+ array_t *rts;
+ /** firewall mark used by CHILD_SA */
+ u_int mark;
+ /** local IKE_SA endpoint */
+ host_t *lhost;
+ /** remote IKE_SA endpoint */
+ host_t *rhost;
+ /** inbound SPI */
+ u_int32_t spi;
+ /** use UDP encapsulation */
+ bool encap;
+ /** whether we should allow reencapsulation of IPsec received forecasts */
+ bool reinject;
+ /** broadcast address used for that entry */
+ u_int32_t broadcast;
+} entry_t;
+
+/**
+ * Destroy an entry
+ */
+static void entry_destroy(entry_t *entry)
+{
+ if (entry)
+ {
+ entry->lhost->destroy(entry->lhost);
+ entry->rhost->destroy(entry->rhost);
+ array_destroy_offset(entry->lts, offsetof(traffic_selector_t, destroy));
+ array_destroy_offset(entry->rts, offsetof(traffic_selector_t, destroy));
+ free(entry);
+ }
+}
+
+/**
+ * Convert an (IPv4) traffic selector to an address and mask
+ */
+static bool ts2in(traffic_selector_t *ts,
+ struct in_addr *addr, struct in_addr *mask)
+{
+ u_int8_t bits;
+ host_t *net;
+
+ if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE &&
+ ts->to_subnet(ts, &net, &bits))
+ {
+ memcpy(&addr->s_addr, net->get_address(net).ptr, 4);
+ net->destroy(net);
+ mask->s_addr = htonl(0xffffffffU << (32 - bits));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Convert an (IPv4) host to an address with mask
+ */
+static bool host2in(host_t *host, struct in_addr *addr, struct in_addr *mask)
+{
+ if (host->get_family(host) == AF_INET)
+ {
+ memcpy(&addr->s_addr, host->get_address(host).ptr, 4);
+ mask->s_addr = ~0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Add or remove a rule to/from the specified chain
+ */
+static bool manage_rule(struct iptc_handle *ipth, const char *chain,
+ bool add, struct ipt_entry *e)
+{
+ if (add)
+ {
+ if (!iptc_insert_entry(chain, e, 0, ipth))
+ {
+ DBG1(DBG_CFG, "appending %s rule failed: %s",
+ chain, iptc_strerror(errno));
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!iptc_delete_entry(chain, e, "", ipth))
+ {
+ DBG1(DBG_CFG, "deleting %s rule failed: %s",
+ chain, iptc_strerror(errno));
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Add rule marking UDP-encapsulated ESP packets to match the correct policy
+ */
+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,
+ },
+ },
+ .m = {
+ .u = {
+ .user = {
+ .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)),
+ .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)
+ },
+ },
+ .t = {
+ .u = {
+ .user = {
+ .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)),
+ .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 rule marking non-encapsulated ESP packets to match the correct policy
+ */
+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,
+ },
+ },
+ .m = {
+ .u = {
+ .user = {
+ .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)),
+ .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,
+ },
+ },
+ },
+ .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 rule marking ESP packets to match the correct policy
+ */
+static bool manage_pre(struct iptc_handle *ipth, entry_t *entry, bool add)
+{
+ if (entry->encap)
+ {
+ return manage_pre_esp_in_udp(ipth, entry, add);
+ }
+ return manage_pre_esp(ipth, entry, add);
+}
+
+/**
+ * Add rule handling outbound traffic to use correct mark
+ */
+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,
+ },
+ };
+ 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))
+ {
+ 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))
+ {
+ /* 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))
+ {
+ enumerator->destroy(enumerator);
+ return FALSE;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return TRUE;
+}
+
+/**
+ * Check if config is whitelisted to reinject traffic
+ */
+static bool is_reinject_config(private_forecast_listener_t *this, char *name)
+{
+ enumerator_t *enumerator;
+ bool reinject = FALSE;
+ char *token;
+
+ enumerator = enumerator_create_token(this->reinject_configs, ",", " ");
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ if (streq(token, name))
+ {
+ reinject = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return reinject;
+}
+
+/**
+ * Add rules and entry for given CHILD_SA
+ */
+static bool add_entry(private_forecast_listener_t *this,
+ struct iptc_handle *ipth, host_t *lhost, host_t *rhost,
+ child_sa_t *child_sa, bool encap)
+{
+ enumerator_t *enumerator;
+ traffic_selector_t *ts;
+ entry_t *entry;
+
+ INIT(entry,
+ .lts = array_create(0, 0),
+ .rts = array_create(0, 0),
+ .lhost = lhost->clone(lhost),
+ .rhost = rhost->clone(rhost),
+ .spi = child_sa->get_spi(child_sa, TRUE),
+ .encap = encap,
+ .mark = child_sa->get_mark(child_sa, TRUE).value,
+ .reinject = is_reinject_config(this, child_sa->get_name(child_sa)),
+ .broadcast = this->broadcast,
+ );
+
+ enumerator = child_sa->create_ts_enumerator(child_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &ts))
+ {
+ array_insert(entry->lts, ARRAY_TAIL, ts->clone(ts));
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = child_sa->create_ts_enumerator(child_sa, FALSE);
+ while (enumerator->enumerate(enumerator, &ts))
+ {
+ array_insert(entry->rts, ARRAY_TAIL, ts->clone(ts));
+ }
+ enumerator->destroy(enumerator);
+
+ if (manage_pre(ipth, entry, TRUE) &&
+ manage_out(ipth, entry, TRUE))
+ {
+ this->lock->write_lock(this->lock);
+ this->entries->insert_last(this->entries, entry);
+ this->lock->unlock(this->lock);
+ return TRUE;
+ }
+ entry_destroy(entry);
+ return FALSE;
+}
+
+/**
+ * Remove an entry and rules for a given mark
+ */
+static bool remove_entry(private_forecast_listener_t *this,
+ struct iptc_handle *ipth, child_sa_t *child_sa)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ bool done = FALSE;
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->entries->create_enumerator(this->entries);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->mark == child_sa->get_mark(child_sa, TRUE).value)
+ {
+ this->entries->remove_at(this->entries, enumerator);
+ if (manage_pre(ipth, entry, FALSE) &&
+ manage_out(ipth, entry, FALSE))
+ {
+ done = TRUE;
+ }
+ entry_destroy(entry);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
+ return done;
+}
+
+/**
+ * Initialize iptables handle, log error
+ */
+static struct iptc_handle* init_handle()
+{
+ struct iptc_handle *ipth;
+
+ ipth = iptc_init("mangle");
+ if (ipth)
+ {
+ return ipth;
+ }
+ DBG1(DBG_CFG, "initializing iptables failed: %s", iptc_strerror(errno));
+ return NULL;
+}
+
+/**
+ * Commit iptables rules, log error
+ */
+static bool commit_handle(struct iptc_handle *ipth)
+{
+ if (iptc_commit(ipth))
+ {
+ return TRUE;
+ }
+ DBG1(DBG_CFG, "forecast iptables commit failed: %s", iptc_strerror(errno));
+ return FALSE;
+}
+
+/**
+ * Check if we should handle the given CHILD_SA
+ */
+static bool handle_sa(child_sa_t *child_sa)
+{
+ return child_sa->get_mark(child_sa, TRUE).value &&
+ child_sa->get_mark(child_sa, FALSE).value;
+}
+
+METHOD(listener_t, child_updown, bool,
+ private_forecast_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ bool up)
+{
+ struct iptc_handle *ipth;
+ host_t *lhost, *rhost;
+ bool encap;
+
+ lhost = ike_sa->get_my_host(ike_sa);
+ rhost = ike_sa->get_other_host(ike_sa);
+ encap = child_sa->has_encap(child_sa);
+
+ if (handle_sa(child_sa))
+ {
+ ipth = init_handle();
+ if (ipth)
+ {
+ if (up)
+ {
+ if (add_entry(this, ipth, lhost, rhost, child_sa, encap))
+ {
+ commit_handle(ipth);
+ }
+ }
+ else
+ {
+ if (remove_entry(this, ipth, child_sa))
+ {
+ commit_handle(ipth);
+ }
+ }
+ iptc_free(ipth);
+ }
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, child_rekey, bool,
+ private_forecast_listener_t *this, ike_sa_t *ike_sa,
+ child_sa_t *old, child_sa_t *new)
+{
+ struct iptc_handle *ipth;;
+ host_t *lhost, *rhost;
+
+ lhost = ike_sa->get_my_host(ike_sa);
+ rhost = ike_sa->get_other_host(ike_sa);
+
+ if (handle_sa(old))
+ {
+ ipth = init_handle();
+ if (ipth)
+ {
+ if (remove_entry(this, ipth, old) &&
+ add_entry(this, ipth, lhost, rhost, new, new->has_encap(new)))
+ {
+ commit_handle(ipth);
+ }
+ iptc_free(ipth);
+ }
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, ike_update, bool,
+ private_forecast_listener_t *this, ike_sa_t *ike_sa,
+ bool local, host_t *new)
+{
+ struct iptc_handle *ipth;
+ enumerator_t *enumerator;
+ child_sa_t *child_sa;
+ host_t *lhost, *rhost;
+ bool encap;
+
+ if (local)
+ {
+ lhost = new;
+ rhost = ike_sa->get_other_host(ike_sa);
+ }
+ else
+ {
+ lhost = ike_sa->get_my_host(ike_sa);
+ rhost = new;
+ }
+ /* during ike_update(), has_encap() on the CHILD_SA has not yet been
+ * updated, but shows the old state. */
+ encap = ike_sa->has_condition(ike_sa, COND_NAT_ANY);
+
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, &child_sa))
+ {
+ if (handle_sa(child_sa))
+ {
+ ipth = init_handle();
+ if (ipth)
+ {
+ if (remove_entry(this, ipth, child_sa) &&
+ add_entry(this, ipth, lhost, rhost, child_sa, encap))
+ {
+ commit_handle(ipth);
+ }
+ iptc_free(ipth);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return TRUE;
+}
+
+/**
+ * Filter to map entries to ts/mark
+ */
+static bool ts_filter(entry_t *entry, traffic_selector_t **ts,
+ traffic_selector_t **out, void *dummy, u_int32_t *mark,
+ void *dummy2, bool *reinject)
+{
+ *out = *ts;
+ *mark = entry->mark;
+ *reinject = entry->reinject;
+ return TRUE;
+}
+
+/**
+ * Create inner enumerator over local traffic selectors
+ */
+static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock)
+{
+ return enumerator_create_filter(array_create_enumerator(entry->lts),
+ (void*)ts_filter, entry, NULL);
+}
+
+/**
+ * Create inner enumerator over remote traffic selectors
+ */
+static enumerator_t* create_inner_remote(entry_t *entry, rwlock_t *lock)
+{
+ return enumerator_create_filter(array_create_enumerator(entry->rts),
+ (void*)ts_filter, entry, NULL);
+}
+
+METHOD(forecast_listener_t, create_enumerator, enumerator_t*,
+ private_forecast_listener_t *this, bool local)
+{
+ this->lock->read_lock(this->lock);
+ return enumerator_create_nested(
+ this->entries->create_enumerator(this->entries),
+ (void*)(local ? create_inner_local : create_inner_remote),
+ this->lock, (void*)this->lock->unlock);
+}
+
+METHOD(forecast_listener_t, set_broadcast, void,
+ private_forecast_listener_t *this, host_t *bcast)
+{
+ if (bcast->get_family(bcast) == AF_INET)
+ {
+ struct sockaddr_in *in;
+
+ in = (struct sockaddr_in*)bcast->get_sockaddr(bcast);
+ this->broadcast = in->sin_addr.s_addr;
+ }
+}
+
+METHOD(forecast_listener_t, destroy, void,
+ private_forecast_listener_t *this)
+{
+ this->entries->destroy(this->entries);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/**
+ * See header
+ */
+forecast_listener_t *forecast_listener_create()
+{
+ private_forecast_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_update = _ike_update,
+ .child_updown = _child_updown,
+ .child_rekey = _child_rekey,
+ },
+ .create_enumerator = _create_enumerator,
+ .set_broadcast = _set_broadcast,
+ .destroy = _destroy,
+ },
+ .entries = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .reinject_configs = lib->settings->get_str(lib->settings,
+ "%s.plugins.forecast.reinject", "", lib->ns),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/forecast/forecast_listener.h b/src/libcharon/plugins/forecast/forecast_listener.h
new file mode 100644
index 000000000..49827ecb1
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_listener.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup forecast_listener forecast_listener
+ * @{ @ingroup forecast
+ */
+
+#ifndef FORECAST_LISTENER_H_
+#define FORECAST_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct forecast_listener_t forecast_listener_t;
+
+/**
+ * Listener to register the set of IPs we forward received multi/broadcasts to.
+ */
+struct forecast_listener_t {
+
+ /**
+ * Implements listener_t interface.
+ */
+ listener_t listener;
+
+ /**
+ * Create an enumerator over active tunnels.
+ *
+ * The enumerator enumerates over local or remote traffic selectors,
+ * associated firewall marks and if decasulated packets should get
+ * reinjected into other tunnels.
+ *
+ * @param local TRUE to enumerate local, FALSE to enumerate remote TS
+ * @return enumerator over (traffic_selector_t*, u_int, bool)
+ */
+ enumerator_t* (*create_enumerator)(forecast_listener_t *this, bool local);
+
+ /**
+ * Set the broadcast address of the LAN interface.
+ *
+ * @param bcast broadcast address
+ */
+ void (*set_broadcast)(forecast_listener_t *this, host_t *bcast);
+
+ /**
+ * Destroy a forecast_listener_t.
+ */
+ void (*destroy)(forecast_listener_t *this);
+};
+
+/**
+ * Create a forecast_listener instance.
+ */
+forecast_listener_t *forecast_listener_create();
+
+#endif /** FORECAST_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/forecast/forecast_plugin.c b/src/libcharon/plugins/forecast/forecast_plugin.c
new file mode 100644
index 000000000..a129b76b2
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_plugin.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "forecast_plugin.h"
+#include "forecast_listener.h"
+#include "forecast_forwarder.h"
+
+#include <daemon.h>
+
+typedef struct private_forecast_plugin_t private_forecast_plugin_t;
+
+/**
+ * Private data of forecast plugin
+ */
+struct private_forecast_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ forecast_plugin_t public;
+
+ /**
+ * Listener registering active tunnels
+ */
+ forecast_listener_t *listener;
+
+ /**
+ * Broadcast/Multicast sniffer and forwarder
+ */
+ forecast_forwarder_t *forwarder;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_forecast_plugin_t *this)
+{
+ return "forecast";
+}
+
+/**
+ * Register plugin features
+ */
+static bool register_forecast(private_forecast_plugin_t *this,
+ plugin_feature_t *feature, bool reg, void *data)
+{
+ if (reg)
+ {
+ this->forwarder = forecast_forwarder_create(this->listener);
+ if (!this->forwarder)
+ {
+ return FALSE;
+ }
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+ }
+ else
+ {
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->forwarder->destroy(this->forwarder);
+ }
+ return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_forecast_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((plugin_feature_callback_t)register_forecast, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "forecast"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_forecast_plugin_t *this)
+{
+ this->listener->destroy(this->listener);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *forecast_plugin_create()
+{
+ private_forecast_plugin_t *this;
+
+ if (!lib->caps->keep(lib->caps, CAP_NET_RAW))
+ {
+ DBG1(DBG_NET, "forecast plugin requires CAP_NET_RAW capability");
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .listener = forecast_listener_create(),
+ );
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/forecast/forecast_plugin.h b/src/libcharon/plugins/forecast/forecast_plugin.h
new file mode 100644
index 000000000..739ca4d79
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup forecast forecast
+ * @ingroup cplugins
+ *
+ * @defgroup forecast_plugin forecast_plugin
+ * @{ @ingroup forecast
+ */
+
+#ifndef FORECAST_PLUGIN_H_
+#define FORECAST_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct forecast_plugin_t forecast_plugin_t;
+
+/**
+ * Broadcast/Multicast forwarding plugin.
+ */
+struct forecast_plugin_t {
+
+ /**
+ * Implements plugin interface.
+ */
+ plugin_t plugin;
+};
+
+#endif /** FORECAST_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in
index aa5bdb747..de74f88cc 100644
--- a/src/libcharon/plugins/ha/Makefile.in
+++ b/src/libcharon/plugins/ha/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/ha/ha_attribute.c b/src/libcharon/plugins/ha/ha_attribute.c
index dd55fae8b..2b271a8e7 100644
--- a/src/libcharon/plugins/ha/ha_attribute.c
+++ b/src/libcharon/plugins/ha/ha_attribute.c
@@ -170,7 +170,7 @@ static bool responsible_for(private_ha_attribute_t *this, int bit)
}
METHOD(attribute_provider_t, acquire_address, host_t*,
- private_ha_attribute_t *this, linked_list_t *pools, identification_t *id,
+ private_ha_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
host_t *requested)
{
enumerator_t *enumerator;
@@ -233,7 +233,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
METHOD(attribute_provider_t, release_address, bool,
private_ha_attribute_t *this, linked_list_t *pools, host_t *address,
- identification_t *id)
+ ike_sa_t *ike_sa)
{
enumerator_t *enumerator;
pool_t *pool;
diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c
index 60e75fc7e..6c1b3471d 100644
--- a/src/libcharon/plugins/ha/ha_cache.c
+++ b/src/libcharon/plugins/ha/ha_cache.c
@@ -196,9 +196,26 @@ static status_t rekey_children(ike_sa_t *ike_sa)
enumerator_t *enumerator;
child_sa_t *child_sa;
status_t status = SUCCESS;
+ linked_list_t *children;
+ struct {
+ protocol_id_t protocol;
+ u_int32_t spi;
+ } *info;
+ children = linked_list_create();
enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
- while (enumerator->enumerate(enumerator, (void**)&child_sa))
+ while (enumerator->enumerate(enumerator, &child_sa))
+ {
+ INIT(info,
+ .protocol = child_sa->get_protocol(child_sa),
+ .spi = child_sa->get_spi(child_sa, TRUE),
+ );
+ children->insert_last(children, info);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = children->create_enumerator(children);
+ while (enumerator->enumerate(enumerator, &info))
{
if (ike_sa->supports_extension(ike_sa, EXT_MS_WINDOWS) &&
ike_sa->has_condition(ike_sa, COND_NAT_THERE))
@@ -207,17 +224,13 @@ static status_t rekey_children(ike_sa_t *ike_sa)
* with an "invalid situation" error. We just close the CHILD_SA,
* Windows will reestablish it immediately if required. */
DBG1(DBG_CFG, "resyncing CHILD_SA using a delete");
- status = ike_sa->delete_child_sa(ike_sa,
- child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE),
+ status = ike_sa->delete_child_sa(ike_sa, info->protocol, info->spi,
FALSE);
}
else
{
DBG1(DBG_CFG, "resyncing CHILD_SA using a rekey");
- status = ike_sa->rekey_child_sa(ike_sa,
- child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE));
+ status = ike_sa->rekey_child_sa(ike_sa, info->protocol, info->spi);
}
if (status == DESTROY_ME)
{
@@ -225,6 +238,8 @@ static status_t rekey_children(ike_sa_t *ike_sa)
}
}
enumerator->destroy(enumerator);
+ children->destroy_function(children, free);
+
return status;
}
diff --git a/src/libcharon/plugins/ha/ha_child.c b/src/libcharon/plugins/ha/ha_child.c
index c166d72ac..17f2d50d1 100644
--- a/src/libcharon/plugins/ha/ha_child.c
+++ b/src/libcharon/plugins/ha/ha_child.c
@@ -97,7 +97,7 @@ METHOD(listener_t, child_keys, bool,
}
m->add_attribute(m, HA_NONCE_I, nonce_i);
m->add_attribute(m, HA_NONCE_R, nonce_r);
- if (dh && dh->get_shared_secret(dh, &secret) == SUCCESS)
+ if (dh && dh->get_shared_secret(dh, &secret))
{
m->add_attribute(m, HA_SECRET, secret);
chunk_clear(&secret);
@@ -128,7 +128,7 @@ METHOD(listener_t, child_keys, bool,
ike_sa->get_other_host(ike_sa), child_sa->get_spi(child_sa, FALSE));
DBG1(DBG_CFG, "handling HA CHILD_SA %s{%d} %#R=== %#R "
"(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa),
- child_sa->get_reqid(child_sa), local_ts, remote_ts,
+ child_sa->get_unique_id(child_sa), local_ts, remote_ts,
seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "",
seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : "");
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index e20e872c1..31eeb934e 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -81,17 +81,18 @@ struct ha_diffie_hellman_t {
chunk_t pub;
};
-METHOD(diffie_hellman_t, dh_get_shared_secret, status_t,
+METHOD(diffie_hellman_t, dh_get_shared_secret, bool,
ha_diffie_hellman_t *this, chunk_t *secret)
{
*secret = chunk_clone(this->secret);
- return SUCCESS;
+ return TRUE;
}
-METHOD(diffie_hellman_t, dh_get_my_public_value, void,
+METHOD(diffie_hellman_t, dh_get_my_public_value, bool,
ha_diffie_hellman_t *this, chunk_t *value)
{
*value = chunk_clone(this->pub);
+ return TRUE;
}
METHOD(diffie_hellman_t, dh_destroy, void,
@@ -373,6 +374,9 @@ static void process_ike_update(private_ha_dispatcher_t *this,
else
{
DBG1(DBG_IKE, "HA is missing nodes peer configuration");
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
+ ike_sa = NULL;
}
break;
case HA_EXTENSIONS:
@@ -718,7 +722,8 @@ static void process_child_add(private_ha_dispatcher_t *this,
child_sa = child_sa_create(ike_sa->get_my_host(ike_sa),
ike_sa->get_other_host(ike_sa), config, 0,
- ike_sa->has_condition(ike_sa, COND_NAT_ANY));
+ ike_sa->has_condition(ike_sa, COND_NAT_ANY),
+ 0, 0);
child_sa->set_mode(child_sa, mode);
child_sa->set_protocol(child_sa, PROTO_ESP);
child_sa->set_ipcomp(child_sa, ipcomp);
@@ -835,7 +840,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
DBG1(DBG_CFG, "installed HA CHILD_SA %s{%d} %#R=== %#R "
"(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa),
- child_sa->get_reqid(child_sa), local_ts, remote_ts,
+ child_sa->get_unique_id(child_sa), local_ts, remote_ts,
seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "",
seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : "");
child_sa->add_policies(child_sa, local_ts, remote_ts);
diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c
index 442a3a23d..6b4b53c9c 100644
--- a/src/libcharon/plugins/ha/ha_ike.c
+++ b/src/libcharon/plugins/ha/ha_ike.c
@@ -84,7 +84,7 @@ METHOD(listener_t, ike_keys, bool,
{ /* do not sync SA between nodes */
return TRUE;
}
- if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+ if (!dh->get_shared_secret(dh, &secret))
{
return TRUE;
}
@@ -127,9 +127,11 @@ METHOD(listener_t, ike_keys, bool,
chunk_clear(&secret);
if (ike_sa->get_version(ike_sa) == IKEV1)
{
- dh->get_my_public_value(dh, &secret);
- m->add_attribute(m, HA_LOCAL_DH, secret);
- chunk_free(&secret);
+ if (dh->get_my_public_value(dh, &secret))
+ {
+ m->add_attribute(m, HA_LOCAL_DH, secret);
+ chunk_free(&secret);
+ }
m->add_attribute(m, HA_REMOTE_DH, dh_other);
if (shared)
{
diff --git a/src/libcharon/plugins/ha/ha_plugin.c b/src/libcharon/plugins/ha/ha_plugin.c
index 493cad5ec..a58377bab 100644
--- a/src/libcharon/plugins/ha/ha_plugin.c
+++ b/src/libcharon/plugins/ha/ha_plugin.c
@@ -25,7 +25,6 @@
#include "ha_attribute.h"
#include <daemon.h>
-#include <hydra.h>
#include <config/child_cfg.h>
typedef struct private_ha_plugin_t private_ha_plugin_t;
@@ -108,13 +107,13 @@ static bool plugin_cb(private_ha_plugin_t *this,
charon->bus->add_listener(charon->bus, &this->segments->listener);
charon->bus->add_listener(charon->bus, &this->ike->listener);
charon->bus->add_listener(charon->bus, &this->child->listener);
- hydra->attributes->add_provider(hydra->attributes,
- &this->attr->provider);
+ charon->attributes->add_provider(charon->attributes,
+ &this->attr->provider);
}
else
{
- hydra->attributes->remove_provider(hydra->attributes,
- &this->attr->provider);
+ charon->attributes->remove_provider(charon->attributes,
+ &this->attr->provider);
charon->bus->remove_listener(charon->bus, &this->segments->listener);
charon->bus->remove_listener(charon->bus, &this->ike->listener);
charon->bus->remove_listener(charon->bus, &this->child->listener);
@@ -224,4 +223,3 @@ plugin_t *ha_plugin_create()
return &this->public.plugin;
}
-
diff --git a/src/libcharon/plugins/ipseckey/Makefile.in b/src/libcharon/plugins/ipseckey/Makefile.in
index bd3fd63aa..f98e78ffc 100644
--- a/src/libcharon/plugins/ipseckey/Makefile.in
+++ b/src/libcharon/plugins/ipseckey/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/kernel_iph/Makefile.in b/src/libcharon/plugins/kernel_iph/Makefile.in
index 7e1f79bd8..7a2583d06 100644
--- a/src/libcharon/plugins/kernel_iph/Makefile.in
+++ b/src/libcharon/plugins/kernel_iph/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.in b/src/libcharon/plugins/kernel_libipsec/Makefile.in
index c961c0bd8..6b6c95688 100644
--- a/src/libcharon/plugins/kernel_libipsec/Makefile.in
+++ b/src/libcharon/plugins/kernel_libipsec/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ 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@
@@ -368,6 +371,8 @@ 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@
diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
index bd07a67a2..6246dc505 100644
--- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
+++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
@@ -222,10 +222,10 @@ static inline bool policy_entry_equals(policy_entry_t *a,
/**
* Expiration callback
*/
-static void expire(u_int32_t reqid, u_int8_t protocol, u_int32_t spi, bool hard)
+static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard)
{
- hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
- spi, hard);
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi, dst, hard);
}
METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
@@ -236,14 +236,14 @@ METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
METHOD(kernel_ipsec_t, get_spi, status_t,
private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+ u_int8_t protocol, u_int32_t *spi)
{
- return ipsec->sas->get_spi(ipsec->sas, src, dst, protocol, reqid, spi);
+ return ipsec->sas->get_spi(ipsec->sas, src, dst, protocol, spi);
}
METHOD(kernel_ipsec_t, get_cpi, status_t,
private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ u_int16_t *cpi)
{
return NOT_SUPPORTED;
}
@@ -254,13 +254,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
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,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ bool initiator, bool encap, bool esn, bool inbound, bool update,
+ linked_list_t *src_ts, linked_list_t *dst_ts)
{
return ipsec->sas->add_sa(ipsec->sas, src, dst, spi, protocol, reqid, mark,
tfc, lifetime, enc_alg, enc_key, int_alg, int_key,
- mode, ipcomp, cpi, initiator, encap, esn, inbound,
- src_ts, dst_ts);
+ mode, ipcomp, cpi, initiator, encap, esn,
+ inbound, update);
}
METHOD(kernel_ipsec_t, update_sa, status_t,
diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
index 6ce1d4eb0..830954e11 100644
--- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
+++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
@@ -131,35 +131,6 @@ static void deliver_plain(private_kernel_libipsec_router_t *this,
}
/**
- * Create an FD set covering all TUN devices and the read end of the notify pipe
- */
-static int collect_fds(private_kernel_libipsec_router_t *this, fd_set *fds)
-{
- enumerator_t *enumerator;
- tun_entry_t *entry;
- int maxfd;
-
- FD_ZERO(fds);
- FD_SET(this->notify[0], fds);
- maxfd = this->notify[0];
-
- FD_SET(this->tun.fd, fds);
- maxfd = max(maxfd, this->tun.fd);
-
- this->lock->read_lock(this->lock);
- enumerator = this->tuns->create_enumerator(this->tuns);
- while (enumerator->enumerate(enumerator, NULL, &entry))
- {
- FD_SET(entry->fd, fds);
- maxfd = max(maxfd, entry->fd);
- }
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
-
- return maxfd + 1;
-}
-
-/**
* Read and process outbound plaintext packet for the given TUN device
*/
static void process_plain(tun_device_t *tun)
@@ -183,29 +154,20 @@ static void process_plain(tun_device_t *tun)
}
/**
- * Handle waiting data for any TUN device
+ * Find flagged revents in a pollfd set by fd
*/
-static void handle_tuns(private_kernel_libipsec_router_t *this, fd_set *fds)
+static int find_revents(struct pollfd *pfd, int count, int fd)
{
- enumerator_t *enumerator;
- tun_entry_t *entry;
+ int i;
- if (FD_ISSET(this->tun.fd, fds))
+ for (i = 0; i < count; i++)
{
- process_plain(this->tun.tun);
- }
-
- this->lock->read_lock(this->lock);
- enumerator = this->tuns->create_enumerator(this->tuns);
- while (enumerator->enumerate(enumerator, NULL, &entry))
- {
- if (FD_ISSET(entry->fd, fds))
+ if (pfd[i].fd == fd)
{
- process_plain(entry->tun);
+ return pfd[i].revents;
}
}
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
+ return 0;
}
/**
@@ -213,28 +175,68 @@ static void handle_tuns(private_kernel_libipsec_router_t *this, fd_set *fds)
*/
static job_requeue_t handle_plain(private_kernel_libipsec_router_t *this)
{
+ enumerator_t *enumerator;
+ tun_entry_t *entry;
bool oldstate;
- fd_set fds;
- int maxfd;
+ int count = 0;
+ char buf[1];
+ struct pollfd *pfd;
+
+ this->lock->read_lock(this->lock);
- maxfd = collect_fds(this, &fds);
+ pfd = alloca(sizeof(*pfd) * (this->tuns->get_count(this->tuns) + 2));
+ pfd[count].fd = this->notify[0];
+ pfd[count].events = POLLIN;
+ count++;
+ pfd[count].fd = this->tun.fd;
+ pfd[count].events = POLLIN;
+ count++;
+
+ enumerator = this->tuns->create_enumerator(this->tuns);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ pfd[count].fd = entry->fd;
+ pfd[count].events = POLLIN;
+ count++;
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
oldstate = thread_cancelability(TRUE);
- if (select(maxfd, &fds, NULL, NULL, NULL) <= 0)
+ if (poll(pfd, count, -1) <= 0)
{
thread_cancelability(oldstate);
return JOB_REQUEUE_FAIR;
}
thread_cancelability(oldstate);
- if (FD_ISSET(this->notify[0], &fds))
- { /* list of TUN devices changed, read notification data, rebuild FDs */
- char buf[1];
- while (read(this->notify[0], &buf, sizeof(buf)) == sizeof(buf));
+ if (pfd[0].revents & POLLIN)
+ {
+ /* list of TUN devices changed, read notification data, rebuild FDs */
+ while (read(this->notify[0], &buf, sizeof(buf)) == sizeof(buf))
+ {
+ /* nop */
+ }
return JOB_REQUEUE_DIRECT;
}
- handle_tuns(this, &fds);
+ if (pfd[1].revents & POLLIN)
+ {
+ process_plain(this->tun.tun);
+ }
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->tuns->create_enumerator(this->tuns);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ if (find_revents(pfd, count, entry->fd) & POLLIN)
+ {
+ process_plain(entry->tun);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
return JOB_REQUEUE_DIRECT;
}
diff --git a/src/libcharon/plugins/kernel_wfp/Makefile.in b/src/libcharon/plugins/kernel_wfp/Makefile.in
index 1c92e30fc..efb214b88 100644
--- a/src/libcharon/plugins/kernel_wfp/Makefile.in
+++ b/src/libcharon/plugins/kernel_wfp/Makefile.in
@@ -237,6 +237,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -297,10 +298,12 @@ 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@
@@ -374,6 +377,8 @@ 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@
diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c
index 41f85ba5c..2e31aa151 100644
--- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c
+++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c
@@ -54,6 +54,24 @@ const GUID FWPM_LAYER_IPFORWARD_V4 = {
const GUID FWPM_LAYER_IPFORWARD_V6 = {
0x7b964818, 0x19c7, 0x493a, { 0xb7,0x1f,0x83,0x2c,0x36,0x84,0xd2,0x8c }
};
+const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V4 = {
+ 0xc38d57d1, 0x05a7, 0x4c33, { 0x90,0x4f,0x7f,0xbc,0xee,0xe6,0x0e,0x82 }
+};
+const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V6 = {
+ 0x4a72393b, 0x319f, 0x44bc, { 0x84,0xc3,0xba,0x54,0xdc,0xb3,0xb6,0xb4 }
+};
+const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4 = {
+ 0xe1cd9fe7, 0xf4b5, 0x4273, { 0x96,0xc0,0x59,0x2e,0x48,0x7b,0x86,0x50 }
+};
+const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6 = {
+ 0xa3b42c97, 0x9f04, 0x4672, { 0xb8,0x7e,0xce,0xe9,0xc4,0x83,0x25,0x7f }
+};
+const GUID FWPM_SUBLAYER_IPSEC_TUNNEL = {
+ 0x83f299ed, 0x9ff4, 0x4967, { 0xaf,0xf4,0xc3,0x09,0xf4,0xda,0xb8,0x27 }
+};
+const GUID FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL = {
+ 0xa5082e73, 0x8f71, 0x4559, { 0x8a,0x9a,0x10,0x1c,0xea,0x04,0xef,0x87 }
+};
const GUID FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4 = {
0x5132900d, 0x5e84, 0x4b5f, { 0x80,0xe4,0x01,0x74,0x1e,0x81,0xff,0x10 }
};
@@ -90,6 +108,24 @@ const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4 = {
const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6 = {
0xdae640cc, 0xe021, 0x4bee, { 0x9e,0xb6,0xa4,0x8b,0x27,0x5c,0x8c,0x1d }
};
+const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4 = {
+ 0x6ac141fc, 0xf75d, 0x4203, { 0xb9,0xc8,0x48,0xe6,0x14,0x9c,0x27,0x12 }
+};
+const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6 = {
+ 0x4c0dda05, 0xe31f, 0x4666, { 0x90,0xb0,0xb3,0xdf,0xad,0x34,0x12,0x9a }
+};
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4 = {
+ 0x3df6e7de, 0xfd20, 0x48f2, { 0x9f,0x26,0xf8,0x54,0x44,0x4c,0xba,0x79 }
+};
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6 = {
+ 0xa1e392d3, 0x72ac, 0x47bb, { 0x87,0xa7,0x01,0x22,0xc6,0x94,0x34,0xab }
+};
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V4 = {
+ 0x7dff309b, 0xba7d, 0x4aba, { 0x91,0xaa,0xae,0x5c,0x66,0x40,0xc9,0x44 }
+};
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V6 = {
+ 0xa9a0d6d9, 0xc58c, 0x474e, { 0x8a,0xeb,0x3c,0xfe,0x99,0xd6,0xd5,0x3d }
+};
/**
* Load a function symbol from a loaded dll
diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h
index 50a89a007..a553a0986 100644
--- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h
+++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h
@@ -127,6 +127,10 @@ const GUID FWPM_LAYER_OUTBOUND_TRANSPORT_V4;
const GUID FWPM_LAYER_OUTBOUND_TRANSPORT_V6;
const GUID FWPM_LAYER_IPFORWARD_V4;
const GUID FWPM_LAYER_IPFORWARD_V6;
+const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V4;
+const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V6;
+const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4;
+const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6;
const GUID FWPM_SUBLAYER_IPSEC_TUNNEL;
const GUID FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL;
const GUID FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4;
@@ -141,6 +145,12 @@ const GUID FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4;
const GUID FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6;
const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4;
const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6;
+const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4;
+const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6;
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4;
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6;
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V4;
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V6;
/* integrity config, missing in some MinGW versions */
#ifndef IPSEC_AUTH_CONFIG_HMAC_MD5_96
diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
index c788bfb10..b38ded846 100644
--- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
+++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
@@ -26,6 +26,8 @@
#include <collections/hashtable.h>
#include <processing/jobs/callback_job.h>
+#define IPPROTO_IPIP 4
+#define IPPROTO_IPV6 41
typedef struct private_kernel_wfp_ipsec_t private_kernel_wfp_ipsec_t;
@@ -188,6 +190,14 @@ typedef struct {
u_int64_t provider;
/** WFP allocated LUID for SA context */
u_int64_t sa_id;
+ /** WFP allocated LUID for tunnel mode IP-IPv4 inbound filter */
+ u_int64_t ip_ipv4_in;
+ /** WFP allocated LUID for tunnel mode IP-IPv4 outbound filter */
+ u_int64_t ip_ipv4_out;
+ /** WFP allocated LUID for tunnel mode IP-IPv6 inbound filter */
+ u_int64_t ip_ipv6_in;
+ /** WFP allocated LUID for tunnel mode IP-IPv6 outbound filter */
+ u_int64_t ip_ipv6_out;
} entry_t;
/**
@@ -285,6 +295,22 @@ static void cleanup_policies(private_kernel_wfp_ipsec_t *this, entry_t *entry)
*/
static void entry_destroy(private_kernel_wfp_ipsec_t *this, entry_t *entry)
{
+ if (entry->ip_ipv4_in)
+ {
+ FwpmFilterDeleteById0(this->handle, entry->ip_ipv4_in);
+ }
+ if (entry->ip_ipv4_out)
+ {
+ FwpmFilterDeleteById0(this->handle, entry->ip_ipv4_out);
+ }
+ if (entry->ip_ipv6_in)
+ {
+ FwpmFilterDeleteById0(this->handle, entry->ip_ipv6_in);
+ }
+ if (entry->ip_ipv6_out)
+ {
+ FwpmFilterDeleteById0(this->handle, entry->ip_ipv6_out);
+ }
if (entry->sa_id)
{
IPsecSaContextDeleteById0(this->handle, entry->sa_id);
@@ -553,49 +579,58 @@ static void free_conditions(FWPM_FILTER_CONDITION0 *conds, int count)
* Find the callout GUID for given parameters
*/
static bool find_callout(bool tunnel, bool v6, bool inbound, bool forward,
- GUID *layer, GUID *sublayer, GUID *callout)
+ bool ale, GUID *layer, GUID *sublayer, GUID *callout)
{
struct {
bool tunnel;
bool v6;
bool inbound;
bool forward;
+ bool ale;
const GUID *layer;
const GUID *sublayer;
const GUID *callout;
} map[] = {
- { 0, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4, NULL,
- &FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4 },
- { 0, 0, 1, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V4, NULL,
- &FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4 },
- { 0, 1, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V6, NULL,
- &FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6 },
- { 0, 1, 1, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V6, NULL,
- &FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V6 },
- { 1, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4,
- &FWPM_SUBLAYER_IPSEC_TUNNEL,
- &FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V4 },
- { 1, 0, 0, 1, &FWPM_LAYER_IPFORWARD_V4,
- &FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL,
- &FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4 },
- { 1, 0, 1, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V4,
- &FWPM_SUBLAYER_IPSEC_TUNNEL,
- &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V4 },
- { 1, 0, 1, 1, &FWPM_LAYER_IPFORWARD_V4,
- &FWPM_SUBLAYER_IPSEC_TUNNEL,
- &FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4 },
- { 1, 1, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V6,
- &FWPM_SUBLAYER_IPSEC_TUNNEL,
- &FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V6 },
- { 1, 1, 0, 1, &FWPM_LAYER_IPFORWARD_V6,
- &FWPM_SUBLAYER_IPSEC_TUNNEL,
- &FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6 },
- { 1, 1, 1, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V6,
- &FWPM_SUBLAYER_IPSEC_TUNNEL,
- &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V6 },
- { 1, 1, 1, 1, &FWPM_LAYER_IPFORWARD_V6,
- &FWPM_SUBLAYER_IPSEC_TUNNEL,
- &FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6 },
+ { 0, 0, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4, NULL,
+ &FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4 },
+ { 0, 0, 1, 0, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V4, NULL,
+ &FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4 },
+ { 0, 1, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V6, NULL,
+ &FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6 },
+ { 0, 1, 1, 0, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V6, NULL,
+ &FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V6 },
+ { 1, 0, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4,
+ &FWPM_SUBLAYER_IPSEC_TUNNEL,
+ &FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V4 },
+ { 1, 0, 0, 1, 0, &FWPM_LAYER_IPFORWARD_V4,
+ &FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL,
+ &FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4 },
+ { 1, 0, 1, 0, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V4,
+ &FWPM_SUBLAYER_IPSEC_TUNNEL,
+ &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V4 },
+ { 1, 0, 1, 1, 0, &FWPM_LAYER_IPFORWARD_V4,
+ &FWPM_SUBLAYER_IPSEC_TUNNEL,
+ &FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4 },
+ { 1, 0, 0, 0, 1, &FWPM_LAYER_ALE_AUTH_CONNECT_V4, NULL,
+ &FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4 },
+ { 1, 0, 1, 0, 1, &FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, NULL,
+ &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4},
+ { 1, 1, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V6,
+ &FWPM_SUBLAYER_IPSEC_TUNNEL,
+ &FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V6 },
+ { 1, 1, 0, 1, 0, &FWPM_LAYER_IPFORWARD_V6,
+ &FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL,
+ &FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6 },
+ { 1, 1, 1, 0, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V6,
+ &FWPM_SUBLAYER_IPSEC_TUNNEL,
+ &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V6 },
+ { 1, 1, 1, 1, 0, &FWPM_LAYER_IPFORWARD_V6,
+ &FWPM_SUBLAYER_IPSEC_TUNNEL,
+ &FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6 },
+ { 1, 1, 0, 0, 1, &FWPM_LAYER_ALE_AUTH_CONNECT_V6, NULL,
+ &FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6 },
+ { 1, 1, 1, 0, 1, &FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6, NULL,
+ &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6},
};
int i;
@@ -604,7 +639,8 @@ static bool find_callout(bool tunnel, bool v6, bool inbound, bool forward,
if (tunnel == map[i].tunnel &&
v6 == map[i].v6 &&
inbound == map[i].inbound &&
- forward == map[i].forward)
+ forward == map[i].forward &&
+ ale == map[i].ale)
{
*callout = *map[i].callout;
*layer = *map[i].layer;
@@ -647,7 +683,7 @@ static bool install_sp(private_kernel_wfp_ipsec_t *this, sp_entry_t *sp,
}
v6 = sp->src->get_type(sp->src) == TS_IPV6_ADDR_RANGE;
- if (!find_callout(context != NULL, v6, inbound, fwd,
+ if (!find_callout(context != NULL, v6, inbound, fwd, FALSE,
&filter.layerKey, &filter.subLayerKey,
&filter.action.calloutKey))
{
@@ -688,8 +724,73 @@ static bool install_sp(private_kernel_wfp_ipsec_t *this, sp_entry_t *sp,
free_conditions(conds, count);
if (res != ERROR_SUCCESS)
{
- DBG1(DBG_KNL, "installing %s%sbound WFP filter failed: 0x%08x",
- fwd ? "forward " : "", inbound ? "in" : "out", res);
+ DBG1(DBG_KNL, "installing IPv%d %s%sbound %s WFP filter failed: 0x%08x",
+ v6 ? 6 : 4, fwd ? "forward " : "", inbound ? "in" : "out",
+ context ? "tunnel" : "transport", res);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Install an IP-IP allow filter for SA specific hosts
+ */
+static bool install_ipip_ale(private_kernel_wfp_ipsec_t *this,
+ host_t *local, host_t *remote, GUID *context,
+ bool inbound, int proto, u_int64_t *filter_id)
+{
+ traffic_selector_t *lts, *rts;
+ FWPM_FILTER_CONDITION0 *conds = NULL;
+ int count = 0;
+ bool v6;
+ DWORD res;
+ FWPM_FILTER0 filter = {
+ .displayData = {
+ .name = L"charon IPsec IP-in-IP ALE policy",
+ },
+ .action = {
+ .type = FWP_ACTION_CALLOUT_TERMINATING,
+ },
+ };
+
+ if (context)
+ {
+ filter.flags |= FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT;
+ filter.providerKey = (GUID*)&this->provider.providerKey;
+ filter.providerContextKey = *context;
+ }
+
+ v6 = local->get_family(local) == AF_INET6;
+ if (!find_callout(TRUE, v6, inbound, FALSE, TRUE, &filter.layerKey,
+ &filter.subLayerKey, &filter.action.calloutKey))
+ {
+ return FALSE;
+ }
+
+ lts = traffic_selector_create_from_subnet(local->clone(local),
+ v6 ? 128 : 32 , proto, 0, 65535);
+ rts = traffic_selector_create_from_subnet(remote->clone(remote),
+ v6 ? 128 : 32 , proto, 0, 65535);
+ if (!ts2condition(lts, &FWPM_CONDITION_IP_LOCAL_ADDRESS, &conds, &count) ||
+ !ts2condition(rts, &FWPM_CONDITION_IP_REMOTE_ADDRESS, &conds, &count))
+ {
+ free_conditions(conds, count);
+ lts->destroy(lts);
+ rts->destroy(rts);
+ return FALSE;
+ }
+ lts->destroy(lts);
+ rts->destroy(rts);
+
+ filter.numFilterConditions = count;
+ filter.filterCondition = conds;
+
+ res = FwpmFilterAdd0(this->handle, &filter, NULL, filter_id);
+ free_conditions(conds, count);
+ if (res != ERROR_SUCCESS)
+ {
+ DBG1(DBG_KNL, "installing IP-IPv%d %s ALE WFP filter failed: 0x%08x",
+ v6 ? 6 : 4, inbound ? "inbound" : "outbound", res);
return FALSE;
}
return TRUE;
@@ -703,10 +804,21 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this,
{
enumerator_t *enumerator;
sp_entry_t *sp;
+ bool has_v4 = FALSE, has_v6 = FALSE;
enumerator = array_create_enumerator(entry->sps);
while (enumerator->enumerate(enumerator, &sp))
{
+ switch (sp->src->get_type(sp->src))
+ {
+ case TS_IPV4_ADDR_RANGE:
+ has_v4 = TRUE;
+ break;
+ case TS_IPV6_ADDR_RANGE:
+ has_v6 = TRUE;
+ break;
+ }
+
/* inbound policy */
if (!install_sp(this, sp, context, TRUE, FALSE, &sp->policy_in))
{
@@ -719,21 +831,22 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this,
enumerator->destroy(enumerator);
return FALSE;
}
+
if (context)
{
if (!sp->src->is_host(sp->src, entry->local) ||
!sp->dst->is_host(sp->dst, entry->remote))
{
/* inbound forward policy, from decapsulation */
- if (!install_sp(this, sp, context,
- TRUE, TRUE, &sp->policy_fwd_in))
+ if (!install_sp(this, sp, context, TRUE, TRUE,
+ &sp->policy_fwd_in))
{
enumerator->destroy(enumerator);
return FALSE;
}
/* outbound forward policy, to encapsulate */
- if (!install_sp(this, sp, context,
- FALSE, TRUE, &sp->policy_fwd_out))
+ if (!install_sp(this, sp, context, FALSE, TRUE,
+ &sp->policy_fwd_out))
{
enumerator->destroy(enumerator);
return FALSE;
@@ -743,6 +856,38 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this,
}
enumerator->destroy(enumerator);
+ if (context)
+ {
+ /* In tunnel mode, Windows does firewall filtering on decrypted but
+ * non-unwrapped packets: It sees them as IP-in-IP packets. When using
+ * a default-drop policy, we need to allow such packets explicitly. */
+ if (has_v4)
+ {
+ if (!install_ipip_ale(this, entry->local, entry->remote, context,
+ TRUE, IPPROTO_IPIP, &entry->ip_ipv4_in))
+ {
+ return FALSE;
+ }
+ if (!install_ipip_ale(this, entry->local, entry->remote, NULL,
+ FALSE, IPPROTO_IPIP, &entry->ip_ipv4_out))
+ {
+ return FALSE;
+ }
+ }
+ if (has_v6)
+ {
+ if (!install_ipip_ale(this, entry->local, entry->remote, context,
+ TRUE, IPPROTO_IPV6, &entry->ip_ipv6_in))
+ {
+ return FALSE;
+ }
+ if (!install_ipip_ale(this, entry->local, entry->remote, NULL,
+ FALSE, IPPROTO_IPV6, &entry->ip_ipv6_out))
+ {
+ return FALSE;
+ }
+ }
+ }
return TRUE;
}
@@ -1583,8 +1728,20 @@ static void WINAPI event_callback(void *user, const FWPM_NET_EVENT1 *event)
acquire(this, event->classifyDrop->filterId, local, remote);
break;
case FWPM_NET_EVENT_TYPE_IKEEXT_MM_FAILURE:
+ DBG1(DBG_KNL, "WFP MM failure: %R === %R, 0x%08x, filterId %llu",
+ local, remote, event->ikeMmFailure->failureErrorCode,
+ event->ikeMmFailure->mmFilterId);
+ break;
case FWPM_NET_EVENT_TYPE_IKEEXT_QM_FAILURE:
+ DBG1(DBG_KNL, "WFP QM failure: %R === %R, 0x%08x, filterId %llu",
+ local, remote, event->ikeQmFailure->failureErrorCode,
+ event->ikeQmFailure->qmFilterId);
+ break;
case FWPM_NET_EVENT_TYPE_IKEEXT_EM_FAILURE:
+ DBG1(DBG_KNL, "WFP EM failure: %R === %R, 0x%08x, filterId %llu",
+ local, remote, event->ikeEmFailure->failureErrorCode,
+ event->ikeEmFailure->qmFilterId);
+ break;
case FWPM_NET_EVENT_TYPE_IPSEC_KERNEL_DROP:
DBG1(DBG_KNL, "IPsec kernel drop: %R === %R, error 0x%08x, "
"SPI 0x%08x, %s filterId %llu", local, remote,
@@ -1824,7 +1981,7 @@ static u_int permute(u_int x, u_int p)
METHOD(kernel_ipsec_t, get_spi, status_t,
private_kernel_wfp_ipsec_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+ u_int8_t protocol, u_int32_t *spi)
{
/* To avoid sequencial SPIs, we use a one-to-one permuation function on
* an incrementing counter, that is a full period PRNG for the range we
@@ -1841,7 +1998,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
METHOD(kernel_ipsec_t, get_cpi, status_t,
private_kernel_wfp_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ u_int16_t *cpi)
{
return NOT_SUPPORTED;
}
@@ -1875,9 +2032,8 @@ static void expire_data_destroy(expire_data_t *data)
static job_requeue_t expire_job(expire_data_t *data)
{
private_kernel_wfp_ipsec_t *this = data->this;
- u_int32_t reqid = 0;
u_int8_t protocol;
- entry_t *entry;
+ entry_t *entry = NULL;
sa_entry_t key = {
.spi = data->spi,
.dst = data->dst,
@@ -1891,7 +2047,6 @@ static job_requeue_t expire_job(expire_data_t *data)
if (entry)
{
protocol = entry->isa.protocol;
- reqid = entry->reqid;
if (entry->osa.dst)
{
key.dst = entry->osa.dst;
@@ -1908,15 +2063,14 @@ static job_requeue_t expire_job(expire_data_t *data)
if (entry)
{
protocol = entry->isa.protocol;
- reqid = entry->reqid;
}
this->mutex->unlock(this->mutex);
}
- if (reqid)
+ if (entry)
{
- hydra->kernel_interface->expire(hydra->kernel_interface,
- reqid, protocol, data->spi, data->hard);
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ data->spi, data->dst, data->hard);
}
return JOB_REQUEUE_NONE;
@@ -1949,8 +2103,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
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,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ bool initiator, bool encap, bool esn, bool inbound, bool update,
+ linked_list_t *src_ts, linked_list_t *dst_ts)
{
host_t *local, *remote;
entry_t *entry;
diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in
index db4552dde..7942868f6 100644
--- a/src/libcharon/plugins/led/Makefile.in
+++ b/src/libcharon/plugins/led/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ 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@
@@ -363,6 +366,8 @@ 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@
diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in
index 418dccba5..52dbec53f 100644
--- a/src/libcharon/plugins/load_tester/Makefile.in
+++ b/src/libcharon/plugins/load_tester/Makefile.in
@@ -239,6 +239,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -299,10 +300,12 @@ 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@
@@ -376,6 +379,8 @@ 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@
diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c
index bc7c0ffbc..8a500635c 100644
--- a/src/libcharon/plugins/load_tester/load_tester_config.c
+++ b/src/libcharon/plugins/load_tester/load_tester_config.c
@@ -394,6 +394,28 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
}
}
}
+ else if (strpfx(str, "xauth"))
+ { /* XAuth, use a username */
+ class = AUTH_CLASS_XAUTH;
+ if (*(str + strlen("xauth")) == '-')
+ {
+ auth->add(auth, AUTH_RULE_XAUTH_BACKEND, str + strlen("xauth-"));
+ }
+ if (!id)
+ {
+ if (local && num)
+ {
+ snprintf(buf, sizeof(buf), "cli-%.6d-%.2d", num, rnd);
+ id = identification_create_from_string(buf);
+ }
+ else
+ {
+ id = identification_create_from_encoding(ID_ANY, chunk_empty);
+ }
+ }
+ /* additionally set the ID as XAuth identity */
+ auth->add(auth, AUTH_RULE_XAUTH_IDENTITY, id->clone(id));
+ }
else
{
if (!streq(str, "pubkey"))
@@ -618,7 +640,7 @@ static host_t *allocate_addr(private_load_tester_config_t *this, uint num)
enumerator = this->pools->create_enumerator(this->pools);
while (enumerator->enumerate(enumerator, &pool))
{
- found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW);
+ found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW, NULL);
if (found)
{
iface = (char*)pool->get_name(pool);
diff --git a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c
index d5ec3599b..e1c7c0e0b 100644
--- a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c
+++ b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c
@@ -15,33 +15,38 @@
#include "load_tester_diffie_hellman.h"
-/**
- * Implementation of gmp_diffie_hellman_t.get_my_public_value.
- */
-static void get_my_public_value(load_tester_diffie_hellman_t *this,
- chunk_t *value)
+METHOD(diffie_hellman_t, get_my_public_value, bool,
+ load_tester_diffie_hellman_t *this, chunk_t *value)
{
*value = chunk_empty;
+ return TRUE;
}
-/**
- * Implementation of gmp_diffie_hellman_t.get_shared_secret.
- */
-static status_t get_shared_secret(load_tester_diffie_hellman_t *this,
- chunk_t *secret)
+METHOD(diffie_hellman_t, set_other_public_value, bool,
+ load_tester_diffie_hellman_t *this, chunk_t value)
+{
+ return TRUE;
+}
+
+METHOD(diffie_hellman_t, get_shared_secret, bool,
+ load_tester_diffie_hellman_t *this, chunk_t *secret)
{
*secret = chunk_empty;
- return SUCCESS;
+ return TRUE;
}
-/**
- * Implementation of gmp_diffie_hellman_t.get_dh_group.
- */
-static diffie_hellman_group_t get_dh_group(load_tester_diffie_hellman_t *this)
+METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
+ load_tester_diffie_hellman_t *this)
{
return MODP_NULL;
}
+METHOD(diffie_hellman_t, destroy, void,
+ load_tester_diffie_hellman_t *this)
+{
+ free(this);
+}
+
/**
* See header
*/
@@ -55,13 +60,15 @@ load_tester_diffie_hellman_t *load_tester_diffie_hellman_create(
return NULL;
}
- this = malloc_thing(load_tester_diffie_hellman_t);
-
- this->dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *))get_shared_secret;
- this->dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t ))nop;
- this->dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *))get_my_public_value;
- this->dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *))get_dh_group;
- this->dh.destroy = (void (*)(diffie_hellman_t *))free;
+ INIT(this,
+ .dh = {
+ .get_shared_secret = _get_shared_secret,
+ .set_other_public_value = _set_other_public_value,
+ .get_my_public_value = _get_my_public_value,
+ .get_dh_group = _get_dh_group,
+ .destroy = _destroy,
+ }
+ );
return this;
}
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
index 3f256ddd0..62d43e302 100644
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
@@ -36,7 +36,7 @@ struct private_load_tester_ipsec_t {
METHOD(kernel_ipsec_t, get_spi, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+ u_int8_t protocol, u_int32_t *spi)
{
*spi = (uint32_t)ref_get(&this->spi);
return SUCCESS;
@@ -44,7 +44,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
METHOD(kernel_ipsec_t, get_cpi, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ u_int16_t *cpi)
{
return FAILED;
}
@@ -55,8 +55,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
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,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ bool initiator, bool encap, bool esn, bool inbound, bool update,
+ linked_list_t *src_ts, linked_list_t *dst_ts)
{
return SUCCESS;
}
diff --git a/src/libcharon/plugins/lookip/Makefile.in b/src/libcharon/plugins/lookip/Makefile.in
index f0f2c75f4..264c58ff5 100644
--- a/src/libcharon/plugins/lookip/Makefile.in
+++ b/src/libcharon/plugins/lookip/Makefile.in
@@ -235,6 +235,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -295,10 +296,12 @@ 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@
@@ -372,6 +375,8 @@ 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@
diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in
index 3a866e968..76c9012b2 100644
--- a/src/libcharon/plugins/maemo/Makefile.in
+++ b/src/libcharon/plugins/maemo/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ 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@
@@ -368,6 +371,8 @@ 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@
diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in
index e0f70ce44..35740c369 100644
--- a/src/libcharon/plugins/medcli/Makefile.in
+++ b/src/libcharon/plugins/medcli/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in
index adb61e817..8fe160ef3 100644
--- a/src/libcharon/plugins/medsrv/Makefile.in
+++ b/src/libcharon/plugins/medsrv/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/osx_attr/Makefile.in b/src/libcharon/plugins/osx_attr/Makefile.in
index a0c21c442..9a5e438e1 100644
--- a/src/libcharon/plugins/osx_attr/Makefile.in
+++ b/src/libcharon/plugins/osx_attr/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/osx_attr/osx_attr_handler.c b/src/libcharon/plugins/osx_attr/osx_attr_handler.c
index 9a3b2701d..d974b57ce 100644
--- a/src/libcharon/plugins/osx_attr/osx_attr_handler.c
+++ b/src/libcharon/plugins/osx_attr/osx_attr_handler.c
@@ -169,7 +169,7 @@ static bool manage_dns(int family, chunk_t data, bool add)
}
METHOD(attribute_handler_t, handle, bool,
- private_osx_attr_handler_t *this, identification_t *id,
+ private_osx_attr_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
switch (type)
@@ -182,7 +182,7 @@ METHOD(attribute_handler_t, handle, bool,
}
METHOD(attribute_handler_t, release, void,
- private_osx_attr_handler_t *this, identification_t *server,
+ private_osx_attr_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
switch (type)
@@ -206,7 +206,7 @@ METHOD(enumerator_t, enumerate_dns, bool,
}
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
- private_osx_attr_handler_t *this, identification_t *id,
+ private_osx_attr_handler_t *this, ike_sa_t *ike_sa,
linked_list_t *vips)
{
enumerator_t *enumerator;
diff --git a/src/libcharon/plugins/osx_attr/osx_attr_plugin.c b/src/libcharon/plugins/osx_attr/osx_attr_plugin.c
index 380483c23..4be9eda5e 100644
--- a/src/libcharon/plugins/osx_attr/osx_attr_plugin.c
+++ b/src/libcharon/plugins/osx_attr/osx_attr_plugin.c
@@ -16,7 +16,6 @@
#include "osx_attr_plugin.h"
#include "osx_attr_handler.h"
-#include <hydra.h>
#include <daemon.h>
typedef struct private_osx_attr_plugin_t private_osx_attr_plugin_t;
@@ -51,13 +50,13 @@ static bool plugin_cb(private_osx_attr_plugin_t *this,
{
if (reg)
{
- hydra->attributes->add_handler(hydra->attributes,
- &this->handler->handler);
+ charon->attributes->add_handler(charon->attributes,
+ &this->handler->handler);
}
else
{
- hydra->attributes->remove_handler(hydra->attributes,
- &this->handler->handler);
+ charon->attributes->remove_handler(charon->attributes,
+ &this->handler->handler);
}
return TRUE;
}
diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in
index 14abba99a..baff3fc76 100644
--- a/src/libcharon/plugins/radattr/Makefile.in
+++ b/src/libcharon/plugins/radattr/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ 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@
@@ -367,6 +370,8 @@ 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@
diff --git a/src/libcharon/plugins/resolve/Makefile.am b/src/libcharon/plugins/resolve/Makefile.am
new file mode 100644
index 000000000..9cfc370c0
--- /dev/null
+++ b/src/libcharon/plugins/resolve/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -DRESOLV_CONF=\"${resolv_conf}\"
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-resolve.la
+else
+plugin_LTLIBRARIES = libstrongswan-resolve.la
+endif
+
+libstrongswan_resolve_la_SOURCES = \
+ resolve_plugin.h resolve_plugin.c \
+ resolve_handler.h resolve_handler.c
+
+libstrongswan_resolve_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/resolve/Makefile.in b/src/libcharon/plugins/resolve/Makefile.in
new file mode 100644
index 000000000..91479bf52
--- /dev/null
+++ b/src/libcharon/plugins/resolve/Makefile.in
@@ -0,0 +1,781 @@
+# 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/resolve
+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_resolve_la_LIBADD =
+am_libstrongswan_resolve_la_OBJECTS = resolve_plugin.lo \
+ resolve_handler.lo
+libstrongswan_resolve_la_OBJECTS = \
+ $(am_libstrongswan_resolve_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_resolve_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_resolve_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_resolve_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_resolve_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_resolve_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_resolve_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_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 \
+ -DRESOLV_CONF=\"${resolv_conf}\"
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS)
+
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-resolve.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-resolve.la
+libstrongswan_resolve_la_SOURCES = \
+ resolve_plugin.h resolve_plugin.c \
+ resolve_handler.h resolve_handler.c
+
+libstrongswan_resolve_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/resolve/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/resolve/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-resolve.la: $(libstrongswan_resolve_la_OBJECTS) $(libstrongswan_resolve_la_DEPENDENCIES) $(EXTRA_libstrongswan_resolve_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_resolve_la_LINK) $(am_libstrongswan_resolve_la_rpath) $(libstrongswan_resolve_la_OBJECTS) $(libstrongswan_resolve_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resolve_handler.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resolve_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/resolve/resolve_handler.c b/src/libcharon/plugins/resolve/resolve_handler.c
new file mode 100644
index 000000000..74c3960ff
--- /dev/null
+++ b/src/libcharon/plugins/resolve/resolve_handler.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "resolve_handler.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <hydra.h>
+#include <utils/debug.h>
+#include <threading/mutex.h>
+
+/* path to resolvconf executable */
+#define RESOLVCONF_EXEC "/sbin/resolvconf"
+
+/* default prefix used for resolvconf interfaces (should have high prio) */
+#define RESOLVCONF_PREFIX "lo.inet.ipsec."
+
+typedef struct private_resolve_handler_t private_resolve_handler_t;
+
+/**
+ * Private data of an resolve_handler_t object.
+ */
+struct private_resolve_handler_t {
+
+ /**
+ * Public resolve_handler_t interface.
+ */
+ resolve_handler_t public;
+
+ /**
+ * resolv.conf file to use
+ */
+ char *file;
+
+ /**
+ * use resolvconf instead of writing directly to resolv.conf
+ */
+ bool use_resolvconf;
+
+ /**
+ * prefix to be used for interface names sent to resolvconf
+ */
+ char *iface_prefix;
+
+ /**
+ * Mutex to access file exclusively
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Writes the given nameserver to resolv.conf
+ */
+static bool write_nameserver(private_resolve_handler_t *this,
+ identification_t *server, host_t *addr)
+{
+ FILE *in, *out;
+ char buf[1024];
+ size_t len;
+ bool handled = FALSE;
+
+ in = fopen(this->file, "r");
+ /* allows us to stream from in to out */
+ unlink(this->file);
+ out = fopen(this->file, "w");
+ if (out)
+ {
+ fprintf(out, "nameserver %H # by strongSwan, from %Y\n", addr,
+ server);
+ DBG1(DBG_IKE, "installing DNS server %H to %s", addr, this->file);
+ handled = TRUE;
+
+ /* copy rest of the file */
+ if (in)
+ {
+ while ((len = fread(buf, 1, sizeof(buf), in)))
+ {
+ ignore_result(fwrite(buf, 1, len, out));
+ }
+ }
+ fclose(out);
+ }
+ if (in)
+ {
+ fclose(in);
+ }
+ return handled;
+}
+
+/**
+ * Removes the given nameserver from resolv.conf
+ */
+static void remove_nameserver(private_resolve_handler_t *this,
+ identification_t *server, host_t *addr)
+{
+ FILE *in, *out;
+ char line[1024], matcher[512];
+
+ in = fopen(this->file, "r");
+ if (in)
+ {
+ /* allows us to stream from in to out */
+ unlink(this->file);
+ out = fopen(this->file, "w");
+ if (out)
+ {
+ snprintf(matcher, sizeof(matcher),
+ "nameserver %H # by strongSwan, from %Y\n",
+ addr, server);
+
+ /* copy all, but matching line */
+ while (fgets(line, sizeof(line), in))
+ {
+ if (strpfx(line, matcher))
+ {
+ DBG1(DBG_IKE, "removing DNS server %H from %s",
+ addr, this->file);
+ }
+ else
+ {
+ fputs(line, out);
+ }
+ }
+ fclose(out);
+ }
+ fclose(in);
+ }
+}
+
+/**
+ * Add or remove the given nameserver by invoking resolvconf.
+ */
+static bool invoke_resolvconf(private_resolve_handler_t *this,
+ identification_t *server, host_t *addr,
+ bool install)
+{
+ char cmd[128];
+ bool success = TRUE;
+
+ /* we use the nameserver's IP address as part of the interface name to
+ * make them unique */
+ if (snprintf(cmd, sizeof(cmd), "%s %s %s%H", RESOLVCONF_EXEC,
+ install ? "-a" : "-d", this->iface_prefix, addr) >= sizeof(cmd))
+ {
+ return FALSE;
+ }
+
+ if (install)
+ {
+ FILE *out;
+
+ out = popen(cmd, "w");
+ if (!out)
+ {
+ return FALSE;
+ }
+ DBG1(DBG_IKE, "installing DNS server %H via resolvconf", addr);
+ fprintf(out, "nameserver %H\n", addr);
+ success = !ferror(out);
+ if (pclose(out))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ ignore_result(system(cmd));
+ }
+ return success;
+}
+
+METHOD(attribute_handler_t, handle, bool,
+ private_resolve_handler_t *this, ike_sa_t *ike_sa,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ identification_t *server;
+ host_t *addr;
+ bool handled;
+
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ addr = host_create_from_chunk(AF_INET, data, 0);
+ break;
+ case INTERNAL_IP6_DNS:
+ addr = host_create_from_chunk(AF_INET6, data, 0);
+ break;
+ default:
+ return FALSE;
+ }
+
+ if (!addr || addr->is_anyaddr(addr))
+ {
+ DESTROY_IF(addr);
+ return FALSE;
+ }
+ server = ike_sa->get_other_id(ike_sa);
+
+ this->mutex->lock(this->mutex);
+ if (this->use_resolvconf)
+ {
+ handled = invoke_resolvconf(this, server, addr, TRUE);
+ }
+ else
+ {
+ handled = write_nameserver(this, server, addr);
+ }
+ this->mutex->unlock(this->mutex);
+ addr->destroy(addr);
+
+ if (!handled)
+ {
+ DBG1(DBG_IKE, "adding DNS server failed");
+ }
+ return handled;
+}
+
+METHOD(attribute_handler_t, release, void,
+ private_resolve_handler_t *this, ike_sa_t *ike_sa,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ identification_t *server;
+ host_t *addr;
+ int family;
+
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ family = AF_INET;
+ break;
+ case INTERNAL_IP6_DNS:
+ family = AF_INET6;
+ break;
+ default:
+ return;
+ }
+ addr = host_create_from_chunk(family, data, 0);
+ server = ike_sa->get_other_id(ike_sa);
+
+ this->mutex->lock(this->mutex);
+ if (this->use_resolvconf)
+ {
+ invoke_resolvconf(this, server, addr, FALSE);
+ }
+ else
+ {
+ remove_nameserver(this, server, addr);
+ }
+ this->mutex->unlock(this->mutex);
+
+ addr->destroy(addr);
+}
+
+/**
+ * Attribute enumerator implementation
+ */
+typedef struct {
+ /** implements enumerator_t interface */
+ enumerator_t public;
+ /** request IPv4 DNS? */
+ bool v4;
+ /** request IPv6 DNS? */
+ bool v6;
+} attribute_enumerator_t;
+
+static bool attribute_enumerate(attribute_enumerator_t *this,
+ configuration_attribute_type_t *type,
+ chunk_t *data)
+{
+ if (this->v4)
+ {
+ *type = INTERNAL_IP4_DNS;
+ *data = chunk_empty;
+ this->v4 = FALSE;
+ return TRUE;
+ }
+ if (this->v6)
+ {
+ *type = INTERNAL_IP6_DNS;
+ *data = chunk_empty;
+ this->v6 = FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Check if a list has a host of given family
+ */
+static bool has_host_family(linked_list_t *list, int family)
+{
+ enumerator_t *enumerator;
+ host_t *host;
+ bool found = FALSE;
+
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ if (host->get_family(host) == family)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
+METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
+ private_resolve_handler_t *this, ike_sa_t *ike_sa,
+ linked_list_t *vips)
+{
+ attribute_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)attribute_enumerate,
+ .destroy = (void*)free,
+ },
+ .v4 = has_host_family(vips, AF_INET),
+ .v6 = has_host_family(vips, AF_INET6),
+ );
+ return &enumerator->public;
+}
+
+METHOD(resolve_handler_t, destroy, void,
+ private_resolve_handler_t *this)
+{
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+resolve_handler_t *resolve_handler_create()
+{
+ private_resolve_handler_t *this;
+ struct stat st;
+
+ INIT(this,
+ .public = {
+ .handler = {
+ .handle = _handle,
+ .release = _release,
+ .create_attribute_enumerator = _create_attribute_enumerator,
+ },
+ .destroy = _destroy,
+ },
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .file = lib->settings->get_str(lib->settings, "%s.plugins.resolve.file",
+ RESOLV_CONF, lib->ns),
+ );
+
+ if (stat(RESOLVCONF_EXEC, &st) == 0)
+ {
+ this->use_resolvconf = TRUE;
+ this->iface_prefix = lib->settings->get_str(lib->settings,
+ "%s.plugins.resolve.resolvconf.iface_prefix",
+ RESOLVCONF_PREFIX, lib->ns);
+ }
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/resolve/resolve_handler.h b/src/libcharon/plugins/resolve/resolve_handler.h
new file mode 100644
index 000000000..77bf9781c
--- /dev/null
+++ b/src/libcharon/plugins/resolve/resolve_handler.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup resolve_handler resolve_handler
+ * @{ @ingroup resolve
+ */
+
+#ifndef RESOLVE_HANDLER_H_
+#define RESOLVE_HANDLER_H_
+
+#include <attributes/attribute_handler.h>
+
+typedef struct resolve_handler_t resolve_handler_t;
+
+/**
+ * Handle DNS configuration attributes by mangling a resolv.conf file.
+ */
+struct resolve_handler_t {
+
+ /**
+ * Implements the attribute_handler_t interface
+ */
+ attribute_handler_t handler;
+
+ /**
+ * Destroy a resolve_handler_t.
+ */
+ void (*destroy)(resolve_handler_t *this);
+};
+
+/**
+ * Create a resolve_handler instance.
+ */
+resolve_handler_t *resolve_handler_create();
+
+#endif /** RESOLVE_HANDLER_H_ @}*/
diff --git a/src/libcharon/plugins/resolve/resolve_plugin.c b/src/libcharon/plugins/resolve/resolve_plugin.c
new file mode 100644
index 000000000..193c5b602
--- /dev/null
+++ b/src/libcharon/plugins/resolve/resolve_plugin.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "resolve_plugin.h"
+#include "resolve_handler.h"
+
+#include <daemon.h>
+
+typedef struct private_resolve_plugin_t private_resolve_plugin_t;
+
+/**
+ * private data of resolve plugin
+ */
+struct private_resolve_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ resolve_plugin_t public;
+
+ /**
+ * The registered DNS attribute handler
+ */
+ resolve_handler_t *handler;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_resolve_plugin_t *this)
+{
+ return "resolve";
+}
+
+/**
+ * Register handler
+ */
+static bool plugin_cb(private_resolve_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_resolve_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "resolve"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_resolve_plugin_t *this)
+{
+ this->handler->destroy(this->handler);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *resolve_plugin_create()
+{
+ private_resolve_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ .handler = resolve_handler_create(),
+ );
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/resolve/resolve_plugin.h b/src/libcharon/plugins/resolve/resolve_plugin.h
new file mode 100644
index 000000000..0148b10d7
--- /dev/null
+++ b/src/libcharon/plugins/resolve/resolve_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup resolve resolve
+ * @ingroup cplugins
+ *
+ * @defgroup resolve_plugin resolve_plugin
+ * @{ @ingroup resolve
+ */
+
+#ifndef RESOLVE_PLUGIN_H_
+#define RESOLVE_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct resolve_plugin_t resolve_plugin_t;
+
+/**
+ * Plugin that writes received DNS servers in a resolv.conf file.
+ */
+struct resolve_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** RESOLVE_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in
index 7c5b030f4..572e7fc2f 100644
--- a/src/libcharon/plugins/smp/Makefile.in
+++ b/src/libcharon/plugins/smp/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ 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@
@@ -364,6 +367,8 @@ 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@
diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in
index 548524a38..25b40995b 100644
--- a/src/libcharon/plugins/socket_default/Makefile.in
+++ b/src/libcharon/plugins/socket_default/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c
index 9cc39955b..dbfddbb81 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
@@ -141,6 +141,11 @@ struct private_socket_default_socket_t {
* TRUE if the source address should be set on outbound packets
*/
bool set_source;
+
+ /**
+ * A counter to implement round-robin selection of read sockets
+ */
+ u_int rr_counter;
};
METHOD(socket_t, receiver, status_t,
@@ -150,66 +155,43 @@ METHOD(socket_t, receiver, status_t,
chunk_t data;
packet_t *pkt;
host_t *source = NULL, *dest = NULL;
- int bytes_read = 0;
+ int i, rr, index, bytes_read = 0, selected = -1;
bool oldstate;
-
- fd_set rfds;
- int max_fd = 0, selected = 0;
u_int16_t port = 0;
-
- FD_ZERO(&rfds);
-
- if (this->ipv4 != -1)
- {
- FD_SET(this->ipv4, &rfds);
- max_fd = max(max_fd, this->ipv4);
- }
- if (this->ipv4_natt != -1)
- {
- FD_SET(this->ipv4_natt, &rfds);
- max_fd = max(max_fd, this->ipv4_natt);
- }
- if (this->ipv6 != -1)
- {
- FD_SET(this->ipv6, &rfds);
- max_fd = max(max_fd, this->ipv6);
- }
- if (this->ipv6_natt != -1)
- {
- FD_SET(this->ipv6_natt, &rfds);
- max_fd = max(max_fd, this->ipv6_natt);
- }
+ struct pollfd pfd[] = {
+ { .fd = this->ipv4, .events = POLLIN },
+ { .fd = this->ipv4_natt, .events = POLLIN },
+ { .fd = this->ipv6, .events = POLLIN },
+ { .fd = this->ipv6_natt, .events = POLLIN },
+ };
+ int ports[] = {
+ /* port numbers associated to pollfds */
+ this->port, this->natt, this->port, this->natt,
+ };
DBG2(DBG_NET, "waiting for data on sockets");
oldstate = thread_cancelability(TRUE);
- if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
+ if (poll(pfd, countof(pfd), -1) <= 0)
{
thread_cancelability(oldstate);
return FAILED;
}
thread_cancelability(oldstate);
- if (this->ipv4 != -1 && FD_ISSET(this->ipv4, &rfds))
+ rr = this->rr_counter++;
+ for (i = 0; i < countof(pfd); i++)
{
- port = this->port;
- selected = this->ipv4;
- }
- if (this->ipv4_natt != -1 && FD_ISSET(this->ipv4_natt, &rfds))
- {
- port = this->natt;
- selected = this->ipv4_natt;
- }
- if (this->ipv6 != -1 && FD_ISSET(this->ipv6, &rfds))
- {
- port = this->port;
- selected = this->ipv6;
- }
- if (this->ipv6_natt != -1 && FD_ISSET(this->ipv6_natt, &rfds))
- {
- port = this->natt;
- selected = this->ipv6_natt;
+ /* To serve all ports with equal priority, we use a round-robin
+ * scheme to choose the one to process in this invocation */
+ index = (rr + i) % countof(pfd);
+ if (pfd[index].revents & POLLIN)
+ {
+ selected = pfd[index].fd;
+ port = ports[index];
+ break;
+ }
}
- if (selected)
+ if (selected != -1)
{
struct msghdr msg;
struct cmsghdr *cmsgptr;
diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in
index 892549c6c..5c010a59a 100644
--- a/src/libcharon/plugins/socket_dynamic/Makefile.in
+++ b/src/libcharon/plugins/socket_dynamic/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/socket_win/Makefile.in b/src/libcharon/plugins/socket_win/Makefile.in
index 88b2ac3f0..0c3bf31b9 100644
--- a/src/libcharon/plugins/socket_win/Makefile.in
+++ b/src/libcharon/plugins/socket_win/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in
index 3c132457b..f74257af2 100644
--- a/src/libcharon/plugins/sql/Makefile.in
+++ b/src/libcharon/plugins/sql/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ 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@
@@ -364,6 +367,8 @@ 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@
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index d4680186a..a316f5c25 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ 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@
@@ -368,6 +371,8 @@ 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@
diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c
index 0f3c38986..cd1b4d093 100644
--- a/src/libcharon/plugins/stroke/stroke_attribute.c
+++ b/src/libcharon/plugins/stroke/stroke_attribute.c
@@ -94,7 +94,7 @@ static mem_pool_t *find_pool(private_stroke_attribute_t *this, char *name)
*/
static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools,
identification_t *id, host_t *requested,
- mem_pool_op_t operation)
+ mem_pool_op_t operation, host_t *peer)
{
host_t *addr = NULL;
enumerator_t *enumerator;
@@ -107,7 +107,7 @@ static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools,
pool = find_pool(this, name);
if (pool)
{
- addr = pool->acquire_address(pool, id, requested, operation);
+ addr = pool->acquire_address(pool, id, requested, operation, peer);
if (addr)
{
break;
@@ -120,20 +120,24 @@ static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools,
}
METHOD(attribute_provider_t, acquire_address, host_t*,
- private_stroke_attribute_t *this, linked_list_t *pools, identification_t *id,
+ private_stroke_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
host_t *requested)
{
- host_t *addr;
+ identification_t *id;
+ host_t *addr, *peer;
+
+ id = ike_sa->get_other_eap_id(ike_sa);
+ peer = ike_sa->get_other_host(ike_sa);
this->lock->read_lock(this->lock);
- addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING);
+ addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING, peer);
if (!addr)
{
- addr = find_addr(this, pools, id, requested, MEM_POOL_NEW);
+ addr = find_addr(this, pools, id, requested, MEM_POOL_NEW, peer);
if (!addr)
{
- addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN);
+ addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN, peer);
}
}
@@ -144,13 +148,16 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
METHOD(attribute_provider_t, release_address, bool,
private_stroke_attribute_t *this, linked_list_t *pools, host_t *address,
- identification_t *id)
+ ike_sa_t *ike_sa)
{
enumerator_t *enumerator;
+ identification_t *id;
mem_pool_t *pool;
bool found = FALSE;
char *name;
+ id = ike_sa->get_other_eap_id(ike_sa);
+
enumerator = pools->create_enumerator(pools);
this->lock->read_lock(this->lock);
while (enumerator->enumerate(enumerator, &name))
@@ -197,9 +204,8 @@ static bool attr_filter(void *lock, host_t **in,
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_stroke_attribute_t *this, linked_list_t *pools,
- identification_t *id, linked_list_t *vips)
+ ike_sa_t *ike_sa, linked_list_t *vips)
{
- ike_sa_t *ike_sa;
peer_cfg_t *peer_cfg;
enumerator_t *enumerator;
attributes_t *attr;
@@ -413,4 +419,3 @@ stroke_attribute_t *stroke_attribute_create()
return &this->public;
}
-
diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c
index f8026875f..b470b81c6 100644
--- a/src/libcharon/plugins/stroke/stroke_ca.c
+++ b/src/libcharon/plugins/stroke/stroke_ca.c
@@ -120,6 +120,84 @@ static void ca_section_destroy(ca_section_t *this)
}
/**
+ * Data for the certificate enumerator
+ */
+typedef struct {
+ private_stroke_ca_t *this;
+ certificate_type_t cert;
+ key_type_t key;
+ identification_t *id;
+} cert_data_t;
+
+/**
+ * destroy cert_data
+ */
+static void cert_data_destroy(cert_data_t *data)
+{
+ data->this->lock->unlock(data->this->lock);
+ free(data);
+}
+
+/**
+ * filter function for certs enumerator
+ */
+static bool certs_filter(cert_data_t *data, ca_section_t **in,
+ certificate_t **out)
+{
+ public_key_t *public;
+ certificate_t *cert = (*in)->cert;
+
+ if (data->cert == CERT_ANY || data->cert == cert->get_type(cert))
+ {
+ public = cert->get_public_key(cert);
+ if (public)
+ {
+ if (data->key == KEY_ANY || data->key == public->get_type(public))
+ {
+ if (data->id && public->has_fingerprint(public,
+ data->id->get_encoding(data->id)))
+ {
+ public->destroy(public);
+ *out = cert;
+ return TRUE;
+ }
+ }
+ public->destroy(public);
+ }
+ else if (data->key != KEY_ANY)
+ {
+ return FALSE;
+ }
+ if (data->id == NULL || cert->has_subject(cert, data->id))
+ {
+ *out = cert;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+ private_stroke_ca_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ enumerator_t *enumerator;
+ cert_data_t *data;
+
+ INIT(data,
+ .this = this,
+ .cert = cert,
+ .key = key,
+ .id = id,
+ );
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->sections->create_enumerator(this->sections);
+ return enumerator_create_filter(enumerator, (void*)certs_filter, data,
+ (void*)cert_data_destroy);
+}
+
+/**
* data to pass to create_inner_cdp
*/
typedef struct {
@@ -438,7 +516,7 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
.public = {
.set = {
.create_private_enumerator = (void*)return_null,
- .create_cert_enumerator = (void*)return_null,
+ .create_cert_enumerator = _create_cert_enumerator,
.create_shared_enumerator = (void*)return_null,
.create_cdp_enumerator = _create_cdp_enumerator,
.cache_cert = (void*)nop,
@@ -456,4 +534,3 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
return &this->public;
}
-
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index 62967b006..55ec7cdc9 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2014 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -301,7 +301,8 @@ static void build_crl_policy(auth_cfg_t *cfg, bool local, int policy)
static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
{
enumerator_t *enumerator;
- bool rsa = FALSE, ecdsa = FALSE, rsa_len = FALSE, ecdsa_len = FALSE;
+ bool rsa = FALSE, ecdsa = FALSE, bliss = FALSE,
+ rsa_len = FALSE, ecdsa_len = FALSE, bliss_strength = FALSE;
int strength;
char *token;
@@ -328,9 +329,12 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
{ "sha256", SIGN_ECDSA_256, KEY_ECDSA, },
{ "sha384", SIGN_ECDSA_384, KEY_ECDSA, },
{ "sha512", SIGN_ECDSA_521, KEY_ECDSA, },
+ { "sha256", SIGN_BLISS_WITH_SHA256, KEY_BLISS, },
+ { "sha384", SIGN_BLISS_WITH_SHA384, KEY_BLISS, },
+ { "sha512", SIGN_BLISS_WITH_SHA512, KEY_BLISS, },
};
- if (rsa_len || ecdsa_len)
+ if (rsa_len || ecdsa_len || bliss_strength)
{ /* expecting a key strength token */
strength = atoi(token);
if (strength)
@@ -343,8 +347,12 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
{
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 = FALSE;
+ rsa_len = ecdsa_len = bliss_strength = FALSE;
if (strength)
{
continue;
@@ -360,6 +368,11 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
ecdsa = ecdsa_len = TRUE;
continue;
}
+ if (streq(token, "bliss"))
+ {
+ bliss = bliss_strength = TRUE;
+ continue;
+ }
if (streq(token, "pubkey"))
{
continue;
@@ -376,7 +389,8 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
*/
if ((rsa && schemes[i].key == KEY_RSA) ||
(ecdsa && schemes[i].key == KEY_ECDSA) ||
- (!rsa && !ecdsa))
+ (bliss && schemes[i].key == KEY_BLISS) ||
+ (!rsa && !ecdsa && !bliss))
{
cfg->add(cfg, AUTH_RULE_SIGNATURE_SCHEME,
(uintptr_t)schemes[i].scheme);
@@ -590,7 +604,8 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
/* authentication metod (class, actually) */
if (strpfx(auth, "pubkey") ||
strpfx(auth, "rsa") ||
- strpfx(auth, "ecdsa"))
+ 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);
@@ -620,9 +635,16 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
else if (strpfx(auth, "eap"))
{
eap_vendor_type_t *type;
+ char *pos;
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
-
+ /* check for public key constraints for EAP-TLS etc. */
+ pos = strchr(auth, ':');
+ if (pos)
+ {
+ *pos = 0;
+ parse_pubkey_constraints(pos + 1, cfg);
+ }
type = eap_vendor_type_from_string(auth);
if (type)
{
@@ -667,6 +689,24 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
}
/**
+ * build a mem_pool_t from an address range
+ */
+static mem_pool_t *create_pool_range(char *str)
+{
+ mem_pool_t *pool;
+ host_t *from, *to;
+
+ if (!host_create_from_range(str, &from, &to))
+ {
+ return NULL;
+ }
+ pool = mem_pool_create_range(str, from, to);
+ from->destroy(from);
+ to->destroy(to);
+ return pool;
+}
+
+/**
* build a peer_cfg from a stroke msg
*/
static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
@@ -789,17 +829,25 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
}
else
{
- /* in-memory pool, named using CIDR notation */
+ /* in-memory pool, using range or CIDR notation */
+ mem_pool_t *pool;
host_t *base;
int bits;
- base = host_create_from_subnet(token, &bits);
- if (base)
+ pool = create_pool_range(token);
+ if (!pool)
+ {
+ base = host_create_from_subnet(token, &bits);
+ if (base)
+ {
+ pool = mem_pool_create(token, base, bits);
+ base->destroy(base);
+ }
+ }
+ if (pool)
{
- this->attributes->add_pool(this->attributes,
- mem_pool_create(token, base, bits));
+ this->attributes->add_pool(this->attributes, pool);
peer_cfg->add_pool(peer_cfg, token);
- base->destroy(base);
}
else
{
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index f770d7c9e..0084fbf93 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -352,7 +352,7 @@ METHOD(stroke_control_t, terminate, void,
if (streq(name, child_sa->get_name(child_sa)))
{
child_list->insert_last(child_list,
- (void*)(uintptr_t)child_sa->get_reqid(child_sa));
+ (void*)(uintptr_t)child_sa->get_unique_id(child_sa));
if (!all)
{
break;
@@ -432,13 +432,13 @@ METHOD(stroke_control_t, rekey, void,
while (children->enumerate(children, (void**)&child_sa))
{
if ((name && streq(name, child_sa->get_name(child_sa))) ||
- (id && id == child_sa->get_reqid(child_sa)))
+ (id && id == child_sa->get_unique_id(child_sa)))
{
lib->processor->queue_job(lib->processor,
(job_t*)rekey_child_sa_job_create(
- child_sa->get_reqid(child_sa),
child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE)));
+ child_sa->get_spi(child_sa, TRUE),
+ ike_sa->get_my_host(ike_sa)));
if (!all)
{
finished = TRUE;
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index 83431d17c..5e423f1de 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -70,11 +70,21 @@ struct private_stroke_cred_t {
char *secrets_file;
/**
- * credentials
+ * credentials: end entity certs, attribute certs, CRLs, etc.
*/
mem_cred_t *creds;
/**
+ * CA certificates
+ */
+ mem_cred_t *cacerts;
+
+ /**
+ * Attribute Authority certificates
+ */
+ mem_cred_t *aacerts;
+
+ /**
* ignore missing CA basic constraint (i.e. treat all certificates in
* ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
*/
@@ -231,7 +241,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
}
DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
cert->get_subject(cert), filename);
- return this->creds->add_cert_ref(this->creds, TRUE, cert);
+ return this->creds->get_cert_ref(this->creds, cert);
}
return NULL;
}
@@ -374,133 +384,183 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
}
/**
- * load trusted certificates from a directory
+ * Load a CA certificate from disk
*/
-static void load_certdir(private_stroke_cred_t *this, char *path,
- certificate_type_t type, x509_flag_t flag)
+static void load_x509_ca(private_stroke_cred_t *this, char *file)
{
- struct stat st;
- char *file;
-
- enumerator_t *enumerator = enumerator_create_directory(path);
+ certificate_t *cert;
- if (!enumerator)
+ if (this->force_ca_cert)
+ { /* treat certificate as CA cert even it has no CA basic constraint */
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, X509_CA, BUILD_END);
+ }
+ else
{
- DBG1(DBG_CFG, " reading directory failed");
- return;
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file, BUILD_END);
}
-
- while (enumerator->enumerate(enumerator, NULL, &file, &st))
+ if (cert)
{
- certificate_t *cert;
+ x509_t *x509 = (x509_t*)cert;
- if (!S_ISREG(st.st_mode))
+ if (!(x509->get_flags(x509) & X509_CA))
{
- /* skip special file */
- continue;
+ DBG1(DBG_CFG, " ca certificate \"%Y\" lacks ca basic constraint, "
+ "discarded", cert->get_subject(cert));
+ cert->destroy(cert);
}
- switch (type)
+ else
{
- case CERT_X509:
- if (flag & X509_CA)
- {
- if (this->force_ca_cert)
- { /* treat this certificate as CA cert even it has no
- * CA basic constraint */
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file, BUILD_X509_FLAG,
- X509_CA, BUILD_END);
- }
- else
- {
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file, BUILD_END);
- }
- if (cert)
- {
- x509_t *x509 = (x509_t*)cert;
-
- if (!(x509->get_flags(x509) & X509_CA))
- {
- DBG1(DBG_CFG, " ca certificate \"%Y\" lacks "
- "ca basic constraint, discarded",
- cert->get_subject(cert));
- cert->destroy(cert);
- cert = NULL;
- }
- else
- {
- DBG1(DBG_CFG, " loaded ca certificate \"%Y\" "
- "from '%s'", cert->get_subject(cert), file);
- }
- }
- else
+ DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), file);
+ this->cacerts->add_cert(this->cacerts, TRUE, cert);
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading ca certificate from '%s' failed", file);
+ }
+}
+
+/**
+ * Load AA certificate with flags from disk
+ */
+static void load_x509_aa(private_stroke_cred_t *this, char *file)
+{
+ certificate_t *cert;
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, X509_AA, BUILD_END);
+ if (cert)
+ {
+ DBG1(DBG_CFG, " loaded AA certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), file);
+ this->aacerts->add_cert(this->aacerts, TRUE, cert);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading AA certificate from '%s' failed", file);
+ }
+}
+
+/**
+ * Load a certificate with flags from disk
+ */
+static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
+{
+ certificate_t *cert;
+
+ /* for all other flags, we add them to the certificate. */
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file,
+ BUILD_X509_FLAG, flag, BUILD_END);
+ if (cert)
+ {
+ DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), file);
+ this->creds->add_cert(this->creds, TRUE, cert);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading certificate from '%s' failed", file);
+ }
+}
+
+/**
+ * Load a CRL from a file
+ */
+static void load_x509_crl(private_stroke_cred_t *this, char *file)
+{
+ certificate_t *cert;
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+ BUILD_FROM_FILE, file, BUILD_END);
+ if (cert)
+ {
+ this->creds->add_crl(this->creds, (crl_t*)cert);
+ DBG1(DBG_CFG, " loaded crl from '%s'", file);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading crl from '%s' failed", file);
+ }
+}
+
+/**
+ * Load an attribute certificate from a file
+ */
+static void load_x509_ac(private_stroke_cred_t *this, char *file)
+{
+ certificate_t *cert;
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
+ BUILD_FROM_FILE, file, BUILD_END);
+ if (cert)
+ {
+ DBG1(DBG_CFG, " loaded attribute certificate from '%s'", file);
+ this->creds->add_cert(this->creds, FALSE, cert);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading attribute certificate from '%s' failed", file);
+ }
+}
+
+/**
+ * load trusted certificates from a directory
+ */
+static void load_certdir(private_stroke_cred_t *this, char *path,
+ certificate_type_t type, x509_flag_t flag)
+{
+ enumerator_t *enumerator;
+ struct stat st;
+ char *file;
+
+ enumerator = enumerator_create_directory(path);
+ if (enumerator)
+ {
+ while (enumerator->enumerate(enumerator, NULL, &file, &st))
+ {
+ if (!S_ISREG(st.st_mode))
+ {
+ /* skip special file */
+ continue;
+ }
+ switch (type)
+ {
+ case CERT_X509:
+ if (flag & X509_CA)
{
- DBG1(DBG_CFG, " loading ca certificate from '%s' "
- "failed", file);
+ load_x509_ca(this, file);
}
- }
- else
- { /* for all other flags, we add them to the certificate. */
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file,
- BUILD_X509_FLAG, flag, BUILD_END);
- if (cert)
+ else if (flag & X509_AA)
{
- DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'",
- cert->get_subject(cert), file);
+ load_x509_aa(this, file);
}
else
{
- DBG1(DBG_CFG, " loading certificate from '%s' "
- "failed", file);
+ load_x509(this, file, flag);
}
- }
- if (cert)
- {
- this->creds->add_cert(this->creds, TRUE, cert);
- }
- break;
- case CERT_X509_CRL:
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509_CRL,
- BUILD_FROM_FILE, file,
- BUILD_END);
- if (cert)
- {
- this->creds->add_crl(this->creds, (crl_t*)cert);
- DBG1(DBG_CFG, " loaded crl from '%s'", file);
- }
- else
- {
- DBG1(DBG_CFG, " loading crl from '%s' failed", file);
- }
- break;
- case CERT_X509_AC:
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509_AC,
- BUILD_FROM_FILE, file,
- BUILD_END);
- if (cert)
- {
- this->creds->add_cert(this->creds, FALSE, cert);
- DBG1(DBG_CFG, " loaded attribute certificate from '%s'",
- file);
- }
- else
- {
- DBG1(DBG_CFG, " loading attribute certificate from '%s' "
- "failed", file);
- }
- break;
- default:
- break;
+ break;
+ case CERT_X509_CRL:
+ load_x509_crl(this, file);
+ break;
+ case CERT_X509_AC:
+ load_x509_ac(this, file);
+ break;
+ default:
+ break;
+ }
}
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " reading directory failed");
}
- enumerator->destroy(enumerator);
}
METHOD(stroke_cred_t, cache_cert, void,
@@ -1124,6 +1184,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
while (fetchline(src, &line))
{
chunk_t ids, token;
+ key_type_t key_type;
shared_key_type_t type;
line_nr++;
@@ -1222,10 +1283,22 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
DBG1(DBG_CFG, "line %d: missing token", line_nr);
break;
}
- if (match("RSA", &token) || match("ECDSA", &token))
+ if (match("RSA", &token) || match("ECDSA", &token) ||
+ match("BLISS", &token))
{
- if (!load_private(secrets, line, line_nr, prompt,
- match("RSA", &token) ? KEY_RSA : KEY_ECDSA))
+ if (match("RSA", &token))
+ {
+ key_type = KEY_RSA;
+ }
+ else if (match("ECDSA", &token))
+ {
+ key_type = KEY_ECDSA;
+ }
+ else
+ {
+ key_type = KEY_BLISS;
+ }
+ if (!load_private(secrets, line, line_nr, prompt, key_type))
{
break;
}
@@ -1256,8 +1329,8 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
}
else
{
- DBG1(DBG_CFG, "line %d: token must be either "
- "RSA, ECDSA, P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
+ DBG1(DBG_CFG, "line %d: token must be either RSA, ECDSA, BLISS, "
+ "P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
break;
}
}
@@ -1308,6 +1381,8 @@ METHOD(stroke_cred_t, reread, void,
{
DBG1(DBG_CFG, "rereading ca certificates from '%s'",
CA_CERTIFICATE_DIR);
+ this->cacerts->clear(this->cacerts);
+ lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
}
if (msg->reread.flags & REREAD_OCSPCERTS)
@@ -1321,6 +1396,8 @@ METHOD(stroke_cred_t, reread, void,
{
DBG1(DBG_CFG, "rereading aa certificates from '%s'",
AA_CERTIFICATE_DIR);
+ this->aacerts->clear(this->aacerts);
+ lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
}
if (msg->reread.flags & REREAD_ACERTS)
@@ -1346,7 +1423,11 @@ METHOD(stroke_cred_t, add_shared, void,
METHOD(stroke_cred_t, destroy, void,
private_stroke_cred_t *this)
{
+ lib->credmgr->remove_set(lib->credmgr, &this->aacerts->set);
+ lib->credmgr->remove_set(lib->credmgr, &this->cacerts->set);
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
+ this->aacerts->destroy(this->aacerts);
+ this->cacerts->destroy(this->cacerts);
this->creds->destroy(this->creds);
free(this);
}
@@ -1379,9 +1460,13 @@ stroke_cred_t *stroke_cred_create()
"%s.plugins.stroke.secrets_file", SECRETS_FILE,
lib->ns),
.creds = mem_cred_create(),
+ .cacerts = mem_cred_create(),
+ .aacerts = mem_cred_create(),
);
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
+ lib->credmgr->add_set(lib->credmgr, &this->cacerts->set);
+ lib->credmgr->add_set(lib->credmgr, &this->aacerts->set);
this->force_ca_cert = lib->settings->get_bool(lib->settings,
"%s.plugins.stroke.ignore_missing_ca_basic_constraint",
diff --git a/src/libcharon/plugins/stroke/stroke_cred.h b/src/libcharon/plugins/stroke/stroke_cred.h
index f6fbb96d3..9434629ef 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.h
+++ b/src/libcharon/plugins/stroke/stroke_cred.h
@@ -50,10 +50,13 @@ struct stroke_cred_t {
void (*reread)(stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt);
/**
- * Load a CA certificate, and serve it through the credential_set.
+ * Load a CA certificate.
+ *
+ * This method does not add the loaded CA certificate to the internal
+ * credentail set, but returns it only.
*
* @param filename file to load CA cert from
- * @return reference to loaded certificate, or NULL
+ * @return loaded certificate, or NULL
*/
certificate_t* (*load_ca)(stroke_cred_t *this, char *filename);
diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c
index fef8cab67..d0cc9afab 100644
--- a/src/libcharon/plugins/stroke/stroke_handler.c
+++ b/src/libcharon/plugins/stroke/stroke_handler.c
@@ -94,10 +94,9 @@ static bool attr_filter(void *lock, host_t **in,
}
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
- private_stroke_handler_t *this, identification_t *server,
+ private_stroke_handler_t *this, ike_sa_t *ike_sa,
linked_list_t *vips)
{
- ike_sa_t *ike_sa;
peer_cfg_t *peer_cfg;
enumerator_t *enumerator;
attributes_t *attr;
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index 1aa49ce0d..68b8232bc 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -214,11 +214,12 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
config = child_sa->get_config(child_sa);
now = time_monotonic(NULL);
- fprintf(out, "%12s{%d}: %N, %N%s",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ fprintf(out, "%12s{%d}: %N, %N%s, reqid %u",
+ child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
child_sa_state_names, child_sa->get_state(child_sa),
ipsec_mode_names, child_sa->get_mode(child_sa),
- config->use_proxy_mode(config) ? "_PROXY" : "");
+ config->use_proxy_mode(config) ? "_PROXY" : "",
+ child_sa->get_reqid(child_sa));
if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
{
@@ -238,7 +239,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
if (all)
{
fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa),
- child_sa->get_reqid(child_sa));
+ child_sa->get_unique_id(child_sa));
proposal = child_sa->get_proposal(child_sa);
if (proposal)
@@ -322,7 +323,8 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
}
}
- else if (child_sa->get_state(child_sa) == CHILD_REKEYING)
+ else if (child_sa->get_state(child_sa) == CHILD_REKEYING ||
+ child_sa->get_state(child_sa) == CHILD_REKEYED)
{
rekey = child_sa->get_lifetime(child_sa, TRUE);
fprintf(out, ", expires in %V", &now, &rekey);
@@ -333,7 +335,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
other_ts = linked_list_create_from_enumerator(
child_sa->create_ts_enumerator(child_sa, FALSE));
fprintf(out, "\n%12s{%d}: %#R=== %#R\n",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
my_ts, other_ts);
my_ts->destroy(my_ts);
other_ts->destroy(other_ts);
@@ -496,7 +498,7 @@ METHOD(stroke_list_t, status, void,
{
struct mallinfo mi = mallinfo();
- fprintf(out, " malloc: sbrk %d, mmap %d, used %d, free %d\n",
+ fprintf(out, " malloc: sbrk %u, mmap %u, used %u, free %u\n",
mi.arena, mi.hblkhd, mi.uordblks, mi.fordblks);
}
#endif /* HAVE_MALLINFO */
diff --git a/src/libcharon/plugins/stroke/stroke_plugin.c b/src/libcharon/plugins/stroke/stroke_plugin.c
index 31df1f99b..f64b99f08 100644
--- a/src/libcharon/plugins/stroke/stroke_plugin.c
+++ b/src/libcharon/plugins/stroke/stroke_plugin.c
@@ -69,6 +69,7 @@ METHOD(plugin_t, get_features, int,
PLUGIN_SDEPEND(PRIVKEY, KEY_RSA),
PLUGIN_SDEPEND(PRIVKEY, KEY_ECDSA),
PLUGIN_SDEPEND(PRIVKEY, KEY_DSA),
+ PLUGIN_SDEPEND(PRIVKEY, KEY_BLISS),
PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY),
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509_CRL),
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index 54dd56e91..db7e66f14 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -24,7 +24,6 @@
#include <unistd.h>
#include <errno.h>
-#include <hydra.h>
#include <daemon.h>
#include "stroke_config.h"
@@ -747,8 +746,10 @@ METHOD(stroke_socket_t, destroy, void,
lib->credmgr->remove_set(lib->credmgr, &this->ca->set);
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
charon->backends->remove_backend(charon->backends, &this->config->backend);
- hydra->attributes->remove_provider(hydra->attributes, &this->attribute->provider);
- hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
+ charon->attributes->remove_provider(charon->attributes,
+ &this->attribute->provider);
+ charon->attributes->remove_handler(charon->attributes,
+ &this->handler->handler);
charon->bus->remove_listener(charon->bus, &this->counter->listener);
this->cred->destroy(this->cred);
this->ca->destroy(this->ca);
@@ -790,8 +791,10 @@ stroke_socket_t *stroke_socket_create()
lib->credmgr->add_set(lib->credmgr, &this->ca->set);
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
charon->backends->add_backend(charon->backends, &this->config->backend);
- hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider);
- hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
+ charon->attributes->add_provider(charon->attributes,
+ &this->attribute->provider);
+ charon->attributes->add_handler(charon->attributes,
+ &this->handler->handler);
charon->bus->add_listener(charon->bus, &this->counter->listener);
max_concurrent = lib->settings->get_int(lib->settings,
diff --git a/src/libcharon/plugins/systime_fix/Makefile.in b/src/libcharon/plugins/systime_fix/Makefile.in
index 0e477f9f3..be148b6c3 100644
--- a/src/libcharon/plugins/systime_fix/Makefile.in
+++ b/src/libcharon/plugins/systime_fix/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in
index 3f2952c4b..17cc341c5 100644
--- a/src/libcharon/plugins/tnc_ifmap/Makefile.in
+++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ 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@
@@ -369,6 +372,8 @@ 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@
diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in
index 97c479632..ef05275b7 100644
--- a/src/libcharon/plugins/tnc_pdp/Makefile.in
+++ b/src/libcharon/plugins/tnc_pdp/Makefile.in
@@ -233,6 +233,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -293,10 +294,12 @@ 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@
@@ -370,6 +373,8 @@ 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@
diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c
index 109c216d5..91456f8da 100644
--- a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c
+++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Andreas Steffen
+ * Copyright (C) 2012-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -646,8 +646,8 @@ static bool pt_tls_receive(private_tnc_pdp_t *this, int fd, watcher_event_t even
int pt_tls_fd;
struct sockaddr_storage addr;
socklen_t addrlen = sizeof(addr);
- identification_t *peer;
- host_t *host;
+ identification_t *client_id;
+ host_t *server_ip, *client_ip;
pt_tls_server_t *pt_tls;
tnccs_t *tnccs;
pt_tls_auth_t auth = PT_TLS_AUTH_TLS_OR_SASL;
@@ -658,17 +658,22 @@ static bool pt_tls_receive(private_tnc_pdp_t *this, int fd, watcher_event_t even
DBG1(DBG_TNC, "accepting PT-TLS stream failed: %s", strerror(errno));
return FALSE;
}
- host = host_create_from_sockaddr((sockaddr_t*)&addr);
- DBG1(DBG_TNC, "accepting PT-TLS stream from %H", host);
- host->destroy(host);
+ client_ip = host_create_from_sockaddr((sockaddr_t*)&addr);
+ DBG1(DBG_TNC, "accepting PT-TLS stream from %H", client_ip);
+
+ /* Currently we do not determine the IP address of the server interface */
+ server_ip = host_create_any(client_ip->get_family(client_ip));
- /* At this moment the peer identity is not known yet */
- peer = identification_create_from_encoding(ID_ANY, chunk_empty),
+ /* At this moment the client identity is not known yet */
+ client_id = identification_create_from_encoding(ID_ANY, chunk_empty),
tnccs = tnc->tnccs->create_instance(tnc->tnccs, TNCCS_2_0, TRUE,
- this->server, peer, TNC_IFT_TLS_2_0,
+ this->server, client_id, server_ip,
+ client_ip, TNC_IFT_TLS_2_0,
(tnccs_cb_t)get_recommendation);
- peer->destroy(peer);
+ client_id->destroy(client_id);
+ server_ip->destroy(server_ip);
+ client_ip->destroy(client_ip);
if (!tnccs)
{
diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in
index 5e16c3c35..2c031383a 100644
--- a/src/libcharon/plugins/uci/Makefile.in
+++ b/src/libcharon/plugins/uci/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ 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@
@@ -364,6 +367,8 @@ 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@
diff --git a/src/libcharon/plugins/unit_tester/Makefile.am b/src/libcharon/plugins/unit_tester/Makefile.am
deleted file mode 100644
index b7f8fc319..000000000
--- a/src/libcharon/plugins/unit_tester/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-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-unit-tester.la
-else
-plugin_LTLIBRARIES = libstrongswan-unit-tester.la
-endif
-
-libstrongswan_unit_tester_la_SOURCES = \
- unit_tester.c unit_tester.h tests.h \
- tests/test_auth_info.c \
- tests/test_curl.c \
- tests/test_mysql.c \
- tests/test_sqlite.c \
- tests/test_cert.c \
- tests/test_med_db.c \
- tests/test_pool.c \
- tests/test_agent.c
-
-libstrongswan_unit_tester_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/unit_tester/tests/test_agent.c b/src/libcharon/plugins/unit_tester/tests/test_agent.c
deleted file mode 100644
index baab629be..000000000
--- a/src/libcharon/plugins/unit_tester/tests/test_agent.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-
-/*******************************************************************************
- * SSH agent signature creation and verification
- ******************************************************************************/
-bool test_agent()
-{
- char *path;
- chunk_t sig, data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08);
- private_key_t *private;
- public_key_t *public;
-
- path = getenv("SSH_AUTH_SOCK");
- if (!path)
- {
- DBG1(DBG_CFG, "ssh-agent not found.");
- return FALSE;
- }
-
- private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
- BUILD_AGENT_SOCKET, path, BUILD_END);
- if (!private)
- {
- return FALSE;
- }
- if (!private->sign(private, SIGN_RSA_EMSA_PKCS1_SHA1, data, &sig))
- {
- return FALSE;
- }
- public = private->get_public_key(private);
- if (!public)
- {
- return FALSE;;
- }
- if (!public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig))
- {
- return FALSE;
- }
- free(sig.ptr);
- data.ptr[1] = 0x01; /* fake it */
- if (public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig))
- {
- return FALSE;
- }
-
- private->destroy(private);
- public->destroy(public);
-
- return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_auth_info.c b/src/libcharon/plugins/unit_tester/tests/test_auth_info.c
deleted file mode 100644
index c250c356f..000000000
--- a/src/libcharon/plugins/unit_tester/tests/test_auth_info.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <daemon.h>
-#include <library.h>
-#include <credentials/auth_cfg.h>
-
-
-static chunk_t certchunk = chunk_from_chars(
- 0x30,0x82,0x02,0xfa,0x30,0x82,0x01,0xe2,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x5a,
- 0xf2,0x65,0xae,0x78,0xff,0x23,0xde,0xf7,0xa6,0xa3,0x94,0x8c,0x3f,0xa0,0xc1,0x30,
- 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x39,
- 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,
- 0x17,0x06,0x03,0x55,0x04,0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,
- 0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,
- 0x03,0x13,0x06,0x6d,0x61,0x72,0x74,0x69,0x6e,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,
- 0x34,0x32,0x37,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x17,0x0d,0x31,0x32,0x30,0x34,
- 0x32,0x35,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x30,0x39,0x31,0x0b,0x30,0x09,0x06,
- 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,
- 0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,
- 0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x6d,0x61,
- 0x72,0x74,0x69,0x6e,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
- 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,
- 0x02,0x82,0x01,0x01,0x00,0xd7,0xb9,0xba,0x4d,0xe2,0x3b,0x3d,0x35,0x7a,0x3f,0x88,
- 0x67,0x95,0xe7,0xfd,0x9f,0xe9,0x0a,0x0d,0x79,0x3a,0x9e,0x21,0x8f,0xcb,0xe4,0x67,
- 0x24,0xae,0x0c,0xda,0xb3,0xcc,0xec,0x36,0xb4,0xa8,0x4d,0xf1,0x3d,0xad,0xe4,0x8c,
- 0x63,0x92,0x54,0xb7,0xb2,0x02,0xa2,0x00,0x62,0x8b,0x04,0xac,0xa0,0x17,0xad,0x17,
- 0x9a,0x05,0x0d,0xd7,0xb3,0x08,0x02,0xc5,0x26,0xcf,0xdd,0x05,0x42,0xfc,0x13,0x6d,
- 0x9f,0xb1,0xf3,0x4f,0x82,0x1d,0xef,0x01,0xc9,0x91,0xea,0x37,0x1b,0x79,0x28,0xfa,
- 0xbf,0x9f,0xb3,0xeb,0x82,0x4f,0x10,0xc6,0x4b,0xa4,0x08,0xf7,0x8e,0xf2,0x00,0xea,
- 0x04,0x97,0x80,0x9f,0x65,0x86,0xde,0x6b,0xc7,0xda,0x83,0xfc,0xad,0x4a,0xaf,0x52,
- 0x8b,0x4d,0x33,0xee,0x49,0x87,0x2f,0x3b,0x60,0x45,0x66,0x8f,0xe6,0x89,0xcc,0xb1,
- 0x92,0x02,0x17,0x2b,0x7b,0x8e,0x90,0x47,0x84,0x84,0x59,0x95,0x81,0xd8,0xe0,0xf3,
- 0x87,0xe0,0x04,0x09,0xfd,0xcc,0x3a,0x21,0x34,0xfa,0xec,0xbe,0xf5,0x9c,0xcf,0x55,
- 0x80,0x7b,0xe3,0x75,0x9d,0x36,0x68,0xab,0x83,0xe3,0xad,0x01,0x53,0x0d,0x8a,0x9a,
- 0xa6,0xb0,0x15,0xc9,0xc5,0xf8,0x9b,0x51,0x32,0xcf,0x97,0x6c,0xfe,0x4a,0x56,0x3c,
- 0xc8,0x8f,0x4a,0x70,0x23,0x4f,0xf6,0xf7,0xe6,0x9f,0x09,0xcd,0x8f,0xea,0x20,0x7d,
- 0x34,0xc0,0xc5,0xc0,0x34,0x06,0x6f,0x8b,0xeb,0x04,0x54,0x3f,0x0e,0xcd,0xe2,0x85,
- 0xab,0x94,0x3e,0x91,0x6c,0x18,0x6f,0x96,0x5d,0xf2,0x8b,0x10,0xe9,0x90,0x43,0xb0,
- 0x61,0x52,0xac,0xcf,0x75,0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,
- 0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x09,0x63,
- 0x42,0xad,0xe5,0xa3,0xf6,0xc9,0x5d,0x08,0xf2,0x78,0x7b,0xeb,0x8a,0xef,0x50,0x00,
- 0xc8,0xeb,0xe9,0x26,0x94,0xcb,0x84,0x10,0x7e,0x42,0x6b,0x86,0x38,0x57,0xa6,0x02,
- 0x98,0x5a,0x2c,0x8f,0x44,0x32,0x1b,0x97,0x8c,0x7e,0x4b,0xd8,0xe8,0xe8,0x0f,0x4a,
- 0xb9,0x31,0x9f,0xf6,0x9f,0x0e,0x67,0x26,0x05,0x2a,0x99,0x14,0x35,0x41,0x47,0x9a,
- 0xfa,0x12,0x94,0x0b,0xe9,0x27,0x7c,0x71,0x20,0xd7,0x8d,0x3b,0x97,0x19,0x2d,0x15,
- 0xff,0xa4,0xf3,0x89,0x8d,0x29,0x5f,0xf6,0x3f,0x93,0xaf,0x78,0x61,0xe4,0xe1,0x2e,
- 0x75,0xc1,0x2c,0xc4,0x76,0x95,0x19,0xf8,0x37,0xdc,0xd8,0x00,0x7a,0x3c,0x0f,0x49,
- 0x2e,0x88,0x09,0x16,0xb3,0x92,0x33,0xdf,0x77,0x83,0x4f,0xb5,0x9e,0x30,0x8c,0x48,
- 0x1d,0xd8,0x84,0xfb,0xf1,0xb9,0xa0,0xbe,0x25,0xff,0x4c,0xeb,0xef,0x2b,0xcd,0xfa,
- 0x0b,0x94,0x66,0x3b,0x28,0x08,0x3f,0x3a,0xda,0x41,0xd0,0x6b,0xab,0x5e,0xbb,0x8a,
- 0x9f,0xdc,0x98,0x3e,0x59,0x37,0x48,0xbe,0x69,0xde,0x85,0x82,0xf2,0x53,0x8b,0xe4,
- 0x44,0xe4,0x71,0x91,0x14,0x85,0x0e,0x1e,0x79,0xdd,0x62,0xf5,0xdc,0x25,0x89,0xab,
- 0x50,0x5b,0xaa,0xae,0xe3,0x64,0x6a,0x23,0x34,0xd7,0x30,0xe2,0x2a,0xc8,0x81,0x0c,
- 0xec,0xd2,0x31,0xc6,0x1e,0xb6,0xc0,0x57,0xd9,0xe1,0x14,0x06,0x9b,0xf8,0x51,0x69,
- 0x47,0xf0,0x9c,0xcd,0x69,0xef,0x8e,0x5f,0x62,0xda,0x10,0xf7,0x3c,0x6d,0x0f,0x33,
- 0xec,0x6f,0xfd,0x94,0x07,0x16,0x41,0x32,0x06,0xa4,0xe1,0x08,0x31,0x87,
-);
-
-/*******************************************************************************
- * auth info test
- ******************************************************************************/
-bool test_auth_cfg()
-{
- auth_cfg_t *auth = auth_cfg_create(), *auth2;
- certificate_t *c1, *c2;
- enumerator_t *enumerator;
- int round = 0;
- void *value;
- auth_rule_t type;
-
- c1 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, certchunk,
- BUILD_END);
- if (!c1)
- {
- return FALSE;
- }
-
- auth->add(auth, AUTH_RULE_SUBJECT_CERT, c1->get_ref(c1));
- c2 = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
- if (!c2)
- {
- return FALSE;
- }
- if (!c1->equals(c1, c2))
- {
- return FALSE;
- }
-
- enumerator = auth->create_enumerator(auth);
- while (enumerator->enumerate(enumerator, &type, &value))
- {
- round++;
- if (round == 1 && type == AUTH_RULE_SUBJECT_CERT && value == c1)
- {
- continue;
- }
- return FALSE;
- }
- enumerator->destroy(enumerator);
-
- auth2 = auth_cfg_create();
- auth2->add(auth2, AUTH_RULE_CA_CERT, c1->get_ref(c1));
- auth2->merge(auth2, auth, FALSE);
-
- round = 0;
- enumerator = auth2->create_enumerator(auth2);
- while (enumerator->enumerate(enumerator, &type, &value))
- {
- round++;
- if (round == 1 && type == AUTH_RULE_CA_CERT && value == c1)
- {
- continue;
- }
- if (round == 2 && type == AUTH_RULE_SUBJECT_CERT && value == c1)
- {
- continue;
- }
- return FALSE;
- }
- enumerator->destroy(enumerator);
- auth->destroy(auth);
- auth2->destroy(auth2);
- c1->destroy(c1);
- return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_cert.c b/src/libcharon/plugins/unit_tester/tests/test_cert.c
deleted file mode 100644
index f4410a688..000000000
--- a/src/libcharon/plugins/unit_tester/tests/test_cert.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-#include <credentials/certificates/x509.h>
-
-/*******************************************************************************
- * X509 certificate generation and parsing
- ******************************************************************************/
-bool test_cert_x509()
-{
- private_key_t *ca_key, *peer_key;
- public_key_t *public;
- certificate_t *ca_cert, *peer_cert, *parsed;
- identification_t *issuer, *subject;
- u_int32_t serial = htonl(0);
- chunk_t encoding;
-
- issuer = identification_create_from_string("CN=CA, OU=Test, O=strongSwan");
- subject = identification_create_from_string("CN=Peer, OU=Test, O=strongSwan");
-
- ca_key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
- BUILD_KEY_SIZE, 1024, BUILD_END);
- peer_key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
- BUILD_KEY_SIZE, 1024, BUILD_END);
- if (!ca_key)
- {
- return FALSE;
- }
- ca_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_SIGNING_KEY, ca_key,
- BUILD_SUBJECT, issuer,
- BUILD_SERIAL, chunk_from_thing(serial),
- BUILD_X509_FLAG, X509_CA,
- BUILD_END);
- if (!ca_cert)
- {
- return FALSE;
- }
-
- ca_cert->get_encoding(ca_cert, CERT_ASN1_DER, &encoding);
- parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, encoding,
- BUILD_END);
- chunk_free(&encoding);
- if (!parsed)
- {
- return FALSE;
- }
- if (!parsed->issued_by(parsed, ca_cert, NULL))
- {
- return FALSE;
- }
- parsed->destroy(parsed);
-
- serial = htonl(ntohl(serial) + 1);
- public = peer_key->get_public_key(peer_key);
- peer_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_SIGNING_KEY, ca_key,
- BUILD_SIGNING_CERT, ca_cert,
- BUILD_PUBLIC_KEY, public,
- BUILD_SUBJECT, subject,
- BUILD_SERIAL, chunk_from_thing(serial),
- BUILD_END);
- public->destroy(public);
- if (!peer_cert)
- {
- return FALSE;
- }
-
- peer_cert->get_encoding(peer_cert, CERT_ASN1_DER, &encoding);
- parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, encoding,
- BUILD_END);
- chunk_free(&encoding);
- if (!parsed)
- {
- return FALSE;
- }
- if (!parsed->issued_by(parsed, ca_cert, NULL))
- {
- return FALSE;
- }
- parsed->destroy(parsed);
-
- ca_cert->destroy(ca_cert);
- ca_key->destroy(ca_key);
- peer_cert->destroy(peer_cert);
- peer_key->destroy(peer_key);
- issuer->destroy(issuer);
- subject->destroy(subject);
- return TRUE;
-}
-
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_curl.c b/src/libcharon/plugins/unit_tester/tests/test_curl.c
deleted file mode 100644
index 21656a94e..000000000
--- a/src/libcharon/plugins/unit_tester/tests/test_curl.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <daemon.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-/*******************************************************************************
- * curl get test
- ******************************************************************************/
-
-bool test_curl_get()
-{
- chunk_t chunk;
-
- if (lib->fetcher->fetch(lib->fetcher, "http://www.strongswan.org",
- &chunk, FETCH_END) != SUCCESS)
- {
- return FALSE;
- }
- free(chunk.ptr);
-
- if (lib->fetcher->fetch(lib->fetcher, "http://www.google.com",
- &chunk, FETCH_END) != SUCCESS)
- {
- return FALSE;
- }
- free(chunk.ptr);
- return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_med_db.c b/src/libcharon/plugins/unit_tester/tests/test_med_db.c
deleted file mode 100644
index 75244ab8f..000000000
--- a/src/libcharon/plugins/unit_tester/tests/test_med_db.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-#include <collections/enumerator.h>
-
-#include <unistd.h>
-
-/*******************************************************************************
- * fetch public key from mediation database
- ******************************************************************************/
-
-bool test_med_db()
-{
- chunk_t found, keyid = chunk_from_chars(
- 0xed,0x90,0xe6,0x4f,0xec,0xa2,0x1f,0x4b,
- 0x68,0x97,0x99,0x24,0x22,0xe0,0xde,0x21,
- 0xb9,0xd6,0x26,0x29
- );
- identification_t *id;
- enumerator_t *enumerator;
- public_key_t *public;
- auth_cfg_t *auth;
- bool good = FALSE;
-
- id = identification_create_from_encoding(ID_KEY_ID, keyid);
- enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
- KEY_ANY, id, NULL);
- while (enumerator->enumerate(enumerator, &public, &auth))
- {
- good = public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &found);
- if (good)
- {
- good = chunk_equals(id->get_encoding(id), found);
- }
- }
- enumerator->destroy(enumerator);
- id->destroy(id);
- return good;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_mysql.c b/src/libcharon/plugins/unit_tester/tests/test_mysql.c
deleted file mode 100644
index eda238623..000000000
--- a/src/libcharon/plugins/unit_tester/tests/test_mysql.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-#include <collections/enumerator.h>
-
-/*******************************************************************************
- * mysql simple test
- ******************************************************************************/
-bool test_mysql()
-{
- database_t *db;
- char *txt = "I'm a superduper test";
- chunk_t data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08);
- int row;
- chunk_t qdata;
- char *qtxt;
- bool good = FALSE;
- enumerator_t *enumerator;
-
- db = lib->db->create(lib->db, "mysql://testuser:testpass@localhost/test");
- if (!db)
- {
- return FALSE;
- }
- if (db->execute(db, NULL, "CREATE TABLE test ("
- "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
- "txt TEXT, data BLOB)") < 0)
- {
- return FALSE;
- }
- if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)",
- DB_TEXT, txt, DB_BLOB, data) < 0)
- {
- return FALSE;
- }
- if (row != 1)
- {
- return FALSE;
- }
- enumerator = db->query(db, "SELECT txt, data FROM test WHERE id = ?",
- DB_INT, row,
- DB_TEXT, DB_BLOB);
- if (!enumerator)
- {
- return FALSE;
- }
- while (enumerator->enumerate(enumerator, &qtxt, &qdata))
- {
- if (good)
- { /* only one row */
- good = FALSE;
- break;
- }
- if (streq(qtxt, txt) && chunk_equals(data, qdata))
- {
- good = TRUE;
- }
- }
- enumerator->destroy(enumerator);
- if (!good)
- {
- return FALSE;
- }
- if (db->execute(db, NULL, "DELETE FROM test WHERE id = ?", DB_INT, row) != 1)
- {
- return FALSE;
- }
- if (db->execute(db, NULL, "DROP TABLE test") < 0)
- {
- return FALSE;
- }
- db->destroy(db);
- return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_pool.c b/src/libcharon/plugins/unit_tester/tests/test_pool.c
deleted file mode 100644
index f36953f3a..000000000
--- a/src/libcharon/plugins/unit_tester/tests/test_pool.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <time.h>
-
-#include <library.h>
-#include <threading/thread.h>
-#include <hydra.h>
-
-#define ALLOCS 1000
-#define THREADS 20
-
-static void* testing(void *thread)
-{
- int i;
- host_t *addr[ALLOCS];
- identification_t *id[ALLOCS];
- linked_list_t *pools;
-
- /* prepare identities */
- for (i = 0; i < ALLOCS; i++)
- {
- char buf[256];
-
- snprintf(buf, sizeof(buf), "%d-%d@strongswan.org", (uintptr_t)thread, i);
- id[i] = identification_create_from_string(buf);
- }
-
- pools = linked_list_create();
- pools->insert_last(pools, "test");
-
- /* allocate addresses */
- for (i = 0; i < ALLOCS; i++)
- {
- addr[i] = hydra->attributes->acquire_address(hydra->attributes,
- pools, id[i], NULL);
- if (!addr[i])
- {
- pools->destroy(pools);
- return (void*)FALSE;
- }
- }
-
- /* release addresses */
- for (i = 0; i < ALLOCS; i++)
- {
- hydra->attributes->release_address(hydra->attributes,
- pools, addr[i], id[i]);
- }
-
- pools->destroy(pools);
-
- /* cleanup */
- for (i = 0; i < ALLOCS; i++)
- {
- addr[i]->destroy(addr[i]);
- id[i]->destroy(id[i]);
- }
- return (void*)TRUE;
-}
-
-
-/*******************************************************************************
- * SQL pool performance test
- ******************************************************************************/
-bool test_pool()
-{
- thread_t *threads[THREADS];
- uintptr_t i;
-
- for (i = 0; i < THREADS; i++)
- {
- if (!(threads[i] = thread_create((thread_main_t)testing, (void*)i)))
- {
- return FALSE;
- }
- }
- for (i = 0; i < THREADS; i++)
- {
- bool *res = threads[i]->join(threads[i]);
- if (!res)
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_sqlite.c b/src/libcharon/plugins/unit_tester/tests/test_sqlite.c
deleted file mode 100644
index 99490b566..000000000
--- a/src/libcharon/plugins/unit_tester/tests/test_sqlite.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-#include <collections/enumerator.h>
-
-#include <unistd.h>
-
-
-#define DBFILE "/tmp/strongswan-test.db"
-
-/*******************************************************************************
- * sqlite simple test
- ******************************************************************************/
-bool test_sqlite()
-{
- database_t *db;
- char *txt = "I'm a superduper test";
- chunk_t data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08);
- int row;
- chunk_t qdata;
- char *qtxt;
- bool good = FALSE;
- enumerator_t *enumerator;
-
- db = lib->db->create(lib->db, "sqlite://" DBFILE);
- if (!db)
- {
- return FALSE;
- }
- if (db->execute(db, NULL, "CREATE TABLE test (txt TEXT, data BLOB)") < 0)
- {
- return FALSE;
- }
- if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)",
- DB_TEXT, txt, DB_BLOB, data) < 0)
- {
- return FALSE;
- }
- if (row != 1)
- {
- return FALSE;
- }
- enumerator = db->query(db, "SELECT txt, data FROM test WHERE oid = ?",
- DB_INT, row,
- DB_TEXT, DB_BLOB);
- if (!enumerator)
- {
- return FALSE;
- }
- while (enumerator->enumerate(enumerator, &qtxt, &qdata))
- {
- if (good)
- { /* only one row */
- good = FALSE;
- break;
- }
- if (streq(qtxt, txt) && chunk_equals(data, qdata))
- {
- good = TRUE;
- }
- }
- enumerator->destroy(enumerator);
- if (!good)
- {
- return FALSE;
- }
- if (db->execute(db, NULL, "DELETE FROM test WHERE oid = ?", DB_INT, row) != 1)
- {
- return FALSE;
- }
- if (db->execute(db, NULL, "DROP TABLE test") < 0)
- {
- return FALSE;
- }
- db->destroy(db);
- unlink(DBFILE);
- return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/unit_tester.c b/src/libcharon/plugins/unit_tester/unit_tester.c
deleted file mode 100644
index ea7ffca04..000000000
--- a/src/libcharon/plugins/unit_tester/unit_tester.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2013 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "unit_tester.h"
-
-#include <daemon.h>
-
-typedef struct private_unit_tester_t private_unit_tester_t;
-typedef struct unit_test_t unit_test_t;
-typedef enum test_status_t test_status_t;
-
-/**
- * private data of unit_tester
- */
-struct private_unit_tester_t {
-
- /**
- * public functions
- */
- unit_tester_t public;
-};
-
-struct unit_test_t {
-
- /**
- * name of the test
- */
- char *name;
-
- /**
- * test function
- */
- bool (*test)(void);
-
- /**
- * run the test?
- */
- bool enabled;
-};
-
-#undef DEFINE_TEST
-#define DEFINE_TEST(name, function, enabled) bool function();
-#include <plugins/unit_tester/tests.h>
-#undef DEFINE_TEST
-#define DEFINE_TEST(name, function, enabled) {name, function, enabled},
-static unit_test_t tests[] = {
-#include <plugins/unit_tester/tests.h>
-};
-
-static void run_tests(private_unit_tester_t *this)
-{
- int i, run = 0, failed = 0, success = 0, skipped = 0;
-
- DBG1(DBG_CFG, "running unit tests, %d tests registered",
- sizeof(tests)/sizeof(unit_test_t));
-
- for (i = 0; i < sizeof(tests)/sizeof(unit_test_t); i++)
- {
- if (tests[i].enabled)
- {
- run++;
- if (tests[i].test())
- {
- DBG1(DBG_CFG, "test '%s' successful", tests[i].name);
- success++;
- }
- else
- {
- DBG1(DBG_CFG, "test '%s' failed", tests[i].name);
- failed++;
- }
- }
- else
- {
- DBG1(DBG_CFG, "test '%s' disabled", tests[i].name);
- skipped++;
- }
- }
- DBG1(DBG_CFG, "%d/%d tests successful (%d failed, %d disabled)",
- success, run, failed, skipped);
-}
-
-METHOD(plugin_t, get_name, char*,
- private_unit_tester_t *this)
-{
- return "unit-tester";
-}
-
-/**
- * We currently don't depend explicitly on any plugin features. But in case
- * activated tests depend on such features we at least try to run them in plugin
- * order.
- */
-static bool plugin_cb(private_unit_tester_t *this,
- plugin_feature_t *feature, bool reg, void *cb_data)
-{
- if (reg)
- {
- run_tests(this);
- }
- return TRUE;
-}
-
-METHOD(plugin_t, get_features, int,
- private_unit_tester_t *this, plugin_feature_t *features[])
-{
- static plugin_feature_t f[] = {
- PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
- PLUGIN_PROVIDE(CUSTOM, "unit-tester"),
- };
- *features = f;
- return countof(f);
-}
-
-METHOD(plugin_t, destroy, void,
- private_unit_tester_t *this)
-{
- free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *unit_tester_plugin_create()
-{
- private_unit_tester_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/unity/Makefile.in b/src/libcharon/plugins/unity/Makefile.in
index 1e04ebced..4f0a7e736 100644
--- a/src/libcharon/plugins/unity/Makefile.in
+++ b/src/libcharon/plugins/unity/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ 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@
@@ -365,6 +368,8 @@ 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@
diff --git a/src/libcharon/plugins/unity/unity_handler.c b/src/libcharon/plugins/unity/unity_handler.c
index bcef0dc25..9fc9be61a 100644
--- a/src/libcharon/plugins/unity/unity_handler.c
+++ b/src/libcharon/plugins/unity/unity_handler.c
@@ -50,8 +50,8 @@ struct private_unity_handler_t {
* Traffic selector entry for networks to include under a given IKE_SA
*/
typedef struct {
- /** associated IKE_SA, unique ID */
- u_int32_t sa;
+ /** associated IKE_SA COOKIEs */
+ ike_sa_id_t *id;
/** traffic selector to include/exclude */
traffic_selector_t *ts;
} entry_t;
@@ -61,6 +61,7 @@ typedef struct {
*/
static void entry_destroy(entry_t *this)
{
+ this->id->destroy(this->id);
this->ts->destroy(this->ts);
free(this);
}
@@ -131,9 +132,10 @@ static bool add_include(private_unity_handler_t *this, chunk_t data)
while (list->remove_first(list, (void**)&ts) == SUCCESS)
{
INIT(entry,
- .sa = ike_sa->get_unique_id(ike_sa),
+ .id = ike_sa->get_id(ike_sa),
.ts = ts,
);
+ entry->id = entry->id->clone(entry->id);
this->mutex->lock(this->mutex);
this->include->insert_last(this->include, entry);
@@ -171,7 +173,7 @@ static bool remove_include(private_unity_handler_t *this, chunk_t data)
enumerator = this->include->create_enumerator(this->include);
while (enumerator->enumerate(enumerator, &entry))
{
- if (entry->sa == ike_sa->get_unique_id(ike_sa) &&
+ if (entry->id->equals(entry->id, ike_sa->get_id(ike_sa)) &&
ts->equals(ts, entry->ts))
{
this->include->remove_at(this->include, enumerator);
@@ -209,8 +211,7 @@ static job_requeue_t add_exclude_async(entry_t *entry)
char name[128];
host_t *host;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- entry->sa, FALSE);
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, entry->id);
if (ike_sa)
{
create_shunt_name(ike_sa, entry->ts, name, sizeof(name));
@@ -267,9 +268,10 @@ static bool add_exclude(private_unity_handler_t *this, chunk_t data)
while (list->remove_first(list, (void**)&ts) == SUCCESS)
{
INIT(entry,
- .sa = ike_sa->get_unique_id(ike_sa),
+ .id = ike_sa->get_id(ike_sa),
.ts = ts,
);
+ entry->id = entry->id->clone(entry->id);
/* we can't install the shunt policy yet, as we don't know the virtual IP.
* Defer installation using an async callback. */
@@ -315,7 +317,7 @@ static bool remove_exclude(private_unity_handler_t *this, chunk_t data)
}
METHOD(attribute_handler_t, handle, bool,
- private_unity_handler_t *this, identification_t *id,
+ private_unity_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
switch (type)
@@ -330,7 +332,7 @@ METHOD(attribute_handler_t, handle, bool,
}
METHOD(attribute_handler_t, release, void,
- private_unity_handler_t *this, identification_t *server,
+ private_unity_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
switch (type)
@@ -378,10 +380,9 @@ METHOD(enumerator_t, enumerate_attributes, bool,
}
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
- unity_handler_t *this, identification_t *id, linked_list_t *vips)
+ unity_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips)
{
attribute_enumerator_t *enumerator;
- ike_sa_t *ike_sa;
ike_sa = charon->bus->get_sa(charon->bus);
if (!ike_sa || ike_sa->get_version(ike_sa) != IKEV1 ||
@@ -402,7 +403,7 @@ typedef struct {
/** mutex to unlock */
mutex_t *mutex;
/** IKE_SA ID to filter for */
- u_int32_t id;
+ ike_sa_id_t *id;
} include_filter_t;
/**
@@ -411,7 +412,7 @@ typedef struct {
static bool include_filter(include_filter_t *data,
entry_t **entry, traffic_selector_t **ts)
{
- if ((*entry)->sa == data->id)
+ if (data->id->equals(data->id, (*entry)->id))
{
*ts = (*entry)->ts;
return TRUE;
@@ -429,7 +430,7 @@ static void destroy_filter(include_filter_t *data)
}
METHOD(unity_handler_t, create_include_enumerator, enumerator_t*,
- private_unity_handler_t *this, u_int32_t id)
+ private_unity_handler_t *this, ike_sa_id_t *id)
{
include_filter_t *data;
diff --git a/src/libcharon/plugins/unity/unity_handler.h b/src/libcharon/plugins/unity/unity_handler.h
index 8656fd372..18efe293b 100644
--- a/src/libcharon/plugins/unity/unity_handler.h
+++ b/src/libcharon/plugins/unity/unity_handler.h
@@ -21,6 +21,7 @@
#ifndef UNITY_HANDLER_H_
#define UNITY_HANDLER_H_
+#include <sa/ike_sa_id.h>
#include <attributes/attribute_handler.h>
typedef struct unity_handler_t unity_handler_t;
@@ -38,11 +39,11 @@ struct unity_handler_t {
/**
* Create an enumerator over Split-Include attributes received for an IKE_SA.
*
- * @param id IKE_SA unique ID to get Split-Includes for
+ * @param id IKE_SA ID to get Split-Includes for
* @return enumerator over traffic_selector_t*
*/
enumerator_t* (*create_include_enumerator)(unity_handler_t *this,
- u_int32_t id);
+ ike_sa_id_t *id);
/**
* Destroy a unity_handler_t.
diff --git a/src/libcharon/plugins/unity/unity_narrow.c b/src/libcharon/plugins/unity/unity_narrow.c
index 52a2c7f24..227d24be8 100644
--- a/src/libcharon/plugins/unity/unity_narrow.c
+++ b/src/libcharon/plugins/unity/unity_narrow.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2012 Martin Willi
* Copyright (C) 2012 revosec AG
*
@@ -16,6 +19,8 @@
#include "unity_narrow.h"
#include <daemon.h>
+#include <encoding/payloads/id_payload.h>
+#include <collections/hashtable.h>
typedef struct private_unity_narrow_t private_unity_narrow_t;
@@ -33,6 +38,11 @@ struct private_unity_narrow_t {
* Unity attribute handler
*/
unity_handler_t *handler;
+
+ /**
+ * IKE_SAs for which we received 0.0.0.0/0 as remote traffic selector
+ */
+ hashtable_t *wildcard_ts;
};
/**
@@ -65,7 +75,7 @@ static void narrow_initiator(private_unity_narrow_t *this, ike_sa_t *ike_sa,
enumerator_t *enumerator;
enumerator = this->handler->create_include_enumerator(this->handler,
- ike_sa->get_unique_id(ike_sa));
+ ike_sa->get_id(ike_sa));
while (enumerator->enumerate(enumerator, &current))
{
if (orig == NULL)
@@ -149,7 +159,7 @@ static bool has_split_includes(private_unity_narrow_t *this, ike_sa_t *ike_sa)
bool has;
enumerator = this->handler->create_include_enumerator(this->handler,
- ike_sa->get_unique_id(ike_sa));
+ ike_sa->get_id(ike_sa));
has = enumerator->enumerate(enumerator, &ts);
enumerator->destroy(enumerator);
@@ -191,11 +201,19 @@ METHOD(listener_t, narrow, bool,
{
case NARROW_INITIATOR_PRE_AUTH:
case NARROW_RESPONDER:
- narrow_pre(local, "us");
+ if (this->wildcard_ts->get(this->wildcard_ts, ike_sa))
+ {
+ narrow_pre(local, "us");
+
+ }
break;
case NARROW_INITIATOR_POST_AUTH:
case NARROW_RESPONDER_POST:
- narrow_responder_post(child_sa->get_config(child_sa), local);
+ if (this->wildcard_ts->get(this->wildcard_ts, ike_sa))
+ {
+ narrow_responder_post(child_sa->get_config(child_sa),
+ local);
+ }
break;
default:
break;
@@ -205,9 +223,69 @@ METHOD(listener_t, narrow, bool,
return TRUE;
}
+METHOD(listener_t, message, bool,
+ private_unity_narrow_t *this, ike_sa_t *ike_sa, message_t *message,
+ bool incoming, bool plain)
+{
+ traffic_selector_t *tsr = NULL, *wildcard;
+ enumerator_t *enumerator;
+ id_payload_t *id_payload;
+ payload_t *payload;
+ bool first = TRUE;
+
+ if (!incoming || !plain ||
+ message->get_exchange_type(message) != QUICK_MODE ||
+ !ike_sa || !ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY))
+ {
+ return TRUE;
+ }
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ if (payload->get_type(payload) == PLV1_ID)
+ {
+ if (!first)
+ {
+ id_payload = (id_payload_t*)payload;
+ tsr = id_payload->get_ts(id_payload);
+ break;
+ }
+ first = FALSE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tsr)
+ {
+ return TRUE;
+ }
+ wildcard = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
+ if (tsr->equals(tsr, wildcard))
+ {
+ this->wildcard_ts->put(this->wildcard_ts, ike_sa, ike_sa);
+ }
+ else
+ {
+ this->wildcard_ts->remove(this->wildcard_ts, ike_sa);
+ }
+ wildcard->destroy(wildcard);
+ tsr->destroy(tsr);
+ return TRUE;
+}
+
+METHOD(listener_t, ike_updown, bool,
+ private_unity_narrow_t *this, ike_sa_t *ike_sa, bool up)
+{
+ if (!up)
+ {
+ this->wildcard_ts->remove(this->wildcard_ts, ike_sa);
+ }
+ return TRUE;
+}
+
METHOD(unity_narrow_t, destroy, void,
private_unity_narrow_t *this)
{
+ this->wildcard_ts->destroy(this->wildcard_ts);
free(this);
}
@@ -222,10 +300,14 @@ unity_narrow_t *unity_narrow_create(unity_handler_t *handler)
.public = {
.listener = {
.narrow = _narrow,
+ .message = _message,
+ .ike_updown = _ike_updown,
},
.destroy = _destroy,
},
.handler = handler,
+ .wildcard_ts = hashtable_create(hashtable_hash_ptr,
+ hashtable_equals_ptr, 4),
);
return &this->public;
diff --git a/src/libcharon/plugins/unity/unity_plugin.c b/src/libcharon/plugins/unity/unity_plugin.c
index 9e4571d34..b7a3fee2e 100644
--- a/src/libcharon/plugins/unity/unity_plugin.c
+++ b/src/libcharon/plugins/unity/unity_plugin.c
@@ -19,7 +19,6 @@
#include "unity_provider.h"
#include <daemon.h>
-#include <hydra.h>
typedef struct private_unity_plugin_t private_unity_plugin_t;
@@ -63,19 +62,19 @@ static bool plugin_cb(private_unity_plugin_t *this,
{
if (reg)
{
- hydra->attributes->add_handler(hydra->attributes,
- &this->handler->handler);
- hydra->attributes->add_provider(hydra->attributes,
- &this->provider->provider);
+ charon->attributes->add_handler(charon->attributes,
+ &this->handler->handler);
+ charon->attributes->add_provider(charon->attributes,
+ &this->provider->provider);
charon->bus->add_listener(charon->bus, &this->narrower->listener);
}
else
{
charon->bus->remove_listener(charon->bus, &this->narrower->listener);
- hydra->attributes->remove_handler(hydra->attributes,
- &this->handler->handler);
- hydra->attributes->remove_provider(hydra->attributes,
- &this->provider->provider);
+ charon->attributes->remove_handler(charon->attributes,
+ &this->handler->handler);
+ charon->attributes->remove_provider(charon->attributes,
+ &this->provider->provider);
}
return TRUE;
diff --git a/src/libcharon/plugins/unity/unity_provider.c b/src/libcharon/plugins/unity/unity_provider.c
index 86f81fcfb..1e297a39e 100644
--- a/src/libcharon/plugins/unity/unity_provider.c
+++ b/src/libcharon/plugins/unity/unity_provider.c
@@ -135,19 +135,17 @@ static bool use_ts(traffic_selector_t *ts)
}
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
- private_unity_provider_t *this, linked_list_t *pools, identification_t *id,
+ private_unity_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
linked_list_t *vips)
{
attribute_enumerator_t *attr_enum;
enumerator_t *enumerator;
linked_list_t *list, *current;
traffic_selector_t *ts;
- ike_sa_t *ike_sa;
peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg;
- ike_sa = charon->bus->get_sa(charon->bus);
- if (!ike_sa || ike_sa->get_version(ike_sa) != IKEV1 ||
+ if (ike_sa->get_version(ike_sa) != IKEV1 ||
!ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY) ||
!vips->get_count(vips))
{
diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in
index 834d373f3..619d17a0e 100644
--- a/src/libcharon/plugins/updown/Makefile.in
+++ b/src/libcharon/plugins/updown/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/updown/updown_handler.c b/src/libcharon/plugins/updown/updown_handler.c
index 0894d2d07..72d7f7da3 100644
--- a/src/libcharon/plugins/updown/updown_handler.c
+++ b/src/libcharon/plugins/updown/updown_handler.c
@@ -62,19 +62,13 @@ static void attributes_destroy(attributes_t *this)
}
METHOD(attribute_handler_t, handle, bool,
- private_updown_handler_t *this, identification_t *server,
+ private_updown_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
attributes_t *current, *attr = NULL;
enumerator_t *enumerator;
- ike_sa_t *ike_sa;
host_t *host;
- ike_sa = charon->bus->get_sa(charon->bus);
- if (!ike_sa)
- {
- return FALSE;
- }
switch (type)
{
case INTERNAL_IP4_DNS:
@@ -117,12 +111,11 @@ METHOD(attribute_handler_t, handle, bool,
}
METHOD(attribute_handler_t, release, void,
- private_updown_handler_t *this, identification_t *server,
+ private_updown_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
attributes_t *attr;
enumerator_t *enumerator, *servers;
- ike_sa_t *ike_sa;
host_t *host;
bool found = FALSE;
int family;
@@ -139,43 +132,39 @@ METHOD(attribute_handler_t, release, void,
return;
}
- ike_sa = charon->bus->get_sa(charon->bus);
- if (ike_sa)
+ this->lock->write_lock(this->lock);
+ enumerator = this->attrs->create_enumerator(this->attrs);
+ while (enumerator->enumerate(enumerator, &attr))
{
- this->lock->write_lock(this->lock);
- enumerator = this->attrs->create_enumerator(this->attrs);
- while (enumerator->enumerate(enumerator, &attr))
+ if (attr->id == ike_sa->get_unique_id(ike_sa))
{
- if (attr->id == ike_sa->get_unique_id(ike_sa))
+ servers = attr->dns->create_enumerator(attr->dns);
+ while (servers->enumerate(servers, &host))
{
- servers = attr->dns->create_enumerator(attr->dns);
- while (servers->enumerate(servers, &host))
+ if (host->get_family(host) == family &&
+ chunk_equals(data, host->get_address(host)))
{
- if (host->get_family(host) == family &&
- chunk_equals(data, host->get_address(host)))
- {
- attr->dns->remove_at(attr->dns, servers);
- host->destroy(host);
- found = TRUE;
- break;
- }
- }
- servers->destroy(servers);
- if (attr->dns->get_count(attr->dns) == 0)
- {
- this->attrs->remove_at(this->attrs, enumerator);
- attributes_destroy(attr);
+ attr->dns->remove_at(attr->dns, servers);
+ host->destroy(host);
+ found = TRUE;
break;
}
}
- if (found)
+ servers->destroy(servers);
+ if (attr->dns->get_count(attr->dns) == 0)
{
+ this->attrs->remove_at(this->attrs, enumerator);
+ attributes_destroy(attr);
break;
}
}
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
+ if (found)
+ {
+ break;
+ }
}
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
}
METHOD(updown_handler_t, create_dns_enumerator, enumerator_t*,
diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c
index 1d15cc55e..be65d599f 100644
--- a/src/libcharon/plugins/updown/updown_listener.c
+++ b/src/libcharon/plugins/updown/updown_listener.c
@@ -243,6 +243,7 @@ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa,
me = ike_sa->get_my_host(ike_sa);
other = ike_sa->get_other_host(ike_sa);
+ push_env(envp, countof(envp), "PATH=%s", getenv("PATH"));
push_env(envp, countof(envp), "PLUTO_VERSION=1.1");
is_host = my_ts->is_host(my_ts, me);
if (is_host)
diff --git a/src/libcharon/plugins/updown/updown_plugin.c b/src/libcharon/plugins/updown/updown_plugin.c
index d30267dee..60ecfcce6 100644
--- a/src/libcharon/plugins/updown/updown_plugin.c
+++ b/src/libcharon/plugins/updown/updown_plugin.c
@@ -18,7 +18,6 @@
#include "updown_handler.h"
#include <daemon.h>
-#include <hydra.h>
typedef struct private_updown_plugin_t private_updown_plugin_t;
@@ -61,8 +60,8 @@ static bool plugin_cb(private_updown_plugin_t *this,
"%s.plugins.updown.dns_handler", FALSE, lib->ns))
{
this->handler = updown_handler_create();
- hydra->attributes->add_handler(hydra->attributes,
- &this->handler->handler);
+ charon->attributes->add_handler(charon->attributes,
+ &this->handler->handler);
}
this->listener = updown_listener_create(this->handler);
charon->bus->add_listener(charon->bus, &this->listener->listener);
@@ -74,8 +73,8 @@ static bool plugin_cb(private_updown_plugin_t *this,
if (this->handler)
{
this->handler->destroy(this->handler);
- hydra->attributes->remove_handler(hydra->attributes,
- &this->handler->handler);
+ charon->attributes->remove_handler(charon->attributes,
+ &this->handler->handler);
}
}
return TRUE;
diff --git a/src/libcharon/plugins/vici/Makefile.am b/src/libcharon/plugins/vici/Makefile.am
index da71de394..b25396085 100644
--- a/src/libcharon/plugins/vici/Makefile.am
+++ b/src/libcharon/plugins/vici/Makefile.am
@@ -74,3 +74,7 @@ SUBDIRS =
if USE_RUBY_GEMS
SUBDIRS += ruby
endif
+
+if USE_PYTHON_EGGS
+SUBDIRS += python
+endif
diff --git a/src/libcharon/plugins/vici/Makefile.in b/src/libcharon/plugins/vici/Makefile.in
index 34546b905..b63226daa 100644
--- a/src/libcharon/plugins/vici/Makefile.in
+++ b/src/libcharon/plugins/vici/Makefile.in
@@ -81,6 +81,7 @@ host_triplet = @host@
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
subdir = src/libcharon/plugins/vici
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
@@ -269,7 +270,7 @@ am__tty_colors = { \
std=''; \
fi; \
}
-DIST_SUBDIRS = ruby
+DIST_SUBDIRS = ruby python
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -321,6 +322,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -381,10 +383,12 @@ 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@
@@ -458,6 +462,8 @@ 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@
@@ -571,7 +577,7 @@ vici_tests_LDADD = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
$(top_builddir)/src/libstrongswan/tests/libtest.la
-SUBDIRS = $(am__append_1)
+SUBDIRS = $(am__append_1) $(am__append_2)
all: all-recursive
.SUFFIXES:
diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md
index 272491052..0ce4271b0 100644
--- a/src/libcharon/plugins/vici/README.md
+++ b/src/libcharon/plugins/vici/README.md
@@ -145,25 +145,25 @@ the following C array:
char msg[] = {
/* key1 = value1 */
- 2, 4,'k','e','y','1', 0,6,'v','a','l','u','e','1',
+ 3, 4,'k','e','y','1', 0,6,'v','a','l','u','e','1',
/* section1 */
- 0, 8,'s','e','c','t','i','o','n','1',
+ 1, 8,'s','e','c','t','i','o','n','1',
/* sub-section */
- 0, 11,'s','u','b','-','s','e','c','t','i','o','n',
+ 1, 11,'s','u','b','-','s','e','c','t','i','o','n',
/* key2 = value2 */
- 2, 4,'k','e','y','2', 0,6,'v','a','l','u','e','2',
+ 3, 4,'k','e','y','2', 0,6,'v','a','l','u','e','2',
/* sub-section end */
- 1,
+ 2,
/* list1 */
- 3, 5, 'l','i','s','t','1',
+ 4, 5, 'l','i','s','t','1',
/* item1 */
- 4, 0,5,'i','t','e','m','1',
+ 5, 0,5,'i','t','e','m','1',
/* item2 */
- 4, 0,5,'i','t','e','m','2',
+ 5, 0,5,'i','t','e','m','2',
/* list1 end */
- 5,
+ 6,
/* section1 end */
- 1,
+ 2,
};
## Client-initiated commands ##
@@ -559,6 +559,7 @@ command.
]
child-sas = {
<child-sa-name>* = {
+ uniqueid = <unique CHILD_SA identifier>
reqid = <reqid of CHILD_SA>
state = <state string of CHILD_SA>
mode = <IPsec mode, tunnel|transport|beet>
@@ -820,9 +821,9 @@ during encoding.
## Connecting to the daemon ##
-To create a connection to the daemon, a socket must be passed to the
-_Connection_ constructor. There is no default, but on Unix systems usually
-a Unix socket over _/var/run/charon.vici_ is used:
+To create a connection to the daemon, a socket can be passed to the
+_Connection_ constructor. If none is passed, a default Unix socket at
+_/var/run/charon.vici_ is used:
require "vici"
require "socket"
@@ -854,3 +855,73 @@ _list-conns_ command and implicitly the _list-conn_ event:
For more details about the ruby gem refer to the comments in the gem source
code or the generated documentation.
+
+# vici Python egg #
+
+The _vici Python egg_ is a pure Python implementation of the VICI protocol to
+implement client applications. It is provided in the _python_ subdirectory, and
+gets built and installed if strongSwan has been _./configure_'d with
+_--enable-vici_ and _--enable-python-eggs_.
+
+The _vici_ module provides a _Session()_ constructor for a high level interface,
+the underlying classes are usually not required to build Python applications
+using VICI. The _Session_ class provides methods for the supported VICI
+commands.
+
+To represent the VICI message data tree, the library converts the binary
+encoding to Python data types. The _Session_ class takes and returns Python
+objects for the exchanged message data:
+ * Sections get encoded as OrderedDict, containing other sections, or
+ * Key/Values, where the values are strings as dictionary values
+ * Lists get encoded as Python Lists with string values
+Values that do not conform to Python dict or list get converted to strings using
+str().
+
+## Connecting to the daemon ##
+
+To create a connection to the daemon, a socket can be passed to the _Session_
+constructor. If none is passed, a default Unix socket at _/var/run/charon.vici_
+is used:
+
+ import vici
+ import socket
+
+ s = socket.socket(socket.AF_UNIX)
+ s.connect("/var/run/charon.vici")
+ v = vici.Session(s)
+
+## A simple client request ##
+
+An example to print the daemon version information is as simple as:
+
+ ver = v.version()
+
+ print "{daemon} {version} ({sysname}, {release}, {machine})".format(**ver)
+
+## A request with response iteration ##
+
+The _Session_ class returns an iterable Python generator for streamed events to
+continuously stream objects to the caller. The following example lists all
+loaded connections using the _list-conns_ command and implicitly the _list-conn_
+event:
+
+ for conn in v.list_conns():
+ for key in conn:
+ print key
+
+Please note that if the returned generator is not iterated completely, it must
+be closed using _close()_. This is implicitly done when breaking from a loop,
+but an explicit call may be required when directly iterating the generator with
+_next()_.
+
+## Sorting in dictionaries ##
+
+In VICI, in some message trees the order of objects in dictionary matters. In
+contrast to ruby Hashes, Python dictionaries do not preserve order of added
+objects. It is therefore recommended to use OrderedDicts instead of the default
+dictionaries. Objects returned by the library use OrderedDicts.
+
+## API documentation ##
+
+For more details about the Python egg refer to the comments in the Python source
+code.
diff --git a/src/libcharon/plugins/vici/libvici.c b/src/libcharon/plugins/vici/libvici.c
index c0205ccb6..7c98c8b69 100644
--- a/src/libcharon/plugins/vici/libvici.c
+++ b/src/libcharon/plugins/vici/libvici.c
@@ -427,14 +427,8 @@ vici_res_t* vici_submit(vici_req_t *req, vici_conn_t *conn)
void vici_free_req(vici_req_t *req)
{
- vici_message_t *message;
-
free(req->name);
- message = req->b->finalize(req->b);
- if (message)
- {
- message->destroy(message);
- }
+ req->b->destroy(req->b);
free(req);
}
diff --git a/src/libcharon/plugins/vici/python/LICENSE b/src/libcharon/plugins/vici/python/LICENSE
new file mode 100644
index 000000000..111523ca8
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 Björn Schuberg
+
+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.
diff --git a/src/libcharon/plugins/vici/python/MANIFEST.in b/src/libcharon/plugins/vici/python/MANIFEST.in
new file mode 100644
index 000000000..1aba38f67
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/MANIFEST.in
@@ -0,0 +1 @@
+include LICENSE
diff --git a/src/libcharon/plugins/vici/python/Makefile.am b/src/libcharon/plugins/vici/python/Makefile.am
new file mode 100644
index 000000000..f51737870
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/Makefile.am
@@ -0,0 +1,33 @@
+EXTRA_DIST = LICENSE MANIFEST.in \
+ setup.py.in \
+ vici/test/__init__.py \
+ vici/test/test_protocol.py \
+ vici/__init__.py \
+ vici/compat.py \
+ vici/exception.py \
+ vici/protocol.py \
+ vici/session.py
+
+setup.py: $(srcdir)/setup.py.in
+ $(AM_V_GEN) sed \
+ -e "s:@EGG_VERSION@:$(PACKAGE_VERSION):" \
+ $(srcdir)/setup.py.in > $@
+
+all-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+
+dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg: $(EXTRA_DIST) setup.py
+ (cd $(srcdir); $(PYTHON) setup.py bdist_egg \
+ -b $(shell readlink -f $(builddir))/build \
+ -d $(shell readlink -f $(builddir))/dist)
+
+clean-local: setup.py
+ $(PYTHON) setup.py clean -a
+ rm -rf vici.egg-info dist setup.py
+
+install-exec-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+ $(EASY_INSTALL) $(PYTHONEGGINSTALLDIR) \
+ dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+
+if USE_PY_TEST
+ TESTS = $(PY_TEST)
+endif
diff --git a/src/libcharon/plugins/vici/python/Makefile.in b/src/libcharon/plugins/vici/python/Makefile.in
new file mode 100644
index 000000000..3a5e5ea72
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/Makefile.in
@@ -0,0 +1,686 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/vici/python
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/split-package-version.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+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_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+EXTRA_DIST = LICENSE MANIFEST.in \
+ setup.py.in \
+ vici/test/__init__.py \
+ vici/test/test_protocol.py \
+ vici/__init__.py \
+ vici/compat.py \
+ vici/exception.py \
+ vici/protocol.py \
+ vici/session.py
+
+@USE_PY_TEST_TRUE@TESTS = $(PY_TEST)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/vici/python/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/vici/python/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+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-TESTS
+check: check-am
+all-am: Makefile all-local
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-exec-local
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am all-local check check-TESTS check-am clean \
+ clean-generic clean-libtool clean-local cscopelist-am ctags-am \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-exec-local install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am
+
+
+setup.py: $(srcdir)/setup.py.in
+ $(AM_V_GEN) sed \
+ -e "s:@EGG_VERSION@:$(PACKAGE_VERSION):" \
+ $(srcdir)/setup.py.in > $@
+
+all-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+
+dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg: $(EXTRA_DIST) setup.py
+ (cd $(srcdir); $(PYTHON) setup.py bdist_egg \
+ -b $(shell readlink -f $(builddir))/build \
+ -d $(shell readlink -f $(builddir))/dist)
+
+clean-local: setup.py
+ $(PYTHON) setup.py clean -a
+ rm -rf vici.egg-info dist setup.py
+
+install-exec-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+ $(EASY_INSTALL) $(PYTHONEGGINSTALLDIR) \
+ dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/vici/python/setup.py.in b/src/libcharon/plugins/vici/python/setup.py.in
new file mode 100644
index 000000000..0e4ad8236
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/setup.py.in
@@ -0,0 +1,34 @@
+from setuptools import setup
+
+
+long_description = (
+ "The strongSwan VICI protocol allows external application to monitor, "
+ "configure and control the IKE daemon charon. This python package provides "
+ "a native client side implementation of the VICI protocol, well suited to "
+ "script automated tasks in a reliable way."
+)
+
+setup(
+ name="vici",
+ version="@EGG_VERSION@",
+ description="Native python interface for strongSwan VICI",
+ author="Bjorn Schuberg",
+ url="https://wiki.strongswan.org/projects/strongswan/wiki/Vici",
+ license="MIT",
+ packages=["vici"],
+ long_description=long_description,
+ include_package_data=True,
+ classifiers=(
+ "Development Status :: 3 - Alpha",
+ "Intended Audience :: Developers",
+ "Intended Audience :: System Administrators",
+ "License :: OSI Approved :: MIT License",
+ "Natural Language :: English",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3.2",
+ "Programming Language :: Python :: 3.3",
+ "Programming Language :: Python :: 3.4",
+ "Topic :: Security",
+ "Topic :: Software Development :: Libraries",
+ )
+)
diff --git a/src/libcharon/plugins/vici/python/vici/__init__.py b/src/libcharon/plugins/vici/python/vici/__init__.py
new file mode 100644
index 000000000..d314325b6
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/__init__.py
@@ -0,0 +1 @@
+from .session import Session
diff --git a/src/libcharon/plugins/vici/python/vici/compat.py b/src/libcharon/plugins/vici/python/vici/compat.py
new file mode 100644
index 000000000..b5f46992e
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/compat.py
@@ -0,0 +1,14 @@
+# Help functions for compatibility between python version 2 and 3
+
+
+# From http://legacy.python.org/dev/peps/pep-0469
+try:
+ dict.iteritems
+except AttributeError:
+ # python 3
+ def iteritems(d):
+ return iter(d.items())
+else:
+ # python 2
+ def iteritems(d):
+ return d.iteritems()
diff --git a/src/libcharon/plugins/vici/python/vici/exception.py b/src/libcharon/plugins/vici/python/vici/exception.py
new file mode 100644
index 000000000..36384e556
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/exception.py
@@ -0,0 +1,10 @@
+"""Exception types that may be thrown by this library."""
+
+class DeserializationException(Exception):
+ """Encountered an unexpected byte sequence or missing element type."""
+
+class SessionException(Exception):
+ """Session request exception."""
+
+class CommandException(Exception):
+ """Command result exception."""
diff --git a/src/libcharon/plugins/vici/python/vici/protocol.py b/src/libcharon/plugins/vici/python/vici/protocol.py
new file mode 100644
index 000000000..855a7b2e2
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/protocol.py
@@ -0,0 +1,196 @@
+import io
+import socket
+import struct
+
+from collections import namedtuple
+from collections import OrderedDict
+
+from .compat import iteritems
+from .exception import DeserializationException
+
+
+class Transport(object):
+ HEADER_LENGTH = 4
+ MAX_SEGMENT = 512 * 1024
+
+ def __init__(self, sock):
+ self.socket = sock
+
+ def send(self, packet):
+ self.socket.sendall(struct.pack("!I", len(packet)) + packet)
+
+ def receive(self):
+ raw_length = self.socket.recv(self.HEADER_LENGTH)
+ length, = struct.unpack("!I", raw_length)
+ payload = self.socket.recv(length)
+ return payload
+
+ def close(self):
+ self.socket.shutdown(socket.SHUT_RDWR)
+ self.socket.close()
+
+
+class Packet(object):
+ CMD_REQUEST = 0 # Named request message
+ CMD_RESPONSE = 1 # Unnamed response message for a request
+ CMD_UNKNOWN = 2 # Unnamed response if requested command is unknown
+ EVENT_REGISTER = 3 # Named event registration request
+ EVENT_UNREGISTER = 4 # Named event de-registration request
+ EVENT_CONFIRM = 5 # Unnamed confirmation for event (de-)registration
+ EVENT_UNKNOWN = 6 # Unnamed response if event (de-)registration failed
+ EVENT = 7 # Named event message
+
+ ParsedPacket = namedtuple(
+ "ParsedPacket",
+ ["response_type", "payload"]
+ )
+
+ ParsedEventPacket = namedtuple(
+ "ParsedEventPacket",
+ ["response_type", "event_type", "payload"]
+ )
+
+ @classmethod
+ def _named_request(cls, request_type, request, message=None):
+ request = request.encode()
+ payload = struct.pack("!BB", request_type, len(request)) + request
+ if message is not None:
+ return payload + message
+ else:
+ return payload
+
+ @classmethod
+ def request(cls, command, message=None):
+ return cls._named_request(cls.CMD_REQUEST, command, message)
+
+ @classmethod
+ def register_event(cls, event_type):
+ return cls._named_request(cls.EVENT_REGISTER, event_type)
+
+ @classmethod
+ def unregister_event(cls, event_type):
+ return cls._named_request(cls.EVENT_UNREGISTER, event_type)
+
+ @classmethod
+ def parse(cls, packet):
+ stream = FiniteStream(packet)
+ response_type, = struct.unpack("!B", stream.read(1))
+
+ if response_type == cls.EVENT:
+ length, = struct.unpack("!B", stream.read(1))
+ event_type = stream.read(length)
+ return cls.ParsedEventPacket(response_type, event_type, stream)
+ else:
+ return cls.ParsedPacket(response_type, stream)
+
+
+class Message(object):
+ SECTION_START = 1 # Begin a new section having a name
+ SECTION_END = 2 # End a previously started section
+ KEY_VALUE = 3 # Define a value for a named key in the section
+ LIST_START = 4 # Begin a named list for list items
+ LIST_ITEM = 5 # Define an unnamed item value in the current list
+ LIST_END = 6 # End a previously started list
+
+ @classmethod
+ def serialize(cls, message):
+ def encode_named_type(marker, name):
+ name = name.encode()
+ return struct.pack("!BB", marker, len(name)) + name
+
+ def encode_blob(value):
+ if not isinstance(value, bytes):
+ value = str(value).encode()
+ return struct.pack("!H", len(value)) + value
+
+ def serialize_list(lst):
+ segment = bytes()
+ for item in lst:
+ segment += struct.pack("!B", cls.LIST_ITEM) + encode_blob(item)
+ return segment
+
+ def serialize_dict(d):
+ segment = bytes()
+ for key, value in iteritems(d):
+ if isinstance(value, dict):
+ segment += (
+ encode_named_type(cls.SECTION_START, key)
+ + serialize_dict(value)
+ + struct.pack("!B", cls.SECTION_END)
+ )
+ elif isinstance(value, list):
+ segment += (
+ encode_named_type(cls.LIST_START, key)
+ + serialize_list(value)
+ + struct.pack("!B", cls.LIST_END)
+ )
+ else:
+ segment += (
+ encode_named_type(cls.KEY_VALUE, key)
+ + encode_blob(value)
+ )
+ return segment
+
+ return serialize_dict(message)
+
+ @classmethod
+ def deserialize(cls, stream):
+ def decode_named_type(stream):
+ length, = struct.unpack("!B", stream.read(1))
+ return stream.read(length).decode()
+
+ def decode_blob(stream):
+ length, = struct.unpack("!H", stream.read(2))
+ return stream.read(length)
+
+ def decode_list_item(stream):
+ marker, = struct.unpack("!B", stream.read(1))
+ while marker == cls.LIST_ITEM:
+ yield decode_blob(stream)
+ marker, = struct.unpack("!B", stream.read(1))
+
+ if marker != cls.LIST_END:
+ raise DeserializationException(
+ "Expected end of list at {pos}".format(pos=stream.tell())
+ )
+
+ section = OrderedDict()
+ section_stack = []
+ while stream.has_more():
+ element_type, = struct.unpack("!B", stream.read(1))
+ if element_type == cls.SECTION_START:
+ section_name = decode_named_type(stream)
+ new_section = OrderedDict()
+ section[section_name] = new_section
+ section_stack.append(section)
+ section = new_section
+
+ elif element_type == cls.LIST_START:
+ list_name = decode_named_type(stream)
+ section[list_name] = [item for item in decode_list_item(stream)]
+
+ elif element_type == cls.KEY_VALUE:
+ key = decode_named_type(stream)
+ section[key] = decode_blob(stream)
+
+ elif element_type == cls.SECTION_END:
+ if len(section_stack):
+ section = section_stack.pop()
+ else:
+ raise DeserializationException(
+ "Unexpected end of section at {pos}".format(
+ pos=stream.tell()
+ )
+ )
+
+ if len(section_stack):
+ raise DeserializationException("Expected end of section")
+ return section
+
+
+class FiniteStream(io.BytesIO):
+ def __len__(self):
+ return len(self.getvalue())
+
+ def has_more(self):
+ return self.tell() < len(self)
diff --git a/src/libcharon/plugins/vici/python/vici/session.py b/src/libcharon/plugins/vici/python/vici/session.py
new file mode 100644
index 000000000..dee58699d
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/session.py
@@ -0,0 +1,327 @@
+import collections
+import socket
+
+from .exception import SessionException, CommandException
+from .protocol import Transport, Packet, Message
+
+
+class Session(object):
+ def __init__(self, sock=None):
+ if sock is None:
+ sock = socket.socket(socket.AF_UNIX)
+ sock.connect("/var/run/charon.vici")
+ self.handler = SessionHandler(Transport(sock))
+
+ def version(self):
+ """Retrieve daemon and system specific version information.
+
+ :return: daemon and system specific version information
+ :rtype: dict
+ """
+ return self.handler.request("version")
+
+ def stats(self):
+ """Retrieve IKE daemon statistics and load information.
+
+ :return: IKE daemon statistics and load information
+ :rtype: dict
+ """
+ return self.handler.request("stats")
+
+ def reload_settings(self):
+ """Reload strongswan.conf settings and any plugins supporting reload.
+ """
+ self.handler.request("reload-settings")
+
+ def initiate(self, sa):
+ """Initiate an SA.
+
+ :param sa: the SA to initiate
+ :type sa: dict
+ :return: generator for logs emitted as dict
+ :rtype: generator
+ """
+ return self.handler.streamed_request("initiate", "control-log", sa)
+
+ def terminate(self, sa):
+ """Terminate an SA.
+
+ :param sa: the SA to terminate
+ :type sa: dict
+ :return: generator for logs emitted as dict
+ :rtype: generator
+ """
+ return self.handler.streamed_request("terminate", "control-log", sa)
+
+ def install(self, policy):
+ """Install a trap, drop or bypass policy defined by a CHILD_SA config.
+
+ :param policy: policy to install
+ :type policy: dict
+ """
+ self.handler.request("install", policy)
+
+ def uninstall(self, policy):
+ """Uninstall a trap, drop or bypass policy defined by a CHILD_SA config.
+
+ :param policy: policy to uninstall
+ :type policy: dict
+ """
+ self.handler.request("uninstall", policy)
+
+ def list_sas(self, filters=None):
+ """Retrieve active IKE_SAs and associated CHILD_SAs.
+
+ :param filters: retrieve only matching IKE_SAs (optional)
+ :type filters: dict
+ :return: generator for active IKE_SAs and associated CHILD_SAs as dict
+ :rtype: generator
+ """
+ return self.handler.streamed_request("list-sas", "list-sa", filters)
+
+ def list_policies(self, filters=None):
+ """Retrieve installed trap, drop and bypass policies.
+
+ :param filters: retrieve only matching policies (optional)
+ :type filters: dict
+ :return: generator for installed trap, drop and bypass policies as dict
+ :rtype: generator
+ """
+ return self.handler.streamed_request("list-policies", "list-policy",
+ filters)
+
+ def list_conns(self, filters=None):
+ """Retrieve loaded connections.
+
+ :param filters: retrieve only matching configuration names (optional)
+ :type filters: dict
+ :return: generator for loaded connections as dict
+ :rtype: generator
+ """
+ return self.handler.streamed_request("list-conns", "list-conn",
+ filters)
+
+ def get_conns(self):
+ """Retrieve connection names loaded exclusively over vici.
+
+ :return: connection names
+ :rtype: dict
+ """
+ return self.handler.request("get-conns")
+
+ def list_certs(self, filters=None):
+ """Retrieve loaded certificates.
+
+ :param filters: retrieve only matching certificates (optional)
+ :type filters: dict
+ :return: generator for loaded certificates as dict
+ :rtype: generator
+ """
+ return self.handler.streamed_request("list-certs", "list-cert", filters)
+
+ def load_conn(self, connection):
+ """Load a connection definition into the daemon.
+
+ :param connection: connection definition
+ :type connection: dict
+ """
+ self.handler.request("load-conn", connection)
+
+ def unload_conn(self, name):
+ """Unload a connection definition.
+
+ :param name: connection definition name
+ :type name: dict
+ """
+ self.handler.request("unload-conn", name)
+
+ def load_cert(self, certificate):
+ """Load a certificate into the daemon.
+
+ :param certificate: PEM or DER encoded certificate
+ :type certificate: dict
+ """
+ self.handler.request("load-cert", certificate)
+
+ def load_key(self, private_key):
+ """Load a private key into the daemon.
+
+ :param private_key: PEM or DER encoded key
+ """
+ self.handler.request("load-key", private_key)
+
+ def load_shared(self, secret):
+ """Load a shared IKE PSK, EAP or XAuth secret into the daemon.
+
+ :param secret: shared IKE PSK, EAP or XAuth secret
+ :type secret: dict
+ """
+ self.handler.request("load-shared", secret)
+
+ def clear_creds(self):
+ """Clear credentials loaded over vici.
+
+ Clear all loaded certificate, private key and shared key credentials.
+ This affects only credentials loaded over vici, but additionally
+ flushes the credential cache.
+ """
+ self.handler.request("clear-creds")
+
+ def load_pool(self, pool):
+ """Load a virtual IP pool.
+
+ Load an in-memory virtual IP and configuration attribute pool.
+ Existing pools with the same name get updated, if possible.
+
+ :param pool: virtual IP and configuration attribute pool
+ :type pool: dict
+ """
+ return self.handler.request("load-pool", pool)
+
+ def unload_pool(self, pool_name):
+ """Unload a virtual IP pool.
+
+ Unload a previously loaded virtual IP and configuration attribute pool.
+ Unloading fails for pools with leases currently online.
+
+ :param pool_name: pool by name
+ :type pool_name: dict
+ """
+ self.handler.request("unload-pool", pool_name)
+
+ def get_pools(self):
+ """Retrieve loaded pools.
+
+ :return: loaded pools
+ :rtype: dict
+ """
+ return self.handler.request("get-pools")
+
+
+class SessionHandler(object):
+ """Handles client command execution requests over vici."""
+
+ def __init__(self, transport):
+ self.transport = transport
+
+ def _communicate(self, packet):
+ """Send packet over transport and parse response.
+
+ :param packet: packet to send
+ :type packet: :py:class:`vici.protocol.Packet`
+ :return: parsed packet in a tuple with message type and payload
+ :rtype: :py:class:`collections.namedtuple`
+ """
+ self.transport.send(packet)
+ return Packet.parse(self.transport.receive())
+
+ def request(self, command, message=None):
+ """Send request with an optional message.
+
+ :param command: command to send
+ :type command: str
+ :param message: message (optional)
+ :type message: str
+ :return: command result
+ :rtype: dict
+ """
+ if message is not None:
+ message = Message.serialize(message)
+ packet = Packet.request(command, message)
+ response = self._communicate(packet)
+
+ if response.response_type != Packet.CMD_RESPONSE:
+ raise SessionException(
+ "Unexpected response type {type}, "
+ "expected '{response}' (CMD_RESPONSE)".format(
+ type=response.response_type,
+ response=Packet.CMD_RESPONSE
+ )
+ )
+
+ command_response = Message.deserialize(response.payload)
+ if "success" in command_response:
+ if command_response["success"] != b"yes":
+ raise CommandException(
+ "Command failed: {errmsg}".format(
+ errmsg=command_response["errmsg"]
+ )
+ )
+
+ return command_response
+
+ def streamed_request(self, command, event_stream_type, message=None):
+ """Send command request and collect and return all emitted events.
+
+ :param command: command to send
+ :type command: str
+ :param event_stream_type: event type emitted on command execution
+ :type event_stream_type: str
+ :param message: message (optional)
+ :type message: str
+ :return: generator for streamed event responses as dict
+ :rtype: generator
+ """
+ if message is not None:
+ message = Message.serialize(message)
+
+ # subscribe to event stream
+ packet = Packet.register_event(event_stream_type)
+ response = self._communicate(packet)
+
+ if response.response_type != Packet.EVENT_CONFIRM:
+ raise SessionException(
+ "Unexpected response type {type}, "
+ "expected '{confirm}' (EVENT_CONFIRM)".format(
+ type=response.response_type,
+ confirm=Packet.EVENT_CONFIRM,
+ )
+ )
+
+ # issue command, and read any event messages
+ packet = Packet.request(command, message)
+ self.transport.send(packet)
+ exited = False
+ while True:
+ response = Packet.parse(self.transport.receive())
+ if response.response_type == Packet.EVENT:
+ if not exited:
+ try:
+ yield Message.deserialize(response.payload)
+ except GeneratorExit:
+ exited = True
+ pass
+ else:
+ break
+
+ if response.response_type == Packet.CMD_RESPONSE:
+ command_response = Message.deserialize(response.payload)
+ else:
+ raise SessionException(
+ "Unexpected response type {type}, "
+ "expected '{response}' (CMD_RESPONSE)".format(
+ type=response.response_type,
+ response=Packet.CMD_RESPONSE
+ )
+ )
+
+ # unsubscribe from event stream
+ packet = Packet.unregister_event(event_stream_type)
+ response = self._communicate(packet)
+ if response.response_type != Packet.EVENT_CONFIRM:
+ raise SessionException(
+ "Unexpected response type {type}, "
+ "expected '{confirm}' (EVENT_CONFIRM)".format(
+ type=response.response_type,
+ confirm=Packet.EVENT_CONFIRM,
+ )
+ )
+
+ # evaluate command result, if any
+ if "success" in command_response:
+ if command_response["success"] != b"yes":
+ raise CommandException(
+ "Command failed: {errmsg}".format(
+ errmsg=command_response["errmsg"]
+ )
+ )
diff --git a/src/libcharon/plugins/vici/python/vici/test/__init__.py b/src/libcharon/plugins/vici/python/vici/test/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/test/__init__.py
diff --git a/src/libcharon/plugins/vici/python/vici/test/test_protocol.py b/src/libcharon/plugins/vici/python/vici/test/test_protocol.py
new file mode 100644
index 000000000..a1f202d79
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/test/test_protocol.py
@@ -0,0 +1,144 @@
+import pytest
+
+from ..protocol import Packet, Message, FiniteStream
+from ..exception import DeserializationException
+
+
+class TestPacket(object):
+ # test data definitions for outgoing packet types
+ cmd_request = b"\x00\x0c" b"command_type"
+ cmd_request_msg = b"\x00\x07" b"command" b"payload"
+ event_register = b"\x03\x0a" b"event_type"
+ event_unregister = b"\x04\x0a" b"event_type"
+
+ # test data definitions for incoming packet types
+ cmd_response = b"\x01" b"reply"
+ cmd_unknown = b"\x02"
+ event_confirm = b"\x05"
+ event_unknown = b"\x06"
+ event = b"\x07\x03" b"log" b"message"
+
+ def test_request(self):
+ assert Packet.request("command_type") == self.cmd_request
+ assert Packet.request("command", b"payload") == self.cmd_request_msg
+
+ def test_register_event(self):
+ assert Packet.register_event("event_type") == self.event_register
+
+ def test_unregister_event(self):
+ assert Packet.unregister_event("event_type") == self.event_unregister
+
+ def test_parse(self):
+ parsed_cmd_response = Packet.parse(self.cmd_response)
+ assert parsed_cmd_response.response_type == Packet.CMD_RESPONSE
+ assert parsed_cmd_response.payload.getvalue() == self.cmd_response
+
+ parsed_cmd_unknown = Packet.parse(self.cmd_unknown)
+ assert parsed_cmd_unknown.response_type == Packet.CMD_UNKNOWN
+ assert parsed_cmd_unknown.payload.getvalue() == self.cmd_unknown
+
+ parsed_event_confirm = Packet.parse(self.event_confirm)
+ assert parsed_event_confirm.response_type == Packet.EVENT_CONFIRM
+ assert parsed_event_confirm.payload.getvalue() == self.event_confirm
+
+ parsed_event_unknown = Packet.parse(self.event_unknown)
+ assert parsed_event_unknown.response_type == Packet.EVENT_UNKNOWN
+ assert parsed_event_unknown.payload.getvalue() == self.event_unknown
+
+ parsed_event = Packet.parse(self.event)
+ assert parsed_event.response_type == Packet.EVENT
+ assert parsed_event.payload.getvalue() == self.event
+
+
+class TestMessage(object):
+ """Message (de)serialization test."""
+
+ # data definitions for test of de(serialization)
+ # serialized messages holding a section
+ ser_sec_unclosed = b"\x01\x08unclosed"
+ ser_sec_single = b"\x01\x07section\x02"
+ ser_sec_nested = b"\x01\x05outer\x01\x0asubsection\x02\x02"
+
+ # serialized messages holding a list
+ ser_list_invalid = b"\x04\x07invalid\x05\x00\x02e1\x02\x03sec\x06"
+ ser_list_0_item = b"\x04\x05empty\x06"
+ ser_list_1_item = b"\x04\x01l\x05\x00\x02e1\x06"
+ ser_list_2_item = b"\x04\x01l\x05\x00\x02e1\x05\x00\x02e2\x06"
+
+ # serialized messages with key value pairs
+ ser_kv_pair = b"\x03\x03key\x00\x05value"
+ ser_kv_zero = b"\x03\x0azerolength\x00\x00"
+
+ # deserialized messages holding a section
+ des_sec_single = { "section": {} }
+ des_sec_nested = { "outer": { "subsection": {} } }
+
+ # deserialized messages holding a list
+ des_list_0_item = { "empty": [] }
+ des_list_1_item = { "l": [ b"e1" ] }
+ des_list_2_item = { "l": [ b"e1", b"e2" ] }
+
+ # deserialized messages with key value pairs
+ des_kv_pair = { "key": b"value" }
+ des_kv_zero = { "zerolength": b"" }
+
+ def test_section_serialization(self):
+ assert Message.serialize(self.des_sec_single) == self.ser_sec_single
+ assert Message.serialize(self.des_sec_nested) == self.ser_sec_nested
+
+ def test_list_serialization(self):
+ assert Message.serialize(self.des_list_0_item) == self.ser_list_0_item
+ assert Message.serialize(self.des_list_1_item) == self.ser_list_1_item
+ assert Message.serialize(self.des_list_2_item) == self.ser_list_2_item
+
+ def test_key_serialization(self):
+ assert Message.serialize(self.des_kv_pair) == self.ser_kv_pair
+ assert Message.serialize(self.des_kv_zero) == self.ser_kv_zero
+
+ def test_section_deserialization(self):
+ single = Message.deserialize(FiniteStream(self.ser_sec_single))
+ nested = Message.deserialize(FiniteStream(self.ser_sec_nested))
+
+ assert single == self.des_sec_single
+ assert nested == self.des_sec_nested
+
+ with pytest.raises(DeserializationException):
+ Message.deserialize(FiniteStream(self.ser_sec_unclosed))
+
+ def test_list_deserialization(self):
+ l0 = Message.deserialize(FiniteStream(self.ser_list_0_item))
+ l1 = Message.deserialize(FiniteStream(self.ser_list_1_item))
+ l2 = Message.deserialize(FiniteStream(self.ser_list_2_item))
+
+ assert l0 == self.des_list_0_item
+ assert l1 == self.des_list_1_item
+ assert l2 == self.des_list_2_item
+
+ with pytest.raises(DeserializationException):
+ Message.deserialize(FiniteStream(self.ser_list_invalid))
+
+ def test_key_deserialization(self):
+ pair = Message.deserialize(FiniteStream(self.ser_kv_pair))
+ zerolength = Message.deserialize(FiniteStream(self.ser_kv_zero))
+
+ assert pair == self.des_kv_pair
+ assert zerolength == self.des_kv_zero
+
+ def test_roundtrip(self):
+ message = {
+ "key1": "value1",
+ "section1": {
+ "sub-section": {
+ "key2": b"value2",
+ },
+ "list1": [ "item1", "item2" ],
+ },
+ }
+ serialized_message = FiniteStream(Message.serialize(message))
+ deserialized_message = Message.deserialize(serialized_message)
+
+ # ensure that list items and key values remain as undecoded bytes
+ deserialized_section = deserialized_message["section1"]
+ assert deserialized_message["key1"] == b"value1"
+ assert deserialized_section["sub-section"]["key2"] == b"value2"
+ assert deserialized_section["list1"] == [ b"item1", b"item2" ]
diff --git a/src/libcharon/plugins/vici/ruby/Makefile.am b/src/libcharon/plugins/vici/ruby/Makefile.am
index ce38e1c3d..3e12f86cc 100644
--- a/src/libcharon/plugins/vici/ruby/Makefile.am
+++ b/src/libcharon/plugins/vici/ruby/Makefile.am
@@ -5,8 +5,10 @@ vici.gemspec: $(srcdir)/vici.gemspec.in
-e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \
$(srcdir)/vici.gemspec.in > $@
-vici-$(PACKAGE_VERSION).gem: vici.gemspec
- $(GEM) build vici.gemspec
+vici-$(PACKAGE_VERSION).gem: vici.gemspec $(EXTRA_DIST)
+ (cd $(srcdir); $(GEM) build $(abs_builddir)/vici.gemspec)
+ [ "$(srcdir)" = "$(builddir)" ] || \
+ mv $(srcdir)/vici-$(PACKAGE_VERSION).gem $(builddir)
all-local: vici-$(PACKAGE_VERSION).gem
diff --git a/src/libcharon/plugins/vici/ruby/Makefile.in b/src/libcharon/plugins/vici/ruby/Makefile.in
index c8a8c11fb..f37c09ea2 100644
--- a/src/libcharon/plugins/vici/ruby/Makefile.in
+++ b/src/libcharon/plugins/vici/ruby/Makefile.in
@@ -142,6 +142,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -202,10 +203,12 @@ 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@
@@ -279,6 +282,8 @@ 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@
@@ -535,8 +540,10 @@ vici.gemspec: $(srcdir)/vici.gemspec.in
-e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \
$(srcdir)/vici.gemspec.in > $@
-vici-$(PACKAGE_VERSION).gem: vici.gemspec
- $(GEM) build vici.gemspec
+vici-$(PACKAGE_VERSION).gem: vici.gemspec $(EXTRA_DIST)
+ (cd $(srcdir); $(GEM) build $(abs_builddir)/vici.gemspec)
+ [ "$(srcdir)" = "$(builddir)" ] || \
+ mv $(srcdir)/vici-$(PACKAGE_VERSION).gem $(builddir)
all-local: vici-$(PACKAGE_VERSION).gem
diff --git a/src/libcharon/plugins/vici/ruby/lib/vici.rb b/src/libcharon/plugins/vici/ruby/lib/vici.rb
index e8a9ddca9..f87e46e69 100644
--- a/src/libcharon/plugins/vici/ruby/lib/vici.rb
+++ b/src/libcharon/plugins/vici/ruby/lib/vici.rb
@@ -243,6 +243,25 @@ module Vici
end
##
+ # Receive data from socket, until len bytes read
+ def recv_all(len)
+ encoding = ""
+ while encoding.length < len do
+ encoding << @socket.recv(len - encoding.length)
+ end
+ encoding
+ end
+
+ ##
+ # Send data to socket, until all bytes sent
+ def send_all(encoding)
+ len = 0
+ while len < encoding.length do
+ len += @socket.send(encoding[len..-1], 0)
+ end
+ end
+
+ ##
# Write a packet prefixed by its length over the transport socket. Type
# specifies the message, the optional label and message get appended.
def write(type, label, message)
@@ -253,15 +272,15 @@ module Vici
if message
encoding << message.encoding
end
- @socket.send([encoding.length + 1, type].pack("Nc") + encoding, 0)
+ send_all([encoding.length + 1, type].pack("Nc") + encoding)
end
##
# Read a packet from the transport socket. Returns the packet type, and
# if available in the packet a label and the contained message.
def read
- len = @socket.recv(4).unpack("N")[0]
- encoding = @socket.recv(len)
+ len = recv_all(4).unpack("N")[0]
+ encoding = recv_all(len)
type = encoding.unpack("c")[0]
len = 1
case type
@@ -371,7 +390,10 @@ module Vici
# during encoding.
class Connection
- def initialize(socket)
+ def initialize(socket = nil)
+ if socket == nil
+ socket = UNIXSocket.new("/var/run/charon.vici")
+ end
@transp = Transport.new(socket)
end
diff --git a/src/libcharon/plugins/vici/ruby/vici.gemspec.in b/src/libcharon/plugins/vici/ruby/vici.gemspec.in
index 5ad61c0a0..2bd2b3d88 100644
--- a/src/libcharon/plugins/vici/ruby/vici.gemspec.in
+++ b/src/libcharon/plugins/vici/ruby/vici.gemspec.in
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
s.name = "vici"
s.version = "@GEM_VERSION@"
s.authors = ["Martin Willi"]
- s.email = ["martin@strongswan.ch"]
+ s.email = ["martin@strongswan.org"]
s.description = %q{
The strongSwan VICI protocol allows external application to monitor,
configure and control the IKE daemon charon. This ruby gem provides a
diff --git a/src/libcharon/plugins/vici/vici_attribute.c b/src/libcharon/plugins/vici/vici_attribute.c
index 2178116c9..f04bae774 100644
--- a/src/libcharon/plugins/vici/vici_attribute.c
+++ b/src/libcharon/plugins/vici/vici_attribute.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2014 Martin Willi
* Copyright (C) 2014 revosec AG
*
@@ -93,7 +96,8 @@ static void pool_destroy(pool_t *pool)
* Find an existing or not yet existing lease
*/
static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools,
- identification_t *id, host_t *requested, mem_pool_op_t op)
+ identification_t *id, host_t *requested,
+ mem_pool_op_t op, host_t *peer)
{
enumerator_t *enumerator;
host_t *addr = NULL;
@@ -106,7 +110,8 @@ static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools,
pool = this->pools->get(this->pools, name);
if (pool)
{
- addr = pool->vips->acquire_address(pool->vips, id, requested, op);
+ addr = pool->vips->acquire_address(pool->vips, id, requested,
+ op, peer);
if (addr)
{
break;
@@ -119,20 +124,24 @@ static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools,
}
METHOD(attribute_provider_t, acquire_address, host_t*,
- private_vici_attribute_t *this, linked_list_t *pools, identification_t *id,
+ private_vici_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
host_t *requested)
{
- host_t *addr;
+ identification_t *id;
+ host_t *addr, *peer;
+
+ id = ike_sa->get_other_eap_id(ike_sa);
+ peer = ike_sa->get_other_host(ike_sa);
this->lock->read_lock(this->lock);
- addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING);
+ addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING, peer);
if (!addr)
{
- addr = find_addr(this, pools, id, requested, MEM_POOL_NEW);
+ addr = find_addr(this, pools, id, requested, MEM_POOL_NEW, peer);
if (!addr)
{
- addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN);
+ addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN, peer);
}
}
@@ -143,13 +152,16 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
METHOD(attribute_provider_t, release_address, bool,
private_vici_attribute_t *this, linked_list_t *pools, host_t *address,
- identification_t *id)
+ ike_sa_t *ike_sa)
{
enumerator_t *enumerator;
+ identification_t *id;
bool found = FALSE;
pool_t *pool;
char *name;
+ id = ike_sa->get_other_eap_id(ike_sa);
+
this->lock->read_lock(this->lock);
enumerator = pools->create_enumerator(pools);
@@ -256,7 +268,7 @@ static bool have_vips_from_pool(mem_pool_t *pool, linked_list_t *vips)
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_vici_attribute_t *this, linked_list_t *pools,
- identification_t *id, linked_list_t *vips)
+ ike_sa_t *ike_sa, linked_list_t *vips)
{
enumerator_t *enumerator;
nested_data_t *data;
@@ -355,6 +367,24 @@ static vici_message_t* create_reply(char *fmt, ...)
}
/**
+ * Parse a range definition of an address pool
+ */
+static mem_pool_t *create_pool_range(char *name, char *buf)
+{
+ mem_pool_t *pool;
+ host_t *from, *to;
+
+ if (!host_create_from_range(buf, &from, &to))
+ {
+ return NULL;
+ }
+ pool = mem_pool_create_range(name, from, to);
+ from->destroy(from);
+ to->destroy(to);
+ return pool;
+}
+
+/**
* Parse callback data, passed to each callback
*/
typedef struct {
@@ -490,7 +520,8 @@ CALLBACK(pool_kv, bool,
if (streq(name, "addrs"))
{
char buf[128];
- host_t *base;
+ mem_pool_t *pool;
+ host_t *base = NULL;
int bits;
if (data->pool->vips)
@@ -503,14 +534,22 @@ CALLBACK(pool_kv, bool,
data->request->reply = create_reply("invalid addrs value");
return FALSE;
}
- base = host_create_from_subnet(buf, &bits);
- if (!base)
+ pool = create_pool_range(data->name, buf);
+ if (!pool)
+ {
+ base = host_create_from_subnet(buf, &bits);
+ if (base)
+ {
+ pool = mem_pool_create(data->name, base, bits);
+ base->destroy(base);
+ }
+ }
+ if (!pool)
{
data->request->reply = create_reply("invalid addrs value: %s", buf);
return FALSE;
}
- data->pool->vips = mem_pool_create(data->name, base, bits);
- base->destroy(base);
+ data->pool->vips = pool;
return TRUE;
}
data->request->reply = create_reply("invalid attribute: %s", name);
diff --git a/src/libcharon/plugins/vici/vici_builder.c b/src/libcharon/plugins/vici/vici_builder.c
index 561632049..82f12c9da 100644
--- a/src/libcharon/plugins/vici/vici_builder.c
+++ b/src/libcharon/plugins/vici/vici_builder.c
@@ -84,6 +84,8 @@ METHOD(vici_builder_t, add, void,
if (value.len > 0xffff)
{
+ DBG1(DBG_ENC, "vici value exceeds size limit (%zu > %u)",
+ value.len, 0xffff);
this->error++;
return;
}
@@ -125,24 +127,58 @@ METHOD(vici_builder_t, add, void,
}
}
-METHOD(vici_builder_t, vadd_kv, void,
- private_vici_builder_t *this, char *key, char *fmt, va_list args)
+/**
+ * Add a list item or a key/value, if key given
+ */
+static void vadd_kv_or_li(private_vici_builder_t *this, char *key,
+ char *fmt, va_list args)
{
- char buf[2048];
+ u_char buf[512];
+ chunk_t value;
ssize_t len;
+ va_list copy;
- len = vsnprintf(buf, sizeof(buf), fmt, args);
- if (len < 0 || len >= sizeof(buf))
+ va_copy(copy, args);
+ len = vsnprintf(buf, sizeof(buf), fmt, copy);
+ va_end(copy);
+ if (len >= sizeof(buf))
{
- DBG1(DBG_ENC, "vici builder format buffer exceeds limit");
+ value = chunk_alloc(len + 1);
+ len = vsnprintf(value.ptr, value.len, fmt, args);
+ }
+ else
+ {
+ value = chunk_create(buf, len);
+ }
+
+ if (len < 0)
+ {
+ DBG1(DBG_ENC, "vici builder format print failed");
this->error++;
}
else
{
- add(this, VICI_KEY_VALUE, key, chunk_create(buf, len));
+ if (key)
+ {
+ add(this, VICI_KEY_VALUE, key, value);
+ }
+ else
+ {
+ add(this, VICI_LIST_ITEM, value);
+ }
+ }
+ if (value.ptr != buf)
+ {
+ free(value.ptr);
}
}
+METHOD(vici_builder_t, vadd_kv, void,
+ private_vici_builder_t *this, char *key, char *fmt, va_list args)
+{
+ vadd_kv_or_li(this, key, fmt, args);
+}
+
METHOD(vici_builder_t, add_kv, void,
private_vici_builder_t *this, char *key, char *fmt, ...)
{
@@ -153,23 +189,10 @@ METHOD(vici_builder_t, add_kv, void,
va_end(args);
}
-
METHOD(vici_builder_t, vadd_li, void,
private_vici_builder_t *this, char *fmt, va_list args)
{
- char buf[2048];
- ssize_t len;
-
- len = vsnprintf(buf, sizeof(buf), fmt, args);
- if (len < 0 || len >= sizeof(buf))
- {
- DBG1(DBG_ENC, "vici builder format buffer exceeds limit");
- this->error++;
- }
- else
- {
- add(this, VICI_LIST_ITEM, chunk_create(buf, len));
- }
+ vadd_kv_or_li(this, NULL, fmt, args);
}
METHOD(vici_builder_t, add_li, void,
@@ -206,6 +229,13 @@ METHOD(vici_builder_t, end_list, void,
add(this, VICI_LIST_END);
}
+METHOD(vici_builder_t, destroy, void,
+ private_vici_builder_t *this)
+{
+ this->writer->destroy(this->writer);
+ free(this);
+}
+
METHOD(vici_builder_t, finalize, vici_message_t*,
private_vici_builder_t *this)
{
@@ -215,14 +245,12 @@ METHOD(vici_builder_t, finalize, vici_message_t*,
{
DBG1(DBG_ENC, "vici builder error: %u errors (section: %u, list %u)",
this->error, this->section, this->list);
- this->writer->destroy(this->writer);
- free(this);
+ destroy(this);
return NULL;
}
product = vici_message_create_from_data(
this->writer->extract_buf(this->writer), TRUE);
- this->writer->destroy(this->writer);
- free(this);
+ destroy(this);
return product;
}
@@ -245,6 +273,7 @@ vici_builder_t *vici_builder_create()
.begin_list = _begin_list,
.end_list = _end_list,
.finalize = _finalize,
+ .destroy = _destroy,
},
.writer = bio_writer_create(0),
);
diff --git a/src/libcharon/plugins/vici/vici_builder.h b/src/libcharon/plugins/vici/vici_builder.h
index 5a5cc8a03..f7d21eb8f 100644
--- a/src/libcharon/plugins/vici/vici_builder.h
+++ b/src/libcharon/plugins/vici/vici_builder.h
@@ -119,6 +119,14 @@ struct vici_builder_t {
* @return vici message, NULL on error
*/
vici_message_t* (*finalize)(vici_builder_t *this);
+
+ /**
+ * Destroy a vici builder without finalization.
+ *
+ * Note that finalize() already destroys the message, and calling destroy()
+ * is required only if the message does not get finalize()d.
+ */
+ void (*destroy)(vici_builder_t *this);
};
/**
diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c
index 113d48084..649161020 100644
--- a/src/libcharon/plugins/vici/vici_config.c
+++ b/src/libcharon/plugins/vici/vici_config.c
@@ -1551,8 +1551,8 @@ static void clear_start_action(private_vici_config_t *this,
enumerator_t *enumerator, *children;
child_sa_t *child_sa;
ike_sa_t *ike_sa;
- u_int32_t reqid = 0, *del;
- array_t *reqids = NULL;
+ u_int32_t id = 0, *del;
+ array_t *ids = NULL;
char *name;
name = child_cfg->get_name(child_cfg);
@@ -1568,23 +1568,23 @@ static void clear_start_action(private_vici_config_t *this,
{
if (streq(name, child_sa->get_name(child_sa)))
{
- reqid = child_sa->get_reqid(child_sa);
- array_insert_create(&reqids, ARRAY_TAIL, &reqid);
+ id = child_sa->get_unique_id(child_sa);
+ array_insert_create(&ids, ARRAY_TAIL, &id);
}
}
children->destroy(children);
}
enumerator->destroy(enumerator);
- if (array_count(reqids))
+ if (array_count(ids))
{
- while (array_remove(reqids, ARRAY_HEAD, &del))
+ while (array_remove(ids, ARRAY_HEAD, &del))
{
DBG1(DBG_CFG, "closing '%s' #%u", name, *del);
charon->controller->terminate_child(charon->controller,
*del, NULL, NULL, 0);
}
- array_destroy(reqids);
+ array_destroy(ids);
}
break;
case ACTION_ROUTE:
@@ -1601,14 +1601,14 @@ static void clear_start_action(private_vici_config_t *this,
{
if (streq(name, child_sa->get_name(child_sa)))
{
- reqid = child_sa->get_reqid(child_sa);
+ id = child_sa->get_reqid(child_sa);
break;
}
}
enumerator->destroy(enumerator);
- if (reqid)
+ if (id)
{
- charon->traps->uninstall(charon->traps, reqid);
+ charon->traps->uninstall(charon->traps, id);
}
break;
}
@@ -1751,7 +1751,8 @@ CALLBACK(config_sn, bool,
.fragmentation = FRAGMENTATION_NO,
.unique = UNIQUE_NO,
.keyingtries = 1,
- .rekey_time = LFT_DEFAULT_IKE_REKEY,
+ .rekey_time = LFT_UNDEFINED,
+ .reauth_time = LFT_UNDEFINED,
.over_time = LFT_UNDEFINED,
.rand_time = LFT_UNDEFINED,
};
@@ -1809,6 +1810,20 @@ CALLBACK(config_sn, bool,
peer.local_port = charon->socket->get_port(charon->socket, FALSE);
}
+ if (peer.rekey_time == LFT_UNDEFINED && peer.reauth_time == LFT_UNDEFINED)
+ {
+ /* apply a default rekey time if no rekey/reauth time set */
+ peer.rekey_time = LFT_DEFAULT_IKE_REKEY;
+ peer.reauth_time = 0;
+ }
+ if (peer.rekey_time == LFT_UNDEFINED)
+ {
+ peer.rekey_time = 0;
+ }
+ if (peer.reauth_time == LFT_UNDEFINED)
+ {
+ peer.reauth_time = 0;
+ }
if (peer.over_time == LFT_UNDEFINED)
{
/* default over_time to 10% of rekey/reauth time if not given */
@@ -1816,9 +1831,17 @@ CALLBACK(config_sn, bool,
}
if (peer.rand_time == LFT_UNDEFINED)
{
- /* default rand_time to over_time if not given */
- peer.rand_time = min(peer.over_time,
- max(peer.rekey_time, peer.reauth_time) / 2);
+ /* default rand_time to over_time if not given, but don't make it
+ * longer than half of rekey/rauth time */
+ if (peer.rekey_time && peer.reauth_time)
+ {
+ peer.rand_time = min(peer.rekey_time, peer.reauth_time);
+ }
+ else
+ {
+ peer.rand_time = max(peer.rekey_time, peer.reauth_time);
+ }
+ peer.rand_time = min(peer.over_time, peer.rand_time / 2);
}
log_peer_data(&peer);
diff --git a/src/libcharon/plugins/vici/vici_control.c b/src/libcharon/plugins/vici/vici_control.c
index 292a40032..01d503644 100644
--- a/src/libcharon/plugins/vici/vici_control.c
+++ b/src/libcharon/plugins/vici/vici_control.c
@@ -264,11 +264,11 @@ CALLBACK(terminate, vici_message_t*,
{
continue;
}
- if (child_id && child_sa->get_reqid(child_sa) != child_id)
+ if (child_id && child_sa->get_unique_id(child_sa) != child_id)
{
continue;
}
- current = child_sa->get_reqid(child_sa);
+ current = child_sa->get_unique_id(child_sa);
array_insert(ids, ARRAY_TAIL, &current);
}
csas->destroy(csas);
diff --git a/src/libcharon/plugins/vici/vici_plugin.c b/src/libcharon/plugins/vici/vici_plugin.c
index 8881feca9..af8bd283b 100644
--- a/src/libcharon/plugins/vici/vici_plugin.c
+++ b/src/libcharon/plugins/vici/vici_plugin.c
@@ -23,7 +23,6 @@
#include "vici_logger.h"
#include <library.h>
-#include <hydra.h>
#include <daemon.h>
typedef struct private_vici_plugin_t private_vici_plugin_t;
@@ -104,8 +103,8 @@ static bool register_vici(private_vici_plugin_t *this,
charon->backends->add_backend(charon->backends,
&this->config->backend);
- hydra->attributes->add_provider(hydra->attributes,
- &this->attrs->provider);
+ charon->attributes->add_provider(charon->attributes,
+ &this->attrs->provider);
charon->bus->add_logger(charon->bus, &this->logger->logger);
return TRUE;
}
@@ -114,8 +113,8 @@ static bool register_vici(private_vici_plugin_t *this,
else
{
charon->bus->remove_logger(charon->bus, &this->logger->logger);
- hydra->attributes->remove_provider(hydra->attributes,
- &this->attrs->provider);
+ charon->attributes->remove_provider(charon->attributes,
+ &this->attrs->provider);
charon->backends->remove_backend(charon->backends,
&this->config->backend);
diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c
index 54833abde..3e0d73cdf 100644
--- a/src/libcharon/plugins/vici/vici_query.c
+++ b/src/libcharon/plugins/vici/vici_query.c
@@ -63,11 +63,13 @@ static void list_child(private_vici_query_t *this, vici_builder_t *b,
enumerator_t *enumerator;
traffic_selector_t *ts;
+ b->add_kv(b, "uniqueid", "%u", child->get_unique_id(child));
b->add_kv(b, "reqid", "%u", child->get_reqid(child));
b->add_kv(b, "state", "%N", child_sa_state_names, child->get_state(child));
b->add_kv(b, "mode", "%N", ipsec_mode_names, child->get_mode(child));
if (child->get_state(child) == CHILD_INSTALLED ||
- child->get_state(child) == CHILD_REKEYING)
+ child->get_state(child) == CHILD_REKEYING ||
+ child->get_state(child) == CHILD_REKEYED)
{
b->add_kv(b, "protocol", "%N", protocol_id_names,
child->get_protocol(child));
@@ -507,11 +509,14 @@ static void build_auth_cfgs(peer_cfg_t *peer_cfg, bool local, vici_builder_t *b)
certificate_t *cert;
char *str;
} v;
+ char buf[32];
+ int i = 0;
enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
while (enumerator->enumerate(enumerator, &auth))
{
- b->begin_section(b, local ? "local" : "remote");
+ snprintf(buf, sizeof(buf), "%s-%d", local ? "local" : "remote", ++i);
+ b->begin_section(b, buf);
rules = auth->create_enumerator(auth);
while (rules->enumerate(rules, &rule, &v))
@@ -976,10 +981,10 @@ CALLBACK(stats, vici_message_t*,
struct mallinfo mi = mallinfo();
b->begin_section(b, "mallinfo");
- b->add_kv(b, "sbrk", "%d", mi.arena);
- b->add_kv(b, "mmap", "%d", mi.hblkhd);
- b->add_kv(b, "used", "%d", mi.uordblks);
- b->add_kv(b, "free", "%d", mi.fordblks);
+ b->add_kv(b, "sbrk", "%u", mi.arena);
+ b->add_kv(b, "mmap", "%u", mi.hblkhd);
+ b->add_kv(b, "used", "%u", mi.uordblks);
+ b->add_kv(b, "free", "%u", mi.fordblks);
b->end_section(b);
}
#endif /* HAVE_MALLINFO */
diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in
index b1cc1d118..e400d9f35 100644
--- a/src/libcharon/plugins/whitelist/Makefile.in
+++ b/src/libcharon/plugins/whitelist/Makefile.in
@@ -236,6 +236,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -296,10 +297,12 @@ 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@
@@ -373,6 +376,8 @@ 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@
diff --git a/src/libcharon/plugins/xauth_eap/Makefile.in b/src/libcharon/plugins/xauth_eap/Makefile.in
index e393ee163..a9684455d 100644
--- a/src/libcharon/plugins/xauth_eap/Makefile.in
+++ b/src/libcharon/plugins/xauth_eap/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/xauth_generic/Makefile.in b/src/libcharon/plugins/xauth_generic/Makefile.in
index f0e772700..5170c924f 100644
--- a/src/libcharon/plugins/xauth_generic/Makefile.in
+++ b/src/libcharon/plugins/xauth_generic/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/xauth_noauth/Makefile.in b/src/libcharon/plugins/xauth_noauth/Makefile.in
index a4c1aaeb2..087f5b350 100644
--- a/src/libcharon/plugins/xauth_noauth/Makefile.in
+++ b/src/libcharon/plugins/xauth_noauth/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/plugins/xauth_pam/Makefile.in b/src/libcharon/plugins/xauth_pam/Makefile.in
index 296ccaa1c..29441bcb5 100644
--- a/src/libcharon/plugins/xauth_pam/Makefile.in
+++ b/src/libcharon/plugins/xauth_pam/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ 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@
@@ -366,6 +369,8 @@ 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@
diff --git a/src/libcharon/processing/jobs/adopt_children_job.c b/src/libcharon/processing/jobs/adopt_children_job.c
index fb480eee2..c8a9c17de 100644
--- a/src/libcharon/processing/jobs/adopt_children_job.c
+++ b/src/libcharon/processing/jobs/adopt_children_job.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2012 Martin Willi
* Copyright (C) 2012 revosec AG
*
@@ -54,10 +57,10 @@ METHOD(job_t, execute, job_requeue_t,
private_adopt_children_job_t *this)
{
identification_t *my_id, *other_id, *xauth;
- host_t *me, *other;
+ host_t *me, *other, *vip;
peer_cfg_t *cfg;
- linked_list_t *children;
- enumerator_t *enumerator, *childenum;
+ linked_list_t *children, *vips;
+ enumerator_t *enumerator, *subenum;
ike_sa_id_t *id;
ike_sa_t *ike_sa;
child_sa_t *child_sa;
@@ -81,7 +84,8 @@ METHOD(job_t, execute, job_requeue_t,
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- /* find old SA to adopt children from */
+ /* find old SA to adopt children and virtual IPs from */
+ vips = linked_list_create();
children = linked_list_create();
enumerator = charon->ike_sa_manager->create_id_enumerator(
charon->ike_sa_manager, my_id, xauth,
@@ -102,18 +106,29 @@ METHOD(job_t, execute, job_requeue_t,
other_id->equals(other_id, ike_sa->get_other_id(ike_sa)) &&
cfg->equals(cfg, ike_sa->get_peer_cfg(ike_sa)))
{
- childenum = ike_sa->create_child_sa_enumerator(ike_sa);
- while (childenum->enumerate(childenum, &child_sa))
+ subenum = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (subenum->enumerate(subenum, &child_sa))
{
- ike_sa->remove_child_sa(ike_sa, childenum);
+ ike_sa->remove_child_sa(ike_sa, subenum);
children->insert_last(children, child_sa);
}
- childenum->destroy(childenum);
- if (children->get_count(children))
+ subenum->destroy(subenum);
+
+ subenum = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
+ while (subenum->enumerate(subenum, &vip))
+ {
+ vips->insert_last(vips, vip->clone(vip));
+ }
+ subenum->destroy(subenum);
+ /* this does not release the addresses, which is good, but
+ * it does trigger an assign_vips(FALSE) event, so we also
+ * trigger one below */
+ ike_sa->clear_virtual_ips(ike_sa, FALSE);
+ if (children->get_count(children) || vips->get_count(vips))
{
DBG1(DBG_IKE, "detected reauth of existing IKE_SA, "
- "adopting %d children",
- children->get_count(children));
+ "adopting %d children and %d virtual IPs",
+ children->get_count(children), vips->get_count(vips));
}
ike_sa->set_state(ike_sa, IKE_DELETING);
charon->bus->ike_updown(charon->bus, ike_sa, FALSE);
@@ -125,7 +140,7 @@ METHOD(job_t, execute, job_requeue_t,
charon->ike_sa_manager->checkin(
charon->ike_sa_manager, ike_sa);
}
- if (children->get_count(children))
+ if (children->get_count(children) || vips->get_count(vips))
{
break;
}
@@ -140,7 +155,7 @@ METHOD(job_t, execute, job_requeue_t,
xauth->destroy(xauth);
cfg->destroy(cfg);
- if (children->get_count(children))
+ if (children->get_count(children) || vips->get_count(vips))
{
/* adopt children by new SA */
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
@@ -152,10 +167,27 @@ METHOD(job_t, execute, job_requeue_t,
{
ike_sa->add_child_sa(ike_sa, child_sa);
}
+ if (vips->get_count(vips))
+ {
+ while (vips->remove_first(vips, (void**)&vip) == SUCCESS)
+ {
+ ike_sa->add_virtual_ip(ike_sa, FALSE, vip);
+ vip->destroy(vip);
+ }
+ charon->bus->assign_vips(charon->bus, ike_sa, TRUE);
+ }
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
}
children->destroy_offset(children, offsetof(child_sa_t, destroy));
+ /* FIXME: If we still have addresses here it means we weren't able to
+ * find the new SA anymore (while not very likely during a proper
+ * reauthentication, this theoretically could happen because the SA is
+ * not locked while we search for the old one). So the addresses here
+ * should be released properly to avoid leaking these leases. This is
+ * currently not possible, though, due to the changed interface of
+ * release_address(), which now takes a complete IKE_SA object. */
+ vips->destroy_offset(vips, offsetof(host_t, destroy));
if (array_count(this->tasks))
{
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c
index 9afbac02b..0d85883be 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.c
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.c
@@ -31,11 +31,6 @@ struct private_delete_child_sa_job_t {
delete_child_sa_job_t public;
/**
- * reqid of the CHILD_SA
- */
- u_int32_t reqid;
-
- /**
* protocol of the CHILD_SA (ESP/AH)
*/
protocol_id_t protocol;
@@ -46,6 +41,11 @@ struct private_delete_child_sa_job_t {
u_int32_t spi;
/**
+ * SA destination address
+ */
+ host_t *dst;
+
+ /**
* Delete for an expired CHILD_SA
*/
bool expired;
@@ -54,6 +54,7 @@ struct private_delete_child_sa_job_t {
METHOD(job_t, destroy, void,
private_delete_child_sa_job_t *this)
{
+ this->dst->destroy(this->dst);
free(this);
}
@@ -62,12 +63,12 @@ METHOD(job_t, execute, job_requeue_t,
{
ike_sa_t *ike_sa;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- this->reqid, TRUE);
+ ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
+ this->protocol, this->spi, this->dst, NULL);
if (ike_sa == NULL)
{
- DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for delete",
- this->reqid);
+ DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for delete",
+ protocol_id_names, this->protocol, htonl(this->spi), this->dst);
}
else
{
@@ -87,8 +88,8 @@ METHOD(job_t, get_priority, job_priority_t,
/*
* Described in header
*/
-delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol, u_int32_t spi, bool expired)
+delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst, bool expired)
{
private_delete_child_sa_job_t *this;
@@ -100,12 +101,11 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
.destroy = _destroy,
},
},
- .reqid = reqid,
.protocol = protocol,
.spi = spi,
+ .dst = dst->clone(dst),
.expired = expired,
);
return &this->public;
}
-
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h
index be6d578bc..6fa53644c 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.h
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.h
@@ -44,16 +44,13 @@ struct delete_child_sa_job_t {
/**
* Creates a job of type DELETE_CHILD_SA.
*
- * The CHILD_SA is identified by its reqid, protocol (AH/ESP) and its
- * inbound SPI.
- *
- * @param reqid reqid of the CHILD_SA, as used in kernel
* @param protocol protocol of the CHILD_SA
* @param spi security parameter index of the CHILD_SA
+ * @param dst SA destination address
* @param expired TRUE if CHILD_SA already expired
* @return delete_child_sa_job_t object
*/
-delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol, u_int32_t spi, bool expired);
+delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst, bool expired);
#endif /** DELETE_CHILD_SA_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/dpd_timeout_job.c b/src/libcharon/processing/jobs/dpd_timeout_job.c
index 9cdce5cab..4c88c13e2 100644
--- a/src/libcharon/processing/jobs/dpd_timeout_job.c
+++ b/src/libcharon/processing/jobs/dpd_timeout_job.c
@@ -63,6 +63,12 @@ METHOD(job_t, execute, job_requeue_t,
this->ike_sa_id);
if (ike_sa)
{
+ if (ike_sa->get_state(ike_sa) == IKE_PASSIVE)
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return JOB_REQUEUE_NONE;
+ }
+
use_time = ike_sa->get_statistic(ike_sa, STAT_INBOUND);
enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c
index 197733979..f0f90eedf 100644
--- a/src/libcharon/processing/jobs/inactivity_job.c
+++ b/src/libcharon/processing/jobs/inactivity_job.c
@@ -30,9 +30,9 @@ struct private_inactivity_job_t {
inactivity_job_t public;
/**
- * Reqid of CHILD_SA to check
+ * Unique CHILD_SA identifier to check
*/
- u_int32_t reqid;
+ u_int32_t id;
/**
* Inactivity timeout
@@ -57,8 +57,8 @@ METHOD(job_t, execute, job_requeue_t,
ike_sa_t *ike_sa;
u_int32_t reschedule = 0;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- this->reqid, TRUE);
+ ike_sa = charon->child_sa_manager->checkout_by_id(charon->child_sa_manager,
+ this->id, NULL);
if (ike_sa)
{
enumerator_t *enumerator;
@@ -69,9 +69,9 @@ METHOD(job_t, execute, job_requeue_t,
status_t status = SUCCESS;
enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
- while (enumerator->enumerate(enumerator, (void**)&child_sa))
+ while (enumerator->enumerate(enumerator, &child_sa))
{
- if (child_sa->get_reqid(child_sa) == this->reqid)
+ if (child_sa->get_unique_id(child_sa) == this->id)
{
time_t in, out, install, diff;
@@ -136,7 +136,7 @@ METHOD(job_t, get_priority, job_priority_t,
/**
* See header
*/
-inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout,
+inactivity_job_t *inactivity_job_create(u_int32_t unique_id, u_int32_t timeout,
bool close_ike)
{
private_inactivity_job_t *this;
@@ -149,7 +149,7 @@ inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout,
.destroy = _destroy,
},
},
- .reqid = reqid,
+ .id = unique_id,
.timeout = timeout,
.close_ike = close_ike,
);
diff --git a/src/libcharon/processing/jobs/inactivity_job.h b/src/libcharon/processing/jobs/inactivity_job.h
index 890f7704b..ff19fe560 100644
--- a/src/libcharon/processing/jobs/inactivity_job.h
+++ b/src/libcharon/processing/jobs/inactivity_job.h
@@ -42,12 +42,12 @@ struct inactivity_job_t {
/**
* Create a inactivity_job instance.
*
- * @param reqid reqid of CHILD_SA to check for inactivity
+ * @param unique_id unique CHILD_SA identifier to check for inactivity
* @param timeout inactivity timeout in s
* @param close_ike close IKE_SA if the last remaining CHILD_SA is inactive?
* @return inactivity checking job
*/
-inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout,
+inactivity_job_t *inactivity_job_create(u_int32_t unique_id, u_int32_t timeout,
bool close_ike);
#endif /** INACTIVITY_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/initiate_tasks_job.c b/src/libcharon/processing/jobs/initiate_tasks_job.c
new file mode 100644
index 000000000..001e71fd1
--- /dev/null
+++ b/src/libcharon/processing/jobs/initiate_tasks_job.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdlib.h>
+
+#include "initiate_tasks_job.h"
+
+#include <sa/ike_sa.h>
+#include <daemon.h>
+
+
+typedef struct private_initiate_tasks_job_t private_initiate_tasks_job_t;
+
+/**
+ * Private data of an initiate_tasks_job_t Object
+ */
+struct private_initiate_tasks_job_t {
+
+ /**
+ * Public initiate_tasks_job_t interface
+ */
+ initiate_tasks_job_t public;
+
+ /**
+ * ID of the IKE_SA to trigger task initiation
+ */
+ ike_sa_id_t *ike_sa_id;
+};
+
+METHOD(job_t, destroy, void,
+ private_initiate_tasks_job_t *this)
+{
+ this->ike_sa_id->destroy(this->ike_sa_id);
+ free(this);
+}
+
+METHOD(job_t, execute, job_requeue_t,
+ private_initiate_tasks_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->ike_sa_id);
+ if (ike_sa)
+ {
+ if (ike_sa->initiate(ike_sa, NULL, 0, NULL, NULL) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+METHOD(job_t, get_priority, job_priority_t,
+ private_initiate_tasks_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
+/*
+ * Described in header
+ */
+initiate_tasks_job_t *initiate_tasks_job_create(ike_sa_id_t *ike_sa_id)
+{
+ private_initiate_tasks_job_t *this;
+
+ INIT(this,
+ .public = {
+ .job_interface = {
+ .execute = _execute,
+ .get_priority = _get_priority,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa_id = ike_sa_id->clone(ike_sa_id),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/processing/jobs/initiate_tasks_job.h b/src/libcharon/processing/jobs/initiate_tasks_job.h
new file mode 100644
index 000000000..071497843
--- /dev/null
+++ b/src/libcharon/processing/jobs/initiate_tasks_job.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup initiate_tasks_job initiate_tasks_job
+ * @{ @ingroup cjobs
+ */
+
+#ifndef INITIATE_TASKS_JOB_H_
+#define INITIATE_TASKS_JOB_H_
+
+typedef struct initiate_tasks_job_t initiate_tasks_job_t;
+
+#include <library.h>
+#include <processing/jobs/job.h>
+#include <sa/ike_sa_id.h>
+
+/**
+ * Job triggering initiation of any queued IKE_SA tasks.
+ */
+struct initiate_tasks_job_t {
+
+ /**
+ * Implements job_t interface
+ */
+ job_t job_interface;
+};
+
+/**
+ * Creates a job to trigger IKE_SA task initiation.
+ *
+ * @param ike_sa_id ID of IKE_SA to trigger tasks for (gets cloned)
+ * @return job instance
+ */
+initiate_tasks_job_t *initiate_tasks_job_create(ike_sa_id_t *ike_sa_id);
+
+#endif /** INITIATE_TASKS_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/migrate_job.c b/src/libcharon/processing/jobs/migrate_job.c
index 2ebfc6714..097dbdffd 100644
--- a/src/libcharon/processing/jobs/migrate_job.c
+++ b/src/libcharon/processing/jobs/migrate_job.c
@@ -70,29 +70,34 @@ METHOD(job_t, destroy, void,
METHOD(job_t, execute, job_requeue_t,
private_migrate_job_t *this)
{
- ike_sa_t *ike_sa = NULL;
+ enumerator_t *ike_sas, *children;
+ ike_sa_t *ike_sa;
- if (this->reqid)
+ ike_sas = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager,
+ TRUE);
+ while (ike_sas->enumerate(ike_sas, &ike_sa))
{
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- this->reqid, TRUE);
- }
- if (ike_sa)
- {
- enumerator_t *children, *enumerator;
- child_sa_t *child_sa;
- host_t *host;
+ child_sa_t *current, *child_sa = NULL;
linked_list_t *vips;
+ status_t status;
+ host_t *host;
children = ike_sa->create_child_sa_enumerator(ike_sa);
- while (children->enumerate(children, (void**)&child_sa))
+ while (children->enumerate(children, &current))
{
- if (child_sa->get_reqid(child_sa) == this->reqid)
+ if (current->get_reqid(current) == this->reqid)
{
+ child_sa = current;
break;
}
}
children->destroy(children);
+
+ if (!child_sa)
+ {
+ continue;
+ }
+
DBG2(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid);
ike_sa->set_kmaddress(ike_sa, this->local, this->remote);
@@ -105,27 +110,28 @@ METHOD(job_t, execute, job_requeue_t,
host->set_port(host, IKEV2_UDP_PORT);
ike_sa->set_other_host(ike_sa, host);
- vips = linked_list_create();
- enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
- while (enumerator->enumerate(enumerator, &host))
- {
- vips->insert_last(vips, host);
- }
- enumerator->destroy(enumerator);
+ vips = linked_list_create_from_enumerator(
+ ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE));
- if (child_sa->update(child_sa, this->local, this->remote, vips,
- ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
+ status = child_sa->update(child_sa, this->local, this->remote, vips,
+ ike_sa->has_condition(ike_sa, COND_NAT_ANY));
+ switch (status)
{
- ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE));
+ case NOT_SUPPORTED:
+ ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE));
+ break;
+ case SUCCESS:
+ charon->child_sa_manager->remove(charon->child_sa_manager,
+ child_sa);
+ charon->child_sa_manager->add(charon->child_sa_manager,
+ child_sa, ike_sa);
+ default:
+ break;
}
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
vips->destroy(vips);
}
- else
- {
- DBG1(DBG_JOB, "no CHILD_SA found with reqid {%d}", this->reqid);
- }
+ ike_sas->destroy(ike_sas);
return JOB_REQUEUE_NONE;
}
diff --git a/src/libcharon/processing/jobs/migrate_job.h b/src/libcharon/processing/jobs/migrate_job.h
index 30c0ad0ac..0f2b9aaad 100644
--- a/src/libcharon/processing/jobs/migrate_job.h
+++ b/src/libcharon/processing/jobs/migrate_job.h
@@ -46,7 +46,7 @@ struct migrate_job_t {
*
* We use the reqid or the traffic selectors to find a matching CHILD_SA.
*
- * @param reqid reqid of the CHILD_SA to acquire
+ * @param reqid reqid of the CHILD_SA to migrate
* @param src_ts source traffic selector to be used in the policy
* @param dst_ts destination traffic selector to be used in the policy
* @param dir direction of the policy (in|out)
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.c b/src/libcharon/processing/jobs/rekey_child_sa_job.c
index 1bf8dc0cb..8f17d39ab 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.c
@@ -24,17 +24,13 @@ typedef struct private_rekey_child_sa_job_t private_rekey_child_sa_job_t;
* Private data of an rekey_child_sa_job_t object.
*/
struct private_rekey_child_sa_job_t {
+
/**
* Public rekey_child_sa_job_t interface.
*/
rekey_child_sa_job_t public;
/**
- * reqid of the child to rekey
- */
- u_int32_t reqid;
-
- /**
* protocol of the CHILD_SA (ESP/AH)
*/
protocol_id_t protocol;
@@ -43,11 +39,17 @@ struct private_rekey_child_sa_job_t {
* inbound SPI of the CHILD_SA
*/
u_int32_t spi;
+
+ /**
+ * SA destination address
+ */
+ host_t *dst;
};
METHOD(job_t, destroy, void,
private_rekey_child_sa_job_t *this)
{
+ this->dst->destroy(this->dst);
free(this);
}
@@ -56,12 +58,12 @@ METHOD(job_t, execute, job_requeue_t,
{
ike_sa_t *ike_sa;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- this->reqid, TRUE);
+ ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
+ this->protocol, this->spi, this->dst, NULL);
if (ike_sa == NULL)
{
- DBG2(DBG_JOB, "CHILD_SA with reqid %d not found for rekeying",
- this->reqid);
+ DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for rekey",
+ protocol_id_names, this->protocol, htonl(this->spi), this->dst);
}
else
{
@@ -80,9 +82,8 @@ METHOD(job_t, get_priority, job_priority_t,
/*
* Described in header
*/
-rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol,
- u_int32_t spi)
+rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst)
{
private_rekey_child_sa_job_t *this;
@@ -94,9 +95,9 @@ rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
.destroy = _destroy,
},
},
- .reqid = reqid,
.protocol = protocol,
.spi = spi,
+ .dst = dst->clone(dst),
);
return &this->public;
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.h b/src/libcharon/processing/jobs/rekey_child_sa_job.h
index fcbe65a06..364bb5ae7 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.h
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.h
@@ -43,15 +43,11 @@ struct rekey_child_sa_job_t {
/**
* Creates a job of type REKEY_CHILD_SA.
*
- * The CHILD_SA is identified by its protocol (AH/ESP) and its
- * inbound SPI.
- *
- * @param reqid reqid of the CHILD_SA to rekey
* @param protocol protocol of the CHILD_SA
* @param spi security parameter index of the CHILD_SA
+ * @param dst SA destination address
* @return rekey_child_sa_job_t object
*/
-rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol,
- u_int32_t spi);
+rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst);
#endif /** REKEY_CHILD_SA_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.c b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
index 516dc5dd5..403d826a3 100644
--- a/src/libcharon/processing/jobs/rekey_ike_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
@@ -67,7 +67,8 @@ static u_int32_t get_retry_delay(ike_sa_t *ike_sa)
enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
while (enumerator->enumerate(enumerator, &child_sa))
{
- if (child_sa->get_state(child_sa) != CHILD_INSTALLED)
+ if (child_sa->get_state(child_sa) != CHILD_INSTALLED &&
+ child_sa->get_state(child_sa) != CHILD_REKEYED)
{
retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
DBG1(DBG_IKE, "unable to reauthenticate in CHILD_SA %N state, "
diff --git a/src/libcharon/processing/jobs/update_sa_job.c b/src/libcharon/processing/jobs/update_sa_job.c
index e6d7da2c6..862506d90 100644
--- a/src/libcharon/processing/jobs/update_sa_job.c
+++ b/src/libcharon/processing/jobs/update_sa_job.c
@@ -27,15 +27,26 @@ typedef struct private_update_sa_job_t private_update_sa_job_t;
* Private data of an update_sa_job_t Object
*/
struct private_update_sa_job_t {
+
/**
* public update_sa_job_t interface
*/
update_sa_job_t public;
/**
- * reqid of the CHILD_SA
+ * protocol of the CHILD_SA (ESP/AH)
+ */
+ protocol_id_t protocol;
+
+ /**
+ * SPI of the CHILD_SA
*/
- u_int32_t reqid;
+ u_int32_t spi;
+
+ /**
+ * Old SA destination address
+ */
+ host_t *dst;
/**
* New SA address and port
@@ -46,6 +57,7 @@ struct private_update_sa_job_t {
METHOD(job_t, destroy, void,
private_update_sa_job_t *this)
{
+ this->dst->destroy(this->dst);
this->new->destroy(this->new);
free(this);
}
@@ -55,11 +67,12 @@ METHOD(job_t, execute, job_requeue_t,
{
ike_sa_t *ike_sa;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- this->reqid, TRUE);
+ ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
+ this->protocol, this->spi, this->dst, NULL);
if (ike_sa == NULL)
{
- DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for update", this->reqid);
+ DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for update",
+ protocol_id_names, this->protocol, htonl(this->spi), this->dst);
}
else
{
@@ -78,7 +91,8 @@ METHOD(job_t, get_priority, job_priority_t,
/*
* Described in header
*/
-update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new)
+update_sa_job_t *update_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst, host_t *new)
{
private_update_sa_job_t *this;
@@ -90,10 +104,11 @@ update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new)
.destroy = _destroy,
},
},
- .reqid = reqid,
- .new = new,
+ .protocol = protocol,
+ .spi = spi,
+ .dst = dst->clone(dst),
+ .new = new->clone(new),
);
return &this->public;
}
-
diff --git a/src/libcharon/processing/jobs/update_sa_job.h b/src/libcharon/processing/jobs/update_sa_job.h
index 55a3df83e..9c19f5b6e 100644
--- a/src/libcharon/processing/jobs/update_sa_job.h
+++ b/src/libcharon/processing/jobs/update_sa_job.h
@@ -26,6 +26,7 @@ typedef struct update_sa_job_t update_sa_job_t;
#include <library.h>
#include <networking/host.h>
#include <processing/jobs/job.h>
+#include <config/proposal.h>
/**
* Update the addresses of an IKE and its CHILD_SAs.
@@ -41,10 +42,13 @@ struct update_sa_job_t {
/**
* Creates a job to update IKE and CHILD_SA addresses.
*
- * @param reqid reqid of the CHILD_SA
+ * @param protocol IPsec protocol of SA to update
+ * @param spi SPI of SA to update
+ * @param dst old destination host of SA to update
* @param new new address and port
* @return update_sa_job_t object
*/
-update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new);
+update_sa_job_t *update_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst, host_t *new);
#endif /** UPDATE_SA_JOB_H_ @}*/
diff --git a/src/libcharon/sa/authenticator.c b/src/libcharon/sa/authenticator.c
index 8571274ac..6c3681a2d 100644
--- a/src/libcharon/sa/authenticator.c
+++ b/src/libcharon/sa/authenticator.c
@@ -31,12 +31,14 @@ ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS,
"RSA signature",
"pre-shared key",
"DSS signature");
-ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_GSPM, AUTH_DSS,
+ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_DS, AUTH_DSS,
"ECDSA-256 signature",
"ECDSA-384 signature",
"ECDSA-521 signature",
- "secure password method");
-ENUM_NEXT(auth_method_names, AUTH_XAUTH_INIT_PSK, AUTH_HYBRID_RESP_RSA, AUTH_GSPM,
+ "secure password method",
+ "NULL authentication",
+ "digital signature");
+ENUM_NEXT(auth_method_names, AUTH_XAUTH_INIT_PSK, AUTH_HYBRID_RESP_RSA, AUTH_DS,
"XAuthInitPSK",
"XAuthRespPSK",
"XAuthInitRSA",
@@ -99,6 +101,7 @@ authenticator_t *authenticator_create_verifier(
case AUTH_ECDSA_256:
case AUTH_ECDSA_384:
case AUTH_ECDSA_521:
+ case AUTH_DS:
return (authenticator_t*)pubkey_authenticator_create_verifier(ike_sa,
sent_nonce, received_init, reserved);
case AUTH_PSK:
diff --git a/src/libcharon/sa/authenticator.h b/src/libcharon/sa/authenticator.h
index 914f42d9d..97c042e71 100644
--- a/src/libcharon/sa/authenticator.h
+++ b/src/libcharon/sa/authenticator.h
@@ -80,6 +80,16 @@ enum auth_method_t {
AUTH_GSPM = 12,
/**
+ * NULL Authentication Method as specified in draft-ietf-ipsecme-ikev2-null-auth
+ */
+ AUTH_NULL = 13,
+
+ /**
+ * Digital Signature as specified in RFC 7427
+ */
+ AUTH_DS = 14,
+
+ /**
* IKEv1 initiator XAUTH with PSK, outside of IANA range
*/
AUTH_XAUTH_INIT_PSK = 256,
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index a96ab4e90..e0db2e655 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -34,6 +34,8 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
"INSTALLED",
"UPDATING",
"REKEYING",
+ "REKEYED",
+ "RETRYING",
"DELETING",
"DESTROYING",
);
@@ -100,6 +102,16 @@ struct private_child_sa_t {
u_int32_t reqid;
/**
+ * Did we allocate/confirm and must release the reqid?
+ */
+ bool reqid_allocated;
+
+ /*
+ * Unique CHILD_SA identifier
+ */
+ u_int32_t unique_id;
+
+ /**
* inbound mark used for this child_sa
*/
mark_t mark_in;
@@ -228,6 +240,12 @@ METHOD(child_sa_t, get_reqid, u_int32_t,
return this->reqid;
}
+METHOD(child_sa_t, get_unique_id, u_int32_t,
+ private_child_sa_t *this)
+{
+ return this->unique_id;
+}
+
METHOD(child_sa_t, get_config, child_cfg_t*,
private_child_sa_t *this)
{
@@ -602,7 +620,7 @@ METHOD(child_sa_t, alloc_spi, u_int32_t,
{
if (hydra->kernel_interface->get_spi(hydra->kernel_interface,
this->other_addr, this->my_addr,
- proto_ike2ip(protocol), this->reqid,
+ proto_ike2ip(protocol),
&this->my_spi) == SUCCESS)
{
/* if we allocate a SPI, but then are unable to establish the SA, we
@@ -618,7 +636,7 @@ METHOD(child_sa_t, alloc_cpi, u_int16_t,
{
if (hydra->kernel_interface->get_cpi(hydra->kernel_interface,
this->other_addr, this->my_addr,
- this->reqid, &this->my_cpi) == SUCCESS)
+ &this->my_cpi) == SUCCESS)
{
return this->my_cpi;
}
@@ -632,7 +650,7 @@ METHOD(child_sa_t, install, status_t,
{
u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
u_int16_t esn = NO_EXT_SEQ_NUMBERS;
- traffic_selector_t *src_ts = NULL, *dst_ts = NULL;
+ linked_list_t *src_ts = NULL, *dst_ts = NULL;
time_t now;
lifetime_cfg_t *lifetime;
u_int32_t tfc = 0;
@@ -680,6 +698,18 @@ METHOD(child_sa_t, install, status_t,
this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS,
&esn, NULL);
+ if (!this->reqid_allocated)
+ {
+ status = hydra->kernel_interface->alloc_reqid(hydra->kernel_interface,
+ my_ts, other_ts, this->mark_in, this->mark_out,
+ &this->reqid);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ this->reqid_allocated = TRUE;
+ }
+
lifetime = this->config->get_lifetime(this->config);
now = time_monotonic(NULL);
@@ -704,18 +734,16 @@ METHOD(child_sa_t, install, status_t,
lifetime->time.rekey = 0;
}
- /* BEET requires the bound address from the traffic selectors.
- * TODO: We add just the first traffic selector for now, as the
- * kernel accepts a single TS per SA only */
+ /* BEET requires the bound address from the traffic selectors */
if (inbound)
{
- my_ts->get_first(my_ts, (void**)&dst_ts);
- other_ts->get_first(other_ts, (void**)&src_ts);
+ dst_ts = my_ts;
+ src_ts = other_ts;
}
else
{
- my_ts->get_first(my_ts, (void**)&src_ts);
- other_ts->get_first(other_ts, (void**)&dst_ts);
+ src_ts = my_ts;
+ dst_ts = other_ts;
}
status = hydra->kernel_interface->add_sa(hydra->kernel_interface,
@@ -723,7 +751,7 @@ METHOD(child_sa_t, install, status_t,
inbound ? this->mark_in : this->mark_out, tfc,
lifetime, enc_alg, encr, int_alg, integ, this->mode,
this->ipcomp, cpi, this->config->get_replay_window(this->config),
- initiator, this->encap, esn, update, src_ts, dst_ts);
+ initiator, this->encap, esn, inbound, update, src_ts, dst_ts);
free(lifetime);
@@ -798,6 +826,19 @@ METHOD(child_sa_t, add_policies, status_t,
traffic_selector_t *my_ts, *other_ts;
status_t status = SUCCESS;
+ if (!this->reqid_allocated)
+ {
+ /* trap policy, get or confirm reqid */
+ status = hydra->kernel_interface->alloc_reqid(
+ hydra->kernel_interface, my_ts_list, other_ts_list,
+ this->mark_in, this->mark_out, &this->reqid);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ this->reqid_allocated = TRUE;
+ }
+
/* apply traffic selectors */
enumerator = my_ts_list->create_enumerator(my_ts_list);
while (enumerator->enumerate(enumerator, &my_ts))
@@ -805,12 +846,15 @@ METHOD(child_sa_t, add_policies, status_t,
array_insert(this->my_ts, ARRAY_TAIL, my_ts->clone(my_ts));
}
enumerator->destroy(enumerator);
+ array_sort(this->my_ts, (void*)traffic_selector_cmp, NULL);
+
enumerator = other_ts_list->create_enumerator(other_ts_list);
while (enumerator->enumerate(enumerator, &other_ts))
{
array_insert(this->other_ts, ARRAY_TAIL, other_ts->clone(other_ts));
}
enumerator->destroy(enumerator);
+ array_sort(this->other_ts, (void*)traffic_selector_cmp, NULL);
if (this->config->install_policy(this->config))
{
@@ -1071,6 +1115,22 @@ METHOD(child_sa_t, destroy, void,
set_state(this, CHILD_DESTROYING);
+ if (this->config->install_policy(this->config))
+ {
+ /* delete all policies in the kernel */
+ enumerator = create_policy_enumerator(this);
+ while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
+ {
+ del_policies_internal(this, my_ts, other_ts, priority);
+ if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update())
+ {
+ del_policies_internal(this, my_ts, other_ts,
+ POLICY_PRIORITY_FALLBACK);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
/* delete SAs in the kernel, if they are set up */
if (this->my_spi)
{
@@ -1087,20 +1147,13 @@ METHOD(child_sa_t, destroy, void,
this->mark_out);
}
- if (this->config->install_policy(this->config))
+ if (this->reqid_allocated)
{
- /* delete all policies in the kernel */
- enumerator = create_policy_enumerator(this);
- while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
+ if (hydra->kernel_interface->release_reqid(hydra->kernel_interface,
+ this->reqid, this->mark_in, this->mark_out) != SUCCESS)
{
- del_policies_internal(this, my_ts, other_ts, priority);
- if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update())
- {
- del_policies_internal(this, my_ts, other_ts,
- POLICY_PRIORITY_FALLBACK);
- }
+ DBG1(DBG_CHD, "releasing reqid %u failed", this->reqid);
}
- enumerator->destroy(enumerator);
}
array_destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
@@ -1151,15 +1204,17 @@ static host_t* get_proxy_addr(child_cfg_t *config, host_t *ike, bool local)
* Described in header.
*/
child_sa_t * child_sa_create(host_t *me, host_t* other,
- child_cfg_t *config, u_int32_t rekey, bool encap)
+ child_cfg_t *config, u_int32_t rekey, bool encap,
+ u_int mark_in, u_int mark_out)
{
- static refcount_t reqid = 0;
private_child_sa_t *this;
+ static refcount_t unique_id = 0, unique_mark = 0, mark;
INIT(this,
.public = {
.get_name = _get_name,
.get_reqid = _get_reqid,
+ .get_unique_id = _get_unique_id,
.get_config = _get_config,
.get_state = _get_state,
.set_state = _set_state,
@@ -1201,6 +1256,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
.close_action = config->get_close_action(config),
.dpd_action = config->get_dpd_action(config),
.reqid = config->get_reqid(config),
+ .unique_id = ref_get(&unique_id),
.mark_in = config->get_mark(config, TRUE),
.mark_out = config->get_mark(config, FALSE),
.install_time = time_monotonic(NULL),
@@ -1209,9 +1265,37 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->config = config;
config->get_ref(config);
+ if (mark_in)
+ {
+ this->mark_in.value = mark_in;
+ }
+ if (mark_out)
+ {
+ this->mark_out.value = mark_out;
+ }
+ if (this->mark_in.value == MARK_UNIQUE ||
+ this->mark_out.value == MARK_UNIQUE)
+ {
+ mark = ref_get(&unique_mark);
+ if (this->mark_in.value == MARK_UNIQUE)
+ {
+ this->mark_in.value = mark;
+ }
+ if (this->mark_out.value == MARK_UNIQUE)
+ {
+ this->mark_out.value = mark;
+ }
+ }
+
if (!this->reqid)
{
- /* reuse old reqid if we are rekeying an existing CHILD_SA */
+ /* reuse old reqid if we are rekeying an existing CHILD_SA. While the
+ * reqid cache would find the same reqid for our selectors, this does
+ * not work in a special case: If an SA is triggered by a trap policy,
+ * but the negotiated SA gets narrowed, we still must reuse the same
+ * reqid to successfully "trigger" the SA on the kernel level. Rekeying
+ * such an SA requires an explicit reqid, as the cache currently knows
+ * the original selectors only for that reqid. */
if (rekey)
{
this->reqid = rekey;
@@ -1219,22 +1303,9 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
else
{
this->reqid = charon->traps->find_reqid(charon->traps, config);
- if (!this->reqid)
- {
- this->reqid = ref_get(&reqid);
- }
}
}
- if (this->mark_in.value == MARK_REQID)
- {
- this->mark_in.value = this->reqid;
- }
- if (this->mark_out.value == MARK_REQID)
- {
- this->mark_out.value = this->reqid;
- }
-
/* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
if (config->get_mode(config) == MODE_TRANSPORT &&
config->use_proxy_mode(config))
diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h
index a0c6c357f..debe8eb2c 100644
--- a/src/libcharon/sa/child_sa.h
+++ b/src/libcharon/sa/child_sa.h
@@ -68,6 +68,16 @@ enum child_sa_state_t {
CHILD_REKEYING,
/**
+ * CHILD_SA that was rekeyed, but stays installed
+ */
+ CHILD_REKEYED,
+
+ /**
+ * CHILD_SA negotiation failed, but gets retried
+ */
+ CHILD_RETRYING,
+
+ /**
* CHILD_SA in progress of delete
*/
CHILD_DELETING,
@@ -121,6 +131,16 @@ struct child_sa_t {
u_int32_t (*get_reqid)(child_sa_t *this);
/**
+ * Get the unique numerical identifier for this CHILD_SA.
+ *
+ * While the same reqid might be shared between multiple SAs, the unique_id
+ * is truly unique for all CHILD_SA instances.
+ *
+ * @return unique CHILD_SA identifier
+ */
+ u_int32_t (*get_unique_id)(child_sa_t *this);
+
+ /**
* Get the config used to set up this child sa.
*
* @return child_cfg
@@ -379,9 +399,12 @@ struct child_sa_t {
* @param config config to use for this CHILD_SA
* @param reqid reqid of old CHILD_SA when rekeying, 0 otherwise
* @param encap TRUE to enable UDP encapsulation (NAT traversal)
+ * @param mark_in explicit inbound mark value to use, 0 for config
+ * @param mark_out explicit outbound mark value to use, 0 for config
* @return child_sa_t object
*/
child_sa_t * child_sa_create(host_t *me, host_t *other, child_cfg_t *config,
- u_int32_t reqid, bool encap);
+ u_int32_t reqid, bool encap,
+ u_int mark_in, u_int mark_out);
#endif /** CHILD_SA_H_ @}*/
diff --git a/src/libcharon/sa/child_sa_manager.c b/src/libcharon/sa/child_sa_manager.c
new file mode 100644
index 000000000..071a119da
--- /dev/null
+++ b/src/libcharon/sa/child_sa_manager.c
@@ -0,0 +1,333 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "child_sa_manager.h"
+
+#include <daemon.h>
+#include <threading/mutex.h>
+#include <collections/hashtable.h>
+
+typedef struct private_child_sa_manager_t private_child_sa_manager_t;
+
+/**
+ * Private data of an child_sa_manager_t object.
+ */
+struct private_child_sa_manager_t {
+
+ /**
+ * Public child_sa_manager_t interface.
+ */
+ child_sa_manager_t public;
+
+ /**
+ * CHILD_SAs by inbound SPI/dst, child_entry_t => child_entry_t
+ */
+ hashtable_t *in;
+
+ /**
+ * CHILD_SAs by outbound SPI/dst, child_entry_t => child_entry_t
+ */
+ hashtable_t *out;
+
+ /**
+ * CHILD_SAs by unique ID, child_entry_t => child_entry_t
+ */
+ hashtable_t *ids;
+
+ /**
+ * Mutex to access any hashtable
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Hashtable entry for a known CHILD_SA
+ */
+typedef struct {
+ /** the associated IKE_SA */
+ ike_sa_id_t *ike_id;
+ /** unique CHILD_SA identifier */
+ u_int32_t unique_id;
+ /** inbound SPI */
+ u_int32_t spi_in;
+ /** outbound SPI */
+ u_int32_t spi_out;
+ /** inbound host address */
+ host_t *host_in;
+ /** outbound host address and port */
+ host_t *host_out;
+ /** IPsec protocol, AH|ESP */
+ protocol_id_t proto;
+} child_entry_t;
+
+/**
+ * Destroy a CHILD_SA entry
+ */
+static void child_entry_destroy(child_entry_t *entry)
+{
+ entry->ike_id->destroy(entry->ike_id);
+ entry->host_in->destroy(entry->host_in);
+ entry->host_out->destroy(entry->host_out);
+ free(entry);
+}
+
+/**
+ * Hashtable hash function for inbound SAs
+ */
+static u_int hash_in(child_entry_t *entry)
+{
+ return chunk_hash_inc(chunk_from_thing(entry->spi_in),
+ chunk_hash_inc(entry->host_in->get_address(entry->host_in),
+ chunk_hash(chunk_from_thing(entry->proto))));
+}
+
+/**
+ * Hashtable equals function for inbound SAs
+ */
+static bool equals_in(child_entry_t *a, child_entry_t *b)
+{
+ return a->spi_in == b->spi_in &&
+ a->proto == b->proto &&
+ a->host_in->ip_equals(a->host_in, b->host_in);
+}
+
+/**
+ * Hashtable hash function for outbound SAs
+ */
+static u_int hash_out(child_entry_t *entry)
+{
+ return chunk_hash_inc(chunk_from_thing(entry->spi_out),
+ chunk_hash_inc(entry->host_out->get_address(entry->host_out),
+ chunk_hash(chunk_from_thing(entry->proto))));
+}
+
+/**
+ * Hashtable equals function for outbound SAs
+ */
+static bool equals_out(child_entry_t *a, child_entry_t *b)
+{
+ return a->spi_out == b->spi_out &&
+ a->proto == b->proto &&
+ a->host_out->ip_equals(a->host_out, b->host_out);
+}
+
+/**
+ * Hashtable hash function for SAs by unique ID
+ */
+static u_int hash_id(child_entry_t *entry)
+{
+ return chunk_hash(chunk_from_thing(entry->unique_id));
+}
+
+/**
+ * Hashtable equals function for SAs by unique ID
+ */
+static bool equals_id(child_entry_t *a, child_entry_t *b)
+{
+ return a->unique_id == b->unique_id;
+}
+
+METHOD(child_sa_manager_t, add, void,
+ private_child_sa_manager_t *this, child_sa_t *child_sa, ike_sa_t *ike_sa)
+{
+ child_entry_t *entry;
+ host_t *in, *out;
+ ike_sa_id_t *id;
+
+ id = ike_sa->get_id(ike_sa);
+ in = ike_sa->get_my_host(ike_sa);
+ out = ike_sa->get_other_host(ike_sa);
+
+ INIT(entry,
+ .ike_id = id->clone(id),
+ .unique_id = child_sa->get_unique_id(child_sa),
+ .proto = child_sa->get_protocol(child_sa),
+ .spi_in = child_sa->get_spi(child_sa, TRUE),
+ .spi_out = child_sa->get_spi(child_sa, FALSE),
+ .host_in = in->clone(in),
+ .host_out = out->clone(out),
+ );
+
+ this->mutex->lock(this->mutex);
+ if (!this->in->get(this->in, entry) &&
+ !this->out->get(this->out, entry))
+ {
+ this->in->put(this->in, entry, entry);
+ this->out->put(this->out, entry, entry);
+ entry = this->ids->put(this->ids, entry, entry);
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (entry)
+ {
+ child_entry_destroy(entry);
+ }
+}
+
+METHOD(child_sa_manager_t, remove_, void,
+ private_child_sa_manager_t *this, child_sa_t *child_sa)
+{
+ child_entry_t *entry, key = {
+ .unique_id = child_sa->get_unique_id(child_sa),
+ };
+
+ this->mutex->lock(this->mutex);
+ entry = this->ids->remove(this->ids, &key);
+ if (entry)
+ {
+ this->in->remove(this->in, entry);
+ this->out->remove(this->out, entry);
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (entry)
+ {
+ child_entry_destroy(entry);
+ }
+}
+
+/**
+ * Check out an IKE_SA for a given CHILD_SA
+ */
+static ike_sa_t *checkout_ikesa(private_child_sa_manager_t *this,
+ ike_sa_id_t *id, u_int32_t unique_id, child_sa_t **child_sa)
+{
+ enumerator_t *enumerator;
+ child_sa_t *current;
+ ike_sa_t *ike_sa;
+ bool found = FALSE;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id);
+ id->destroy(id);
+ if (ike_sa)
+ {
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ found = current->get_unique_id(current) == unique_id;
+ if (found)
+ {
+ if (child_sa)
+ {
+ *child_sa = current;
+ }
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (found)
+ {
+ return ike_sa;
+ }
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ return NULL;
+}
+
+METHOD(child_sa_manager_t, checkout_by_id, ike_sa_t*,
+ private_child_sa_manager_t *this, u_int32_t unique_id,
+ child_sa_t **child_sa)
+{
+ ike_sa_id_t *id;
+ child_entry_t *entry, key = {
+ .unique_id = unique_id,
+ };
+
+ this->mutex->lock(this->mutex);
+ entry = this->ids->get(this->ids, &key);
+ if (entry)
+ {
+ id = entry->ike_id->clone(entry->ike_id);
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (entry)
+ {
+ return checkout_ikesa(this, id, unique_id, child_sa);
+ }
+ return NULL;
+}
+
+METHOD(child_sa_manager_t, checkout, ike_sa_t*,
+ private_child_sa_manager_t *this, protocol_id_t protocol, u_int32_t spi,
+ host_t *dst, child_sa_t **child_sa)
+{
+ ike_sa_id_t *id;
+ u_int32_t unique_id;
+ child_entry_t *entry, key = {
+ .spi_in = spi,
+ .spi_out = spi,
+ .host_in = dst,
+ .host_out = dst,
+ .proto = protocol,
+ };
+
+ this->mutex->lock(this->mutex);
+ entry = this->in->get(this->in, &key);
+ if (!entry)
+ {
+ entry = this->out->get(this->out, &key);
+ }
+ if (entry)
+ {
+ unique_id = entry->unique_id;
+ id = entry->ike_id->clone(entry->ike_id);
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (entry)
+ {
+ return checkout_ikesa(this, id, unique_id, child_sa);
+ }
+ return NULL;
+}
+
+METHOD(child_sa_manager_t, destroy, void,
+ private_child_sa_manager_t *this)
+{
+ this->in->destroy(this->in);
+ this->out->destroy(this->out);
+ this->ids->destroy(this->ids);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+child_sa_manager_t *child_sa_manager_create()
+{
+ private_child_sa_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add = _add,
+ .remove = _remove_,
+ .checkout = _checkout,
+ .checkout_by_id = _checkout_by_id,
+ .destroy = _destroy,
+ },
+ .in = hashtable_create((hashtable_hash_t)hash_in,
+ (hashtable_equals_t)equals_in, 8),
+ .out = hashtable_create((hashtable_hash_t)hash_out,
+ (hashtable_equals_t)equals_out, 8),
+ .ids = hashtable_create((hashtable_hash_t)hash_id,
+ (hashtable_equals_t)equals_id, 8),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/sa/child_sa_manager.h b/src/libcharon/sa/child_sa_manager.h
new file mode 100644
index 000000000..4d57528e8
--- /dev/null
+++ b/src/libcharon/sa/child_sa_manager.h
@@ -0,0 +1,89 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup child_sa_manager child_sa_manager
+ * @{ @ingroup sa
+ */
+
+#ifndef CHILD_SA_MANAGER_H_
+#define CHILD_SA_MANAGER_H_
+
+#include <sa/ike_sa.h>
+#include <sa/child_sa.h>
+
+typedef struct child_sa_manager_t child_sa_manager_t;
+
+/**
+ * Handle CHILD_SA to IKE_SA relations
+ */
+struct child_sa_manager_t {
+
+ /**
+ * Register a CHILD_SA/IKE_SA relation.
+ *
+ * @param child_sa CHILD_SA to register
+ * @param ike_sa IKE_SA owning the CHILD_SA
+ */
+ void (*add)(child_sa_manager_t *this, child_sa_t *child_sa, ike_sa_t *ike_sa);
+
+ /**
+ * Unregister a CHILD_SA/IKE_SA relation.
+ *
+ * @param child_sa CHILD_SA to unregister
+ */
+ void (*remove)(child_sa_manager_t *this, child_sa_t *child_sa);
+
+ /**
+ * Find a CHILD_SA and check out the associated IKE_SA by SPI.
+ *
+ * On success, the returned IKE_SA must be checked in after use to
+ * the IKE_SA manager.
+ *
+ * @param protocol IPsec protocol, AH|ESP
+ * @param spi SPI of CHILD_SA to check out
+ * @param dst SA destination host related to SPI
+ * @param child_sa returns CHILD_SA managed by IKE_SA
+ * @return IKE_SA, NULL if not found
+ */
+ ike_sa_t *(*checkout)(child_sa_manager_t *this,
+ protocol_id_t protocol, u_int32_t spi, host_t *dst,
+ child_sa_t **child_sa);
+
+ /**
+ * Find a CHILD_SA and check out the associated IKE_SA by unique_id.
+ *
+ * On success, the returned IKE_SA must be checked in after use to
+ * the IKE_SA manager.
+ *
+ * @param unique_id unique ID of CHILD_SA to check out
+ * @param child_sa returns CHILD_SA managed by IKE_SA
+ * @return IKE_SA, NULL if not found
+ */
+ ike_sa_t *(*checkout_by_id)(child_sa_manager_t *this, u_int32_t unique_id,
+ child_sa_t **child_sa);
+
+ /**
+ * Destroy a child_sa_manager_t.
+ */
+ void (*destroy)(child_sa_manager_t *this);
+};
+
+/**
+ * Create a child_sa_manager instance.
+ */
+child_sa_manager_t *child_sa_manager_create();
+
+#endif /** CHILD_SA_MANAGER_H_ @}*/
diff --git a/src/libcharon/sa/eap/eap_method.h b/src/libcharon/sa/eap/eap_method.h
index 6242a5a6e..689c0f990 100644
--- a/src/libcharon/sa/eap/eap_method.h
+++ b/src/libcharon/sa/eap/eap_method.h
@@ -137,6 +137,18 @@ struct eap_method_t {
void (*set_identifier) (eap_method_t *this, u_int8_t identifier);
/**
+ * Get authentication details performed by this EAP method.
+ *
+ * After EAP completion, the auth data contains additional information
+ * of the authentication process, used certificates etc.
+ * This method is optional to implement, but if it is, it must return
+ * a valid auth_cfg.
+ *
+ * @return auth method, internal data
+ */
+ auth_cfg_t* (*get_auth)(eap_method_t *this);
+
+ /**
* Destroys a eap_method_t object.
*/
void (*destroy) (eap_method_t *this);
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index d92b9df8e..3aafa4c13 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -932,6 +932,7 @@ METHOD(ike_sa_t, update_hosts, void,
/* update our address in any case */
if (force && !me->equals(me, this->my_host))
{
+ charon->bus->ike_update(charon->bus, &this->public, TRUE, me);
set_my_host(this, me->clone(me));
update = TRUE;
}
@@ -945,6 +946,7 @@ METHOD(ike_sa_t, update_hosts, void,
(!has_condition(this, COND_NAT_HERE) ||
!has_condition(this, COND_ORIGINAL_INITIATOR)))
{
+ charon->bus->ike_update(charon->bus, &this->public, FALSE, other);
set_other_host(this, other->clone(other));
update = TRUE;
}
@@ -964,6 +966,10 @@ METHOD(ike_sa_t, update_hosts, void,
enumerator = array_create_enumerator(this->child_sas);
while (enumerator->enumerate(enumerator, &child_sa))
{
+ charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
+ charon->child_sa_manager->add(charon->child_sa_manager,
+ child_sa, &this->public);
+
if (child_sa->update(child_sa, this->my_host, this->other_host,
vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
{
@@ -971,6 +977,7 @@ METHOD(ike_sa_t, update_hosts, void,
child_sa->get_protocol(child_sa),
child_sa->get_spi(child_sa, TRUE));
}
+
}
enumerator->destroy(enumerator);
@@ -1444,6 +1451,8 @@ METHOD(ike_sa_t, add_child_sa, void,
private_ike_sa_t *this, child_sa_t *child_sa)
{
array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa);
+ charon->child_sa_manager->add(charon->child_sa_manager,
+ child_sa, &this->public);
}
METHOD(ike_sa_t, get_child_sa, child_sa_t*,
@@ -1471,16 +1480,58 @@ METHOD(ike_sa_t, get_child_count, int,
return array_count(this->child_sas);
}
+/**
+ * Private data of a create_child_sa_enumerator()
+ */
+typedef struct {
+ /** implements enumerator */
+ enumerator_t public;
+ /** inner array enumerator */
+ enumerator_t *inner;
+ /** current item */
+ child_sa_t *current;
+} child_enumerator_t;
+
+METHOD(enumerator_t, child_enumerate, bool,
+ child_enumerator_t *this, child_sa_t **child_sa)
+{
+ if (this->inner->enumerate(this->inner, &this->current))
+ {
+ *child_sa = this->current;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(enumerator_t, child_enumerator_destroy, void,
+ child_enumerator_t *this)
+{
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*,
private_ike_sa_t *this)
{
- return array_create_enumerator(this->child_sas);
+ child_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_child_enumerate,
+ .destroy = _child_enumerator_destroy,
+ },
+ .inner = array_create_enumerator(this->child_sas),
+ );
+ return &enumerator->public;
}
METHOD(ike_sa_t, remove_child_sa, void,
private_ike_sa_t *this, enumerator_t *enumerator)
{
- array_remove_at(this->child_sas, enumerator);
+ child_enumerator_t *ce = (child_enumerator_t*)enumerator;
+
+ charon->child_sa_manager->remove(charon->child_sa_manager, ce->current);
+ array_remove_at(this->child_sas, ce->inner);
}
METHOD(ike_sa_t, rekey_child_sa, status_t,
@@ -1513,13 +1564,13 @@ METHOD(ike_sa_t, destroy_child_sa, status_t,
child_sa_t *child_sa;
status_t status = NOT_FOUND;
- enumerator = array_create_enumerator(this->child_sas);
+ enumerator = create_child_sa_enumerator(this);
while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (child_sa->get_protocol(child_sa) == protocol &&
child_sa->get_spi(child_sa, TRUE) == spi)
{
- array_remove_at(this->child_sas, enumerator);
+ remove_child_sa(this, enumerator);
child_sa->destroy(child_sa);
status = SUCCESS;
break;
@@ -1771,7 +1822,7 @@ METHOD(ike_sa_t, reestablish, status_t,
#endif /* ME */
{
/* handle existing CHILD_SAs */
- enumerator = array_create_enumerator(this->child_sas);
+ enumerator = create_child_sa_enumerator(this);
while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (has_condition(this, COND_REAUTHENTICATING))
@@ -1780,7 +1831,7 @@ METHOD(ike_sa_t, reestablish, status_t,
{
case CHILD_ROUTED:
{ /* move routed child directly */
- array_remove_at(this->child_sas, enumerator);
+ remove_child_sa(this, enumerator);
new->add_child_sa(new, child_sa);
action = ACTION_NONE;
break;
@@ -2209,6 +2260,12 @@ METHOD(ike_sa_t, inherit_post, void,
array_insert_create(&this->other_vips, ARRAY_TAIL, vip);
}
+ /* MOBIKE additional addresses */
+ while (array_remove(other->peer_addresses, ARRAY_HEAD, &vip))
+ {
+ array_insert_create(&this->peer_addresses, ARRAY_TAIL, vip);
+ }
+
/* authentication information */
enumerator = array_create_enumerator(other->my_auths);
while (enumerator->enumerate(enumerator, &cfg))
@@ -2251,7 +2308,8 @@ METHOD(ike_sa_t, inherit_post, void,
/* adopt all children */
while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa))
{
- array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa);
+ charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
+ add_child_sa(this, child_sa);
}
/* move pending tasks to the new IKE_SA */
@@ -2296,8 +2354,8 @@ METHOD(ike_sa_t, destroy, void,
{
if (entry.handler)
{
- hydra->attributes->release(hydra->attributes, entry.handler,
- this->other_id, entry.type, entry.data);
+ charon->attributes->release(charon->attributes, entry.handler,
+ &this->public, entry.type, entry.data);
}
free(entry.data.ptr);
}
@@ -2305,6 +2363,7 @@ METHOD(ike_sa_t, destroy, void,
* routes that the CHILD_SA tries to uninstall. */
while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa))
{
+ charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
child_sa->destroy(child_sa);
}
while (array_remove(this->my_vips, ARRAY_TAIL, &vip))
@@ -2321,12 +2380,11 @@ METHOD(ike_sa_t, destroy, void,
if (this->peer_cfg)
{
linked_list_t *pools;
- identification_t *id;
- id = get_other_eap_id(this);
pools = linked_list_create_from_enumerator(
this->peer_cfg->create_pool_enumerator(this->peer_cfg));
- hydra->attributes->release_address(hydra->attributes, pools, vip, id);
+ charon->attributes->release_address(charon->attributes,
+ pools, vip, &this->public);
pools->destroy(pools);
}
vip->destroy(vip);
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index c72d87367..9dbc805c9 100644
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -131,6 +131,11 @@ enum ike_extension_t {
* peer supports proprietary IKEv1 or standardized IKEv2 fragmentation
*/
EXT_IKE_FRAGMENTATION = (1<<11),
+
+ /**
+ * Signature Authentication, RFC 7427
+ */
+ EXT_SIGNATURE_AUTH = (1<<12),
};
/**
@@ -936,8 +941,9 @@ struct ike_sa_t {
/**
* Reauthenticate the IKE_SA.
*
- * Create a completely new IKE_SA with authentication, recreates all children
- * within the IKE_SA, closes this IKE_SA.
+ * Triggers a new IKE_SA that replaces this one. IKEv1 implicitly inherits
+ * all Quick Modes, while IKEv2 recreates all active and queued CHILD_SAs
+ * in the new IKE_SA.
*
* @return DESTROY_ME to destroy the IKE_SA
*/
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index bdabc59b5..13fc74ff7 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -1184,7 +1184,8 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*,
DBG2(DBG_MGR, "checkout IKE_SA by message");
- if (id->get_responder_spi(id) == 0)
+ if (id->get_responder_spi(id) == 0 &&
+ message->get_message_id(message) == 0)
{
if (message->get_major_version(message) == IKEV2_MAJOR_VERSION)
{
@@ -1383,54 +1384,35 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
}
METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
- private_ike_sa_manager_t *this, u_int32_t id, bool child)
+ private_ike_sa_manager_t *this, u_int32_t id)
{
- enumerator_t *enumerator, *children;
+ enumerator_t *enumerator;
entry_t *entry;
ike_sa_t *ike_sa = NULL;
- child_sa_t *child_sa;
u_int segment;
- DBG2(DBG_MGR, "checkout IKE_SA by ID");
+ DBG2(DBG_MGR, "checkout IKE_SA by ID %u", id);
enumerator = create_table_enumerator(this);
while (enumerator->enumerate(enumerator, &entry, &segment))
{
if (wait_for_entry(this, entry, segment))
{
- /* look for a child with such a reqid ... */
- if (child)
- {
- children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa);
- while (children->enumerate(children, (void**)&child_sa))
- {
- if (child_sa->get_reqid(child_sa) == id)
- {
- ike_sa = entry->ike_sa;
- break;
- }
- }
- children->destroy(children);
- }
- else /* ... or for a IKE_SA with such a unique id */
- {
- if (entry->ike_sa->get_unique_id(entry->ike_sa) == id)
- {
- ike_sa = entry->ike_sa;
- }
- }
- /* got one, return */
- if (ike_sa)
+ if (entry->ike_sa->get_unique_id(entry->ike_sa) == id)
{
+ ike_sa = entry->ike_sa;
entry->checked_out = TRUE;
- DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
- ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
break;
}
}
}
enumerator->destroy(enumerator);
+ if (ike_sa)
+ {
+ DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
+ ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
+ }
charon->bus->set_sa(charon->bus, ike_sa);
return ike_sa;
}
@@ -1746,29 +1728,45 @@ METHOD(ike_sa_manager_t, create_id_enumerator, enumerator_t*,
}
/**
- * Move all CHILD_SAs from old to new
+ * Move all CHILD_SAs and virtual IPs from old to new
*/
-static void adopt_children(ike_sa_t *old, ike_sa_t *new)
+static void adopt_children_and_vips(ike_sa_t *old, ike_sa_t *new)
{
enumerator_t *enumerator;
child_sa_t *child_sa;
+ host_t *vip;
+ int chcount = 0, vipcount = 0;
+
enumerator = old->create_child_sa_enumerator(old);
while (enumerator->enumerate(enumerator, &child_sa))
{
old->remove_child_sa(old, enumerator);
new->add_child_sa(new, child_sa);
+ chcount++;
}
enumerator->destroy(enumerator);
-}
-/**
- * Check if the replaced IKE_SA might get reauthenticated from host
- */
-static bool is_ikev1_reauth(ike_sa_t *duplicate, host_t *host)
-{
- return duplicate->get_version(duplicate) == IKEV1 &&
- host->equals(host, duplicate->get_other_host(duplicate));
+ enumerator = old->create_virtual_ip_enumerator(old, FALSE);
+ while (enumerator->enumerate(enumerator, &vip))
+ {
+ new->add_virtual_ip(new, FALSE, vip);
+ vipcount++;
+ }
+ enumerator->destroy(enumerator);
+ /* this does not release the addresses, which is good, but it does trigger
+ * an assign_vips(FALSE) event... */
+ old->clear_virtual_ips(old, FALSE);
+ /* ...trigger the analogous event on the new SA */
+ charon->bus->set_sa(charon->bus, new);
+ charon->bus->assign_vips(charon->bus, new, TRUE);
+ charon->bus->set_sa(charon->bus, old);
+
+ if (chcount || vipcount)
+ {
+ DBG1(DBG_IKE, "detected reauth of existing IKE_SA, adopting %d "
+ "children and %d virtual IPs", chcount, vipcount);
+ }
}
/**
@@ -1780,13 +1778,20 @@ static status_t enforce_replace(private_ike_sa_manager_t *this,
{
charon->bus->alert(charon->bus, ALERT_UNIQUE_REPLACE);
- if (is_ikev1_reauth(duplicate, host))
+ if (host->equals(host, duplicate->get_other_host(duplicate)))
{
/* looks like a reauthentication attempt */
- adopt_children(duplicate, new);
+ if (!new->has_condition(new, COND_INIT_CONTACT_SEEN) &&
+ new->get_version(new) == IKEV1)
+ {
+ /* IKEv1 implicitly takes over children, IKEv2 recreates them
+ * explicitly. */
+ adopt_children_and_vips(duplicate, new);
+ }
/* For IKEv1 we have to delay the delete for the old IKE_SA. Some
* peers need to complete the new SA first, otherwise the quick modes
- * might get lost. */
+ * might get lost. For IKEv2 we do the same, as we want overlapping
+ * CHILD_SAs to keep connectivity up. */
lib->scheduler->schedule_job(lib->scheduler, (job_t*)
delete_ike_sa_job_create(duplicate->get_id(duplicate), TRUE), 10);
return SUCCESS;
@@ -1851,7 +1856,9 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool,
other, other_host);
break;
case UNIQUE_KEEP:
- if (!is_ikev1_reauth(duplicate, other_host))
+ /* potential reauthentication? */
+ if (!other_host->equals(other_host,
+ duplicate->get_other_host(duplicate)))
{
cancel = TRUE;
/* we keep the first IKE_SA and delete all
diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h
index a68ae7763..f259d8e56 100644
--- a/src/libcharon/sa/ike_sa_manager.h
+++ b/src/libcharon/sa/ike_sa_manager.h
@@ -129,19 +129,15 @@ struct ike_sa_manager_t {
/**
* Check out an IKE_SA a unique ID.
*
- * Every IKE_SA and every CHILD_SA is uniquely identified by an ID.
- * These checkout function uses, depending
- * on the child parameter, the unique ID of the IKE_SA or the reqid
- * of one of a IKE_SAs CHILD_SA.
+ * Every IKE_SA is uniquely identified by a numerical ID. This checkout
+ * function uses the unique ID of the IKE_SA to check it out.
*
* @param id unique ID of the object
- * @param child TRUE to use CHILD, FALSE to use IKE_SA
* @return
* - checked out IKE_SA, if found
* - NULL, if not found
*/
- ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this, u_int32_t id,
- bool child);
+ ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this, u_int32_t id);
/**
* Check out an IKE_SA by the policy/connection name.
diff --git a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
index aa966cd5f..bb187f07c 100644
--- a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
+++ b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
@@ -74,7 +74,10 @@ METHOD(authenticator_t, build, status_t,
keymat_v1_t *keymat;
chunk_t hash, dh;
- this->dh->get_my_public_value(this->dh, &dh);
+ if (!this->dh->get_my_public_value(this->dh, &dh))
+ {
+ return FAILED;
+ }
keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value,
this->ike_sa->get_id(this->ike_sa), this->sa_payload,
@@ -108,7 +111,10 @@ METHOD(authenticator_t, process, status_t,
return FAILED;
}
- this->dh->get_my_public_value(this->dh, &dh);
+ if (!this->dh->get_my_public_value(this->dh, &dh))
+ {
+ return FAILED;
+ }
keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh,
this->ike_sa->get_id(this->ike_sa), this->sa_payload,
diff --git a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c
index bfe5ff449..52228ef2e 100644
--- a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c
+++ b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c
@@ -94,7 +94,11 @@ METHOD(authenticator_t, build, status_t,
return NOT_FOUND;
}
- this->dh->get_my_public_value(this->dh, &dh);
+ if (!this->dh->get_my_public_value(this->dh, &dh))
+ {
+ private->destroy(private);
+ return FAILED;
+ }
keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value,
this->ike_sa->get_id(this->ike_sa), this->sa_payload,
@@ -152,7 +156,10 @@ METHOD(authenticator_t, process, status_t,
}
id = this->ike_sa->get_other_id(this->ike_sa);
- this->dh->get_my_public_value(this->dh, &dh);
+ if (!this->dh->get_my_public_value(this->dh, &dh))
+ {
+ return FAILED;
+ }
keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh,
this->ike_sa->get_id(this->ike_sa), this->sa_payload,
diff --git a/src/libcharon/sa/ikev1/keymat_v1.c b/src/libcharon/sa/ikev1/keymat_v1.c
index 619d197bd..f5a91dbeb 100644
--- a/src/libcharon/sa/ikev1/keymat_v1.c
+++ b/src/libcharon/sa/ikev1/keymat_v1.c
@@ -425,7 +425,7 @@ METHOD(keymat_v1_t, derive_ike_keys, bool,
return FALSE;
}
- if (dh->get_shared_secret(dh, &g_xy) != SUCCESS)
+ if (!dh->get_shared_secret(dh, &g_xy))
{
return FALSE;
}
@@ -560,7 +560,10 @@ METHOD(keymat_v1_t, derive_ike_keys, bool,
return FALSE;
}
- dh->get_my_public_value(dh, &dh_me);
+ if (!dh->get_my_public_value(dh, &dh_me))
+ {
+ return FALSE;
+ }
g_xi = this->initiator ? dh_me : dh_other;
g_xr = this->initiator ? dh_other : dh_me;
@@ -661,7 +664,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
protocol = proposal->get_protocol(proposal);
if (dh)
{
- if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+ if (!dh->get_shared_secret(dh, &secret))
{
return FALSE;
}
diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c
index d01a831f8..c968b2a9c 100644
--- a/src/libcharon/sa/ikev1/phase1.c
+++ b/src/libcharon/sa/ikev1/phase1.c
@@ -694,7 +694,13 @@ METHOD(phase1_t, add_nonce_ke, bool,
nonce_gen_t *nonceg;
chunk_t nonce;
- ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, this->dh);
+ ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE,
+ this->dh);
+ if (!ke_payload)
+ {
+ DBG1(DBG_IKE, "creating KE payload failed");
+ return FALSE;
+ }
message->add_payload(message, &ke_payload->payload_interface);
nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
@@ -739,7 +745,11 @@ METHOD(phase1_t, get_nonce_ke, bool,
return FALSE;
}
this->dh_value = chunk_clone(ke_payload->get_key_exchange_data(ke_payload));
- this->dh->set_other_public_value(this->dh, this->dh_value);
+ if (!this->dh->set_other_public_value(this->dh, this->dh_value))
+ {
+ DBG1(DBG_IKE, "unable to apply received KE value");
+ return FALSE;
+ }
nonce_payload = (nonce_payload_t*)message->get_payload(message, PLV1_NONCE);
if (!nonce_payload)
diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c
index 0f8e8bc6d..cb22bf606 100644
--- a/src/libcharon/sa/ikev1/task_manager_v1.c
+++ b/src/libcharon/sa/ikev1/task_manager_v1.c
@@ -1596,7 +1596,8 @@ static bool is_redundant(private_task_manager_t *this, child_sa_t *child_sa)
child_sa->get_lifetime(child_sa, FALSE))
{
DBG1(DBG_IKE, "deleting redundant CHILD_SA %s{%d}",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
+ child_sa->get_name(child_sa),
+ child_sa->get_unique_id(child_sa));
redundant = TRUE;
break;
}
@@ -1647,6 +1648,8 @@ METHOD(task_manager_t, queue_child_rekey, void,
task = quick_mode_create(this->ike_sa, cfg->get_ref(cfg),
get_first_ts(child_sa, TRUE), get_first_ts(child_sa, FALSE));
task->use_reqid(task, child_sa->get_reqid(child_sa));
+ task->use_marks(task, child_sa->get_mark(child_sa, TRUE).value,
+ child_sa->get_mark(child_sa, FALSE).value);
task->rekey(task, child_sa->get_spi(child_sa, TRUE));
queue_task(this, &task->task);
diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_delete.c b/src/libcharon/sa/ikev1/tasks/isakmp_delete.c
index bea0428c4..a56805afb 100644
--- a/src/libcharon/sa/ikev1/tasks/isakmp_delete.c
+++ b/src/libcharon/sa/ikev1/tasks/isakmp_delete.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2011 Martin Willi
* Copyright (C) 2011 revosec AG
*
@@ -74,6 +77,42 @@ METHOD(task_t, process_i, status_t,
METHOD(task_t, process_r, status_t,
private_isakmp_delete_t *this, message_t *message)
{
+ enumerator_t *payloads;
+ payload_t *payload;
+ delete_payload_t *delete_payload;
+ ike_sa_id_t *id;
+ u_int64_t spi_i, spi_r;
+ bool found = FALSE;
+
+ /* some peers send DELETE payloads for other IKE_SAs, e.g. those for expired
+ * ones after a rekeyeing, make sure the SPIs match */
+ id = this->ike_sa->get_id(this->ike_sa);
+ payloads = message->create_payload_enumerator(message);
+ while (payloads->enumerate(payloads, &payload))
+ {
+ if (payload->get_type(payload) == PLV1_DELETE)
+ {
+ delete_payload = (delete_payload_t*)payload;
+ if (!delete_payload->get_ike_spi(delete_payload, &spi_i, &spi_r))
+ {
+ continue;
+ }
+ if (id->get_initiator_spi(id) == spi_i &&
+ id->get_responder_spi(id) == spi_r)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ payloads->destroy(payloads);
+
+ if (!found)
+ {
+ DBG1(DBG_IKE, "received DELETE for different IKE_SA, ignored");
+ return SUCCESS;
+ }
+
DBG1(DBG_IKE, "received DELETE for IKE_SA %s[%d]",
this->ike_sa->get_name(this->ike_sa),
this->ike_sa->get_unique_id(this->ike_sa));
diff --git a/src/libcharon/sa/ikev1/tasks/main_mode.c b/src/libcharon/sa/ikev1/tasks/main_mode.c
index 2fb4c6935..3ea4a2a85 100644
--- a/src/libcharon/sa/ikev1/tasks/main_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/main_mode.c
@@ -205,6 +205,43 @@ static status_t send_delete(private_main_mode_t *this)
return ALREADY_DONE;
}
+/**
+ * Add an INITIAL_CONTACT notify if first contact with peer
+ */
+static void add_initial_contact(private_main_mode_t *this, message_t *message,
+ identification_t *idi)
+{
+ identification_t *idr;
+ host_t *host;
+ notify_payload_t *notify;
+ ike_sa_id_t *ike_sa_id;
+ u_int64_t spi_i, spi_r;
+ chunk_t spi;
+
+ idr = this->ph1->get_id(this->ph1, this->peer_cfg, FALSE);
+ if (idr && !idr->contains_wildcards(idr))
+ {
+ if (this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NO &&
+ this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NEVER)
+ {
+ host = this->ike_sa->get_other_host(this->ike_sa);
+ if (!charon->ike_sa_manager->has_contact(charon->ike_sa_manager,
+ idi, idr, host->get_family(host)))
+ {
+ notify = notify_payload_create_from_protocol_and_type(
+ PLV1_NOTIFY, PROTO_IKE, INITIAL_CONTACT_IKEV1);
+ ike_sa_id = this->ike_sa->get_id(this->ike_sa);
+ spi_i = ike_sa_id->get_initiator_spi(ike_sa_id);
+ spi_r = ike_sa_id->get_responder_spi(ike_sa_id);
+ spi = chunk_cata("cc", chunk_from_thing(spi_i),
+ chunk_from_thing(spi_r));
+ notify->set_spi_data(notify, spi);
+ message->add_payload(message, (payload_t*)notify);
+ }
+ }
+ }
+}
+
METHOD(task_t, build_i, status_t,
private_main_mode_t *this, message_t *message)
{
@@ -311,6 +348,8 @@ METHOD(task_t, build_i, status_t,
return send_notify(this, AUTHENTICATION_FAILED);
}
+ add_initial_contact(this, message, id);
+
this->state = MM_AUTH;
return NEED_MORE;
}
diff --git a/src/libcharon/sa/ikev1/tasks/mode_config.c b/src/libcharon/sa/ikev1/tasks/mode_config.c
index 94026b9af..d0994a961 100644
--- a/src/libcharon/sa/ikev1/tasks/mode_config.c
+++ b/src/libcharon/sa/ikev1/tasks/mode_config.c
@@ -16,7 +16,6 @@
#include "mode_config.h"
#include <daemon.h>
-#include <hydra.h>
#include <encoding/payloads/cp_payload.h>
typedef struct private_mode_config_t private_mode_config_t;
@@ -136,9 +135,8 @@ static void handle_attribute(private_mode_config_t *this,
enumerator->destroy(enumerator);
/* and pass it to the handle function */
- handler = hydra->attributes->handle(hydra->attributes,
- this->ike_sa->get_other_id(this->ike_sa), handler,
- ca->get_type(ca), ca->get_chunk(ca));
+ handler = charon->attributes->handle(charon->attributes,
+ this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca));
this->ike_sa->add_configuration_attribute(this->ike_sa,
handler, ca->get_type(ca), ca->get_chunk(ca));
}
@@ -326,9 +324,8 @@ static status_t build_request(private_mode_config_t *this, message_t *message)
enumerator->destroy(enumerator);
}
- enumerator = hydra->attributes->create_initiator_enumerator(
- hydra->attributes,
- this->ike_sa->get_other_id(this->ike_sa), vips);
+ enumerator = charon->attributes->create_initiator_enumerator(
+ charon->attributes, this->ike_sa, vips);
while (enumerator->enumerate(enumerator, &handler, &type, &data))
{
add_attribute(this, cp, type, data, handler);
@@ -353,7 +350,7 @@ static status_t build_set(private_mode_config_t *this, message_t *message)
cp_payload_t *cp;
peer_cfg_t *config;
identification_t *id;
- linked_list_t *pools;
+ linked_list_t *pools, *migrated, *vips;
host_t *any4, *any6, *found;
char *name;
@@ -361,45 +358,62 @@ static status_t build_set(private_mode_config_t *this, message_t *message)
id = this->ike_sa->get_other_eap_id(this->ike_sa);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
- any4 = host_create_any(AF_INET);
- any6 = host_create_any(AF_INET6);
+ /* if we migrated virtual IPs during reauthentication, reassign them */
+ migrated = linked_list_create_from_enumerator(
+ this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
+ FALSE));
+ vips = migrated->clone_offset(migrated, offsetof(host_t, clone));
+ migrated->destroy(migrated);
this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
/* in push mode, we ask each configured pool for an address */
- enumerator = config->create_pool_enumerator(config);
- while (enumerator->enumerate(enumerator, &name))
+ if (!vips->get_count(vips))
{
- pools = linked_list_create_with_items(name, NULL);
- /* try IPv4, then IPv6 */
- found = hydra->attributes->acquire_address(hydra->attributes,
- pools, id, any4);
- if (!found)
- {
- found = hydra->attributes->acquire_address(hydra->attributes,
- pools, id, any6);
- }
- pools->destroy(pools);
- if (found)
+ any4 = host_create_any(AF_INET);
+ any6 = host_create_any(AF_INET6);
+ enumerator = config->create_pool_enumerator(config);
+ while (enumerator->enumerate(enumerator, &name))
{
- DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
- this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
- cp->add_attribute(cp, build_vip(found));
- this->vips->insert_last(this->vips, found);
+ pools = linked_list_create_with_items(name, NULL);
+ /* try IPv4, then IPv6 */
+ found = charon->attributes->acquire_address(charon->attributes,
+ pools, this->ike_sa, any4);
+ if (!found)
+ {
+ found = charon->attributes->acquire_address(charon->attributes,
+ pools, this->ike_sa, any6);
+ }
+ pools->destroy(pools);
+ if (found)
+ {
+ vips->insert_last(vips, found);
+ }
}
+ enumerator->destroy(enumerator);
+ any4->destroy(any4);
+ any6->destroy(any6);
}
- enumerator->destroy(enumerator);
- any4->destroy(any4);
- any6->destroy(any6);
+ enumerator = vips->create_enumerator(vips);
+ while (enumerator->enumerate(enumerator, &found))
+ {
+ DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
+ this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
+ cp->add_attribute(cp, build_vip(found));
+ this->vips->insert_last(this->vips, found);
+ vips->remove_at(vips, enumerator);
+ }
+ enumerator->destroy(enumerator);
+ vips->destroy(vips);
charon->bus->assign_vips(charon->bus, this->ike_sa, TRUE);
/* query registered providers for additional attributes to include */
pools = linked_list_create_from_enumerator(
config->create_pool_enumerator(config));
- enumerator = hydra->attributes->create_responder_enumerator(
- hydra->attributes, pools, id, this->vips);
+ enumerator = charon->attributes->create_responder_enumerator(
+ charon->attributes, pools, this->ike_sa, this->vips);
while (enumerator->enumerate(enumerator, &type, &value))
{
add_attribute(this, cp, type, value, NULL);
@@ -458,6 +472,28 @@ METHOD(task_t, process_r, status_t,
}
/**
+ * Assign a migrated virtual IP
+ */
+static host_t *assign_migrated_vip(linked_list_t *migrated, host_t *requested)
+{
+ enumerator_t *enumerator;
+ host_t *found = NULL, *vip;
+
+ enumerator = migrated->create_enumerator(migrated);
+ while (enumerator->enumerate(enumerator, &vip))
+ {
+ if (vip->ip_equals(vip, requested))
+ {
+ migrated->remove_at(migrated, enumerator);
+ found = vip;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+/**
* Build CFG_REPLY message after receiving CFG_REQUEST
*/
static status_t build_reply(private_mode_config_t *this, message_t *message)
@@ -468,29 +504,35 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
cp_payload_t *cp;
peer_cfg_t *config;
identification_t *id;
- linked_list_t *vips, *pools;
- host_t *requested;
+ linked_list_t *vips, *pools, *migrated;
+ host_t *requested, *found;
cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REPLY);
id = this->ike_sa->get_other_eap_id(this->ike_sa);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
- vips = linked_list_create();
pools = linked_list_create_from_enumerator(
config->create_pool_enumerator(config));
-
+ /* if we migrated virtual IPs during reauthentication, reassign them */
+ vips = linked_list_create_from_enumerator(
+ this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
+ FALSE));
+ migrated = vips->clone_offset(vips, offsetof(host_t, clone));
+ vips->destroy(vips);
this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
+ vips = linked_list_create();
enumerator = this->vips->create_enumerator(this->vips);
while (enumerator->enumerate(enumerator, &requested))
{
- host_t *found = NULL;
-
- /* query all pools until we get an address */
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
- found = hydra->attributes->acquire_address(hydra->attributes,
- pools, id, requested);
+ found = assign_migrated_vip(migrated, requested);
+ if (!found)
+ {
+ found = charon->attributes->acquire_address(charon->attributes,
+ pools, this->ike_sa, requested);
+ }
if (found)
{
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
@@ -509,8 +551,8 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
charon->bus->assign_vips(charon->bus, this->ike_sa, TRUE);
/* query registered providers for additional attributes to include */
- enumerator = hydra->attributes->create_responder_enumerator(
- hydra->attributes, pools, id, vips);
+ enumerator = charon->attributes->create_responder_enumerator(
+ charon->attributes, pools, this->ike_sa, vips);
while (enumerator->enumerate(enumerator, &type, &value))
{
cp->add_attribute(cp,
@@ -518,6 +560,15 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
type, value));
}
enumerator->destroy(enumerator);
+ /* if a client did not re-request all adresses, release them */
+ enumerator = migrated->create_enumerator(migrated);
+ while (enumerator->enumerate(enumerator, &found))
+ {
+ charon->attributes->release_address(charon->attributes,
+ pools, found, this->ike_sa);
+ }
+ enumerator->destroy(enumerator);
+ migrated->destroy_offset(migrated, offsetof(host_t, destroy));
vips->destroy_offset(vips, offsetof(host_t, destroy));
pools->destroy(pools);
diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.c b/src/libcharon/sa/ikev1/tasks/quick_delete.c
index 499081caa..1b95a8b11 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_delete.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_delete.c
@@ -105,7 +105,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
this->spi = spi = child_sa->get_spi(child_sa, TRUE);
}
- rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYING;
+ rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYED;
child_sa->set_state(child_sa, CHILD_DELETING);
my_ts = linked_list_create_from_enumerator(
@@ -116,7 +116,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
{
DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} "
"with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
ntohl(child_sa->get_spi(child_sa, TRUE)),
ntohl(child_sa->get_spi(child_sa, FALSE)), my_ts, other_ts);
}
@@ -127,7 +127,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs "
"%.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in,
ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out,
my_ts, other_ts);
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c
index 1133aab65..96edfd8d8 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c
@@ -156,6 +156,16 @@ struct private_quick_mode_t {
u_int32_t reqid;
/**
+ * Explicit inbound mark value to use, if any
+ */
+ u_int mark_in;
+
+ /**
+ * Explicit inbound mark value to use, if any
+ */
+ u_int mark_out;
+
+ /**
* SPI of SA we rekey
*/
u_int32_t rekey;
@@ -196,8 +206,8 @@ static void schedule_inactivity_timeout(private_quick_mode_t *this)
close_ike = lib->settings->get_bool(lib->settings,
"%s.inactivity_close_ike", FALSE, lib->ns);
lib->scheduler->schedule_job(lib->scheduler, (job_t*)
- inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
- timeout, close_ike), timeout);
+ inactivity_job_create(this->child_sa->get_unique_id(this->child_sa),
+ timeout, close_ike), timeout);
}
}
@@ -375,7 +385,7 @@ static bool install(private_quick_mode_t *this)
DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
"with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
this->child_sa->get_name(this->child_sa),
- this->child_sa->get_reqid(this->child_sa),
+ this->child_sa->get_unique_id(this->child_sa),
ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts);
@@ -391,15 +401,14 @@ static bool install(private_quick_mode_t *this)
if (old)
{
charon->bus->child_rekey(charon->bus, old, this->child_sa);
+ /* rekeyed CHILD_SAs stay installed until they expire */
+ old->set_state(old, CHILD_REKEYED);
}
else
{
charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
}
- if (!this->rekey)
- {
- schedule_inactivity_timeout(this);
- }
+ schedule_inactivity_timeout(this);
this->child_sa = NULL;
return TRUE;
}
@@ -456,12 +465,19 @@ static bool get_nonce(private_quick_mode_t *this, chunk_t *nonce,
/**
* Add KE payload to message
*/
-static void add_ke(private_quick_mode_t *this, message_t *message)
+static bool add_ke(private_quick_mode_t *this, message_t *message)
{
ke_payload_t *ke_payload;
- ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, this->dh);
+ ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE,
+ this->dh);
+ if (!ke_payload)
+ {
+ DBG1(DBG_IKE, "creating KE payload failed");
+ return FALSE;
+ }
message->add_payload(message, &ke_payload->payload_interface);
+ return TRUE;
}
/**
@@ -477,8 +493,12 @@ static bool get_ke(private_quick_mode_t *this, message_t *message)
DBG1(DBG_IKE, "KE payload missing");
return FALSE;
}
- this->dh->set_other_public_value(this->dh,
- ke_payload->get_key_exchange_data(ke_payload));
+ if (!this->dh->set_other_public_value(this->dh,
+ ke_payload->get_key_exchange_data(ke_payload)))
+ {
+ DBG1(DBG_IKE, "unable to apply received KE value");
+ return FALSE;
+ }
return TRUE;
}
@@ -788,7 +808,8 @@ METHOD(task_t, build_i, status_t,
this->child_sa = child_sa_create(
this->ike_sa->get_my_host(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa),
- this->config, this->reqid, this->udp);
+ this->config, this->reqid, this->udp,
+ this->mark_in, this->mark_out);
if (this->udp && this->mode == MODE_TRANSPORT)
{
@@ -870,7 +891,10 @@ METHOD(task_t, build_i, status_t,
}
if (group != MODP_NONE)
{
- add_ke(this, message);
+ if (!add_ke(this, message))
+ {
+ return FAILED;
+ }
}
if (!this->tsi)
{
@@ -964,6 +988,7 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
{
case CHILD_INSTALLED:
case CHILD_REKEYING:
+ case CHILD_REKEYED:
policies = child_sa->create_policy_enumerator(child_sa);
if (policies->enumerate(policies, &local, &remote) &&
local->equals(local, this->tsr) &&
@@ -972,9 +997,14 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
{
this->reqid = child_sa->get_reqid(child_sa);
this->rekey = child_sa->get_spi(child_sa, TRUE);
+ this->mark_in = child_sa->get_mark(child_sa,
+ TRUE).value;
+ this->mark_out = child_sa->get_mark(child_sa,
+ FALSE).value;
child_sa->set_state(child_sa, CHILD_REKEYING);
DBG1(DBG_IKE, "detected rekeying of CHILD_SA %s{%u}",
- child_sa->get_name(child_sa), this->reqid);
+ child_sa->get_name(child_sa),
+ child_sa->get_unique_id(child_sa));
}
policies->destroy(policies);
break;
@@ -1097,7 +1127,8 @@ METHOD(task_t, process_r, status_t,
this->child_sa = child_sa_create(
this->ike_sa->get_my_host(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa),
- this->config, this->reqid, this->udp);
+ this->config, this->reqid, this->udp,
+ this->mark_in, this->mark_out);
tsi = linked_list_create_with_items(this->tsi, NULL);
tsr = linked_list_create_with_items(this->tsr, NULL);
@@ -1202,7 +1233,10 @@ METHOD(task_t, build_r, status_t,
}
if (this->dh)
{
- add_ke(this, message);
+ if (!add_ke(this, message))
+ {
+ return FAILED;
+ }
}
add_ts(this, message);
@@ -1307,6 +1341,13 @@ METHOD(quick_mode_t, use_reqid, void,
this->reqid = reqid;
}
+METHOD(quick_mode_t, use_marks, void,
+ private_quick_mode_t *this, u_int in, u_int out)
+{
+ this->mark_in = in;
+ this->mark_out = out;
+}
+
METHOD(quick_mode_t, rekey, void,
private_quick_mode_t *this, u_int32_t spi)
{
@@ -1334,6 +1375,8 @@ METHOD(task_t, migrate, void,
this->dh = NULL;
this->spi_i = 0;
this->spi_r = 0;
+ this->mark_in = 0;
+ this->mark_out = 0;
if (!this->initiator)
{
@@ -1372,6 +1415,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config,
.destroy = _destroy,
},
.use_reqid = _use_reqid,
+ .use_marks = _use_marks,
.rekey = _rekey,
},
.ike_sa = ike_sa,
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.h b/src/libcharon/sa/ikev1/tasks/quick_mode.h
index 0b80cb836..ee9b64d13 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.h
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.h
@@ -45,6 +45,14 @@ struct quick_mode_t {
void (*use_reqid)(quick_mode_t *this, u_int32_t reqid);
/**
+ * Use specific mark values, overriding configuration.
+ *
+ * @param in inbound mark value
+ * @param out outbound mark value
+ */
+ void (*use_marks)(quick_mode_t *this, u_int in, u_int out);
+
+ /**
* Set the SPI of the old SA, if rekeying.
*
* @param spi spi of SA to rekey
diff --git a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
index eed6d1996..ebef31930 100644
--- a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
@@ -522,6 +522,13 @@ METHOD(authenticator_t, process_server, status_t,
{
return FAILED;
}
+ if (this->method->get_auth)
+ {
+ auth_cfg_t *auth;
+
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+ auth->merge(auth, this->method->get_auth(this->method), FALSE);
+ }
return NEED_MORE;
}
diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
index 6fb14bc06..151b49718 100644
--- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -20,6 +20,9 @@
#include <daemon.h>
#include <encoding/payloads/auth_payload.h>
#include <sa/ikev2/keymat_v2.h>
+#include <asn1/asn1.h>
+#include <asn1/oid.h>
+#include <collections/array.h>
typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
@@ -52,83 +55,303 @@ struct private_pubkey_authenticator_t {
* Reserved bytes of ID payload
*/
char reserved[3];
+
+ /**
+ * Whether to store signature schemes on remote auth configs.
+ */
+ bool store_signature_scheme;
};
-METHOD(authenticator_t, build, status_t,
- private_pubkey_authenticator_t *this, message_t *message)
+/**
+ * Parse authentication data used for Signature Authentication as per RFC 7427
+ */
+static bool parse_signature_auth_data(chunk_t *auth_data, key_type_t *key_type,
+ signature_scheme_t *scheme)
{
- chunk_t octets = chunk_empty, auth_data;
- status_t status = FAILED;
- private_key_t *private;
- identification_t *id;
- auth_cfg_t *auth;
- auth_payload_t *auth_payload;
- auth_method_t auth_method;
+ u_int8_t len;
+ int oid;
+
+ if (!auth_data->len)
+ {
+ return FALSE;
+ }
+ len = auth_data->ptr[0];
+ *auth_data = chunk_skip(*auth_data, 1);
+ /* we currently don't support schemes that require parameters */
+ oid = asn1_parse_algorithmIdentifier(*auth_data, 1, NULL);
+ *scheme = signature_scheme_from_oid(oid);
+ if (*scheme == SIGN_UNKNOWN)
+ {
+ return FALSE;
+ }
+ *key_type = key_type_from_signature_scheme(*scheme);
+ *auth_data = chunk_skip(*auth_data, len);
+ return TRUE;
+}
+
+/**
+ * Build authentication data used for Signature Authentication as per RFC 7427
+ */
+static bool build_signature_auth_data(chunk_t *auth_data,
+ signature_scheme_t scheme)
+{
+ chunk_t data;
+ u_int8_t len;
+ int oid;
+
+ oid = signature_scheme_to_oid(scheme);
+ if (oid == OID_UNKNOWN)
+ {
+ return FALSE;
+ }
+ data = asn1_algorithmIdentifier(oid);
+ len = data.len;
+ *auth_data = chunk_cat("cmm", chunk_from_thing(len), data, *auth_data);
+ return TRUE;
+}
+
+/**
+ * Selects possible signature schemes based on our configuration, the other
+ * peer's capabilities and the private key
+ */
+static array_t *select_signature_schemes(keymat_v2_t *keymat,
+ auth_cfg_t *auth, private_key_t *private)
+{
+ enumerator_t *enumerator;
signature_scheme_t scheme;
+ uintptr_t config;
+ auth_rule_t rule;
+ key_type_t key_type;
+ bool have_config = FALSE;
+ array_t *selected;
+
+ selected = array_create(sizeof(signature_scheme_t), 0);
+ key_type = private->get_type(private);
+ enumerator = auth->create_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &rule, &config))
+ {
+ if (rule != AUTH_RULE_SIGNATURE_SCHEME)
+ {
+ continue;
+ }
+ have_config = TRUE;
+ if (key_type == key_type_from_signature_scheme(config) &&
+ keymat->hash_algorithm_supported(keymat,
+ hasher_from_signature_scheme(config)))
+ {
+ scheme = config;
+ array_insert(selected, ARRAY_TAIL, &scheme);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!have_config)
+ {
+ /* if no specific configuration, find schemes appropriate for the key
+ * and supported by the other peer */
+ enumerator = signature_schemes_for_key(key_type,
+ private->get_keysize(private));
+ while (enumerator->enumerate(enumerator, &scheme))
+ {
+ if (keymat->hash_algorithm_supported(keymat,
+ hasher_from_signature_scheme(scheme)))
+ {
+ array_insert(selected, ARRAY_TAIL, &scheme);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ /* for RSA we tried at least SHA-512, also try other schemes down to
+ * what we'd use with classic authentication */
+ if (key_type == KEY_RSA)
+ {
+ signature_scheme_t schemes[] = {
+ SIGN_RSA_EMSA_PKCS1_SHA384,
+ SIGN_RSA_EMSA_PKCS1_SHA256,
+ SIGN_RSA_EMSA_PKCS1_SHA1,
+ }, contained;
+ bool found;
+ int i, j;
+
+ for (i = 0; i < countof(schemes); i++)
+ {
+ scheme = schemes[i];
+ found = FALSE;
+ for (j = 0; j < array_count(selected); j++)
+ {
+ array_get(selected, j, &contained);
+ if (scheme == contained)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found && keymat->hash_algorithm_supported(keymat,
+ hasher_from_signature_scheme(scheme)))
+ {
+ array_insert(selected, ARRAY_TAIL, &scheme);
+ }
+ }
+ }
+ }
+ return selected;
+}
+
+/**
+ * Create a signature using RFC 7427 signature authentication
+ */
+static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
+ auth_cfg_t *auth, private_key_t *private,
+ identification_t *id, chunk_t *auth_data)
+{
+ enumerator_t *enumerator;
keymat_v2_t *keymat;
+ signature_scheme_t scheme = SIGN_UNKNOWN, *schemep;
+ array_t *schemes;
+ chunk_t octets = chunk_empty;
+ status_t status = FAILED;
- id = this->ike_sa->get_my_id(this->ike_sa);
- auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
- private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth);
- if (private == NULL)
+ keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
+ schemes = select_signature_schemes(keymat, auth, private);
+ if (!array_count(schemes))
{
- DBG1(DBG_IKE, "no private key found for '%Y'", id);
- return NOT_FOUND;
+ DBG1(DBG_IKE, "no common hash algorithm found to create signature "
+ "with %N key", key_type_names, private->get_type(private));
+ array_destroy(schemes);
+ return FAILED;
}
+ if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
+ this->nonce, id, this->reserved, &octets))
+ {
+ enumerator = array_create_enumerator(schemes);
+ while (enumerator->enumerate(enumerator, &schemep))
+ {
+ scheme = *schemep;
+ if (private->sign(private, scheme, octets, auth_data) &&
+ build_signature_auth_data(auth_data, scheme))
+ {
+ status = SUCCESS;
+ break;
+ }
+ else
+ {
+ DBG2(DBG_IKE, "unable to create %N signature for %N key",
+ signature_scheme_names, scheme, key_type_names,
+ private->get_type(private));
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
+ signature_scheme_names, scheme,
+ status == SUCCESS ? "successful" : "failed");
+ array_destroy(schemes);
+ chunk_free(&octets);
+ return status;
+}
+
+/**
+ * Create a classic IKEv2 signature
+ */
+static status_t sign_classic(private_pubkey_authenticator_t *this,
+ auth_cfg_t *auth, private_key_t *private,
+ identification_t *id, auth_method_t *auth_method,
+ chunk_t *auth_data)
+{
+ signature_scheme_t scheme;
+ keymat_v2_t *keymat;
+ chunk_t octets = chunk_empty;
+ status_t status = FAILED;
+
switch (private->get_type(private))
{
case KEY_RSA:
- /* we currently use always SHA1 for signatures,
- * TODO: support other hashes depending on configuration/auth */
scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
- auth_method = AUTH_RSA;
+ *auth_method = AUTH_RSA;
break;
case KEY_ECDSA:
- /* we try to deduct the signature scheme from the keysize */
+ /* deduct the signature scheme from the keysize */
switch (private->get_keysize(private))
{
case 256:
scheme = SIGN_ECDSA_256;
- auth_method = AUTH_ECDSA_256;
+ *auth_method = AUTH_ECDSA_256;
break;
case 384:
scheme = SIGN_ECDSA_384;
- auth_method = AUTH_ECDSA_384;
+ *auth_method = AUTH_ECDSA_384;
break;
case 521:
scheme = SIGN_ECDSA_521;
- auth_method = AUTH_ECDSA_521;
+ *auth_method = AUTH_ECDSA_521;
break;
default:
DBG1(DBG_IKE, "%d bit ECDSA private key size not supported",
- private->get_keysize(private));
- return status;
+ private->get_keysize(private));
+ return FAILED;
}
break;
default:
DBG1(DBG_IKE, "private key of type %N not supported",
- key_type_names, private->get_type(private));
- return status;
+ key_type_names, private->get_type(private));
+ return FAILED;
}
+
keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
this->nonce, id, this->reserved, &octets) &&
- private->sign(private, scheme, octets, &auth_data))
+ private->sign(private, scheme, octets, auth_data))
{
- auth_payload = auth_payload_create();
- auth_payload->set_auth_method(auth_payload, auth_method);
- auth_payload->set_data(auth_payload, auth_data);
- chunk_free(&auth_data);
- message->add_payload(message, (payload_t*)auth_payload);
status = SUCCESS;
}
DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
- auth_method_names, auth_method,
- (status == SUCCESS)? "successful":"failed");
+ auth_method_names, *auth_method,
+ status == SUCCESS ? "successful" : "failed");
chunk_free(&octets);
+ return status;
+}
+
+METHOD(authenticator_t, build, status_t,
+ private_pubkey_authenticator_t *this, message_t *message)
+{
+ private_key_t *private;
+ identification_t *id;
+ auth_cfg_t *auth;
+ chunk_t auth_data;
+ status_t status;
+ auth_payload_t *auth_payload;
+ auth_method_t auth_method;
+
+ id = this->ike_sa->get_my_id(this->ike_sa);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+ private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth);
+ if (!private)
+ {
+ DBG1(DBG_IKE, "no private key found for '%Y'", id);
+ return NOT_FOUND;
+ }
+
+ if (this->ike_sa->supports_extension(this->ike_sa, EXT_SIGNATURE_AUTH))
+ {
+ auth_method = AUTH_DS;
+ status = sign_signature_auth(this, auth, private, id, &auth_data);
+ }
+ else
+ {
+ status = sign_classic(this, auth, private, id, &auth_method,
+ &auth_data);
+ }
private->destroy(private);
+ if (status == SUCCESS)
+ {
+ auth_payload = auth_payload_create();
+ auth_payload->set_auth_method(auth_payload, auth_method);
+ auth_payload->set_data(auth_payload, auth_data);
+ chunk_free(&auth_data);
+ message->add_payload(message, (payload_t*)auth_payload);
+ }
return status;
}
@@ -153,11 +376,10 @@ METHOD(authenticator_t, process, status_t,
return FAILED;
}
auth_method = auth_payload->get_auth_method(auth_payload);
+ auth_data = auth_payload->get_data(auth_payload);
switch (auth_method)
{
case AUTH_RSA:
- /* We currently accept SHA1 signatures only
- * TODO: allow other hash algorithms and note it in "auth" */
key_type = KEY_RSA;
scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
break;
@@ -170,10 +392,15 @@ METHOD(authenticator_t, process, status_t,
case AUTH_ECDSA_521:
scheme = SIGN_ECDSA_521;
break;
+ case AUTH_DS:
+ if (parse_signature_auth_data(&auth_data, &key_type, &scheme))
+ {
+ break;
+ }
+ /* fall-through */
default:
return INVALID_ARG;
}
- auth_data = auth_payload->get_data(auth_payload);
id = this->ike_sa->get_other_id(this->ike_sa);
keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
if (!keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init,
@@ -188,11 +415,16 @@ METHOD(authenticator_t, process, status_t,
{
if (public->verify(public, scheme, octets, auth_data))
{
- DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
- id, auth_method_names, auth_method);
+ DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id,
+ auth_method == AUTH_DS ? signature_scheme_names : auth_method_names,
+ auth_method == AUTH_DS ? scheme : auth_method);
status = SUCCESS;
auth->merge(auth, current_auth, FALSE);
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ if (this->store_signature_scheme)
+ {
+ auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, (uintptr_t)scheme);
+ }
break;
}
else
@@ -265,6 +497,8 @@ pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa,
.ike_sa = ike_sa,
.ike_sa_init = received_init,
.nonce = sent_nonce,
+ .store_signature_scheme = lib->settings->get_bool(lib->settings,
+ "%s.signature_authentication_constraints", TRUE, lib->ns),
);
memcpy(this->reserved, reserved, sizeof(this->reserved));
diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c
index 88ad14faf..f70f5cfed 100644
--- a/src/libcharon/sa/ikev2/keymat_v2.c
+++ b/src/libcharon/sa/ikev2/keymat_v2.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -17,6 +18,7 @@
#include <daemon.h>
#include <crypto/prf_plus.h>
+#include <crypto/hashers/hash_algorithm_set.h>
typedef struct private_keymat_v2_t private_keymat_v2_t;
@@ -69,6 +71,11 @@ struct private_keymat_v2_t {
* Key to verify incoming authentication data (SKp)
*/
chunk_t skp_verify;
+
+ /**
+ * Set of hash algorithms supported by peer for signature authentication
+ */
+ hash_algorithm_set_t *hash_algorithms;
};
METHOD(keymat_t, get_version, ike_version_t,
@@ -293,7 +300,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
spi_i = chunk_alloca(sizeof(u_int64_t));
spi_r = chunk_alloca(sizeof(u_int64_t));
- if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+ if (!dh->get_shared_secret(dh, &secret))
{
return FALSE;
}
@@ -547,7 +554,7 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
if (dh)
{
- if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+ if (!dh->get_shared_secret(dh, &secret))
{
return FALSE;
}
@@ -676,6 +683,26 @@ METHOD(keymat_v2_t, get_psk_sig, bool,
return TRUE;
}
+METHOD(keymat_v2_t, hash_algorithm_supported, bool,
+ private_keymat_v2_t *this, hash_algorithm_t hash)
+{
+ if (!this->hash_algorithms)
+ {
+ return FALSE;
+ }
+ return this->hash_algorithms->contains(this->hash_algorithms, hash);
+}
+
+METHOD(keymat_v2_t, add_hash_algorithm, void,
+ private_keymat_v2_t *this, hash_algorithm_t hash)
+{
+ if (!this->hash_algorithms)
+ {
+ this->hash_algorithms = hash_algorithm_set_create();
+ }
+ this->hash_algorithms->add(this->hash_algorithms, hash);
+}
+
METHOD(keymat_t, destroy, void,
private_keymat_v2_t *this)
{
@@ -685,6 +712,7 @@ METHOD(keymat_t, destroy, void,
chunk_clear(&this->skd);
chunk_clear(&this->skp_verify);
chunk_clear(&this->skp_build);
+ DESTROY_IF(this->hash_algorithms);
free(this);
}
@@ -709,6 +737,9 @@ keymat_v2_t *keymat_v2_create(bool initiator)
.get_skd = _get_skd,
.get_auth_octets = _get_auth_octets,
.get_psk_sig = _get_psk_sig,
+ .add_hash_algorithm = _add_hash_algorithm,
+ .hash_algorithm_supported = _hash_algorithm_supported,
+
},
.initiator = initiator,
.prf_alg = PRF_UNDEFINED,
diff --git a/src/libcharon/sa/ikev2/keymat_v2.h b/src/libcharon/sa/ikev2/keymat_v2.h
index 04432f05b..927b62b03 100644
--- a/src/libcharon/sa/ikev2/keymat_v2.h
+++ b/src/libcharon/sa/ikev2/keymat_v2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -124,6 +124,22 @@ struct keymat_v2_t {
bool (*get_psk_sig)(keymat_v2_t *this, bool verify, chunk_t ike_sa_init,
chunk_t nonce, chunk_t secret,
identification_t *id, char reserved[3], chunk_t *sig);
+
+ /**
+ * Add a hash algorithm supported by the peer for signature authentication.
+ *
+ * @param hash hash algorithm
+ */
+ void (*add_hash_algorithm)(keymat_v2_t *this, hash_algorithm_t hash);
+
+ /**
+ * Check if a given hash algorithm is supported by the peer for signature
+ * authentication.
+ *
+ * @param hash hash algorithm
+ * @return TRUE if supported, FALSE otherwise
+ */
+ bool (*hash_algorithm_supported)(keymat_v2_t *this, hash_algorithm_t hash);
};
/**
diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c
index eb7df3516..298167703 100644
--- a/src/libcharon/sa/ikev2/task_manager_v2.c
+++ b/src/libcharon/sa/ikev2/task_manager_v2.c
@@ -29,6 +29,7 @@
#include <sa/ikev2/tasks/ike_cert_post.h>
#include <sa/ikev2/tasks/ike_rekey.h>
#include <sa/ikev2/tasks/ike_reauth.h>
+#include <sa/ikev2/tasks/ike_reauth_complete.h>
#include <sa/ikev2/tasks/ike_delete.h>
#include <sa/ikev2/tasks/ike_config.h>
#include <sa/ikev2/tasks/ike_dpd.h>
@@ -171,6 +172,11 @@ struct private_task_manager_t {
* Base to calculate retransmission timeout
*/
double retransmit_base;
+
+ /**
+ * Use make-before-break instead of break-before-make reauth?
+ */
+ bool make_before_break;
};
/**
@@ -510,6 +516,11 @@ METHOD(task_manager_t, initiate, status_t,
break;
}
#endif /* ME */
+ if (activate_task(this, TASK_IKE_REAUTH_COMPLETE))
+ {
+ exchange = INFORMATIONAL;
+ break;
+ }
case IKE_REKEYING:
if (activate_task(this, TASK_IKE_DELETE))
{
@@ -604,6 +615,11 @@ METHOD(task_manager_t, initiate, status_t,
/* update exchange type if a task changed it */
this->initiating.type = message->get_exchange_type(message);
+ if (this->initiating.type == EXCHANGE_TYPE_UNDEFINED)
+ {
+ message->destroy(message);
+ return SUCCESS;
+ }
if (!generate_message(this, message, &this->initiating.packets))
{
@@ -1170,7 +1186,7 @@ static status_t parse_message(private_task_manager_t *this, message_t *msg)
{
unknown = (unknown_payload_t*)payload;
type = payload->get_type(payload);
- if (!payload_is_known(type) &&
+ if (!payload_is_known(type, msg->get_major_version(msg)) &&
unknown->is_critical(unknown))
{
DBG1(DBG_ENC, "payload type %N is not supported, "
@@ -1288,17 +1304,16 @@ METHOD(task_manager_t, process_message, status_t,
{
if (mid == this->responding.mid)
{
- /* reject initial messages once established */
- if (msg->get_exchange_type(msg) == IKE_SA_INIT ||
- msg->get_exchange_type(msg) == IKE_AUTH)
+ /* reject initial messages if not received in specific states */
+ if ((msg->get_exchange_type(msg) == IKE_SA_INIT &&
+ this->ike_sa->get_state(this->ike_sa) != IKE_CREATED) ||
+ (msg->get_exchange_type(msg) == IKE_AUTH &&
+ this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING))
{
- if (this->ike_sa->get_state(this->ike_sa) != IKE_CREATED &&
- this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
- {
- DBG1(DBG_IKE, "ignoring %N in established IKE_SA state",
- exchange_type_names, msg->get_exchange_type(msg));
- return FAILED;
- }
+ DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N",
+ exchange_type_names, msg->get_exchange_type(msg),
+ ike_sa_state_names, this->ike_sa->get_state(this->ike_sa));
+ return FAILED;
}
if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
{ /* with MOBIKE, we do no implicit updates */
@@ -1339,10 +1354,6 @@ METHOD(task_manager_t, process_message, status_t,
{
DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored",
mid, this->responding.mid);
- if (msg->get_exchange_type(msg) == IKE_SA_INIT)
- { /* clean up IKE_SA state if IKE_SA_INIT has invalid msg ID */
- return DESTROY_ME;
- }
}
}
else
@@ -1505,9 +1516,79 @@ METHOD(task_manager_t, queue_ike_rekey, void,
queue_task(this, (task_t*)ike_rekey_create(this->ike_sa, TRUE));
}
+/**
+ * Start reauthentication using make-before-break
+ */
+static void trigger_mbb_reauth(private_task_manager_t *this)
+{
+ enumerator_t *enumerator;
+ child_sa_t *child_sa;
+ child_cfg_t *cfg;
+ ike_sa_t *new;
+ host_t *host;
+ task_t *task;
+
+ new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
+ this->ike_sa->get_version(this->ike_sa), TRUE);
+ if (!new)
+ { /* shouldn't happen */
+ return;
+ }
+
+ new->set_peer_cfg(new, this->ike_sa->get_peer_cfg(this->ike_sa));
+ host = this->ike_sa->get_other_host(this->ike_sa);
+ new->set_other_host(new, host->clone(host));
+ host = this->ike_sa->get_my_host(this->ike_sa);
+ new->set_my_host(new, host->clone(host));
+ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ new->add_virtual_ip(new, TRUE, host);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
+ while (enumerator->enumerate(enumerator, &child_sa))
+ {
+ cfg = child_sa->get_config(child_sa);
+ new->queue_task(new, &child_create_create(new, cfg->get_ref(cfg),
+ FALSE, NULL, NULL)->task);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = array_create_enumerator(this->queued_tasks);
+ while (enumerator->enumerate(enumerator, &task))
+ {
+ if (task->get_type(task) == TASK_CHILD_CREATE)
+ {
+ task->migrate(task, new);
+ new->queue_task(new, task);
+ array_remove_at(this->queued_tasks, enumerator);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
+ {
+ new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
+ this->ike_sa->get_id(this->ike_sa)));
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
+ DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
+ }
+ charon->bus->set_sa(charon->bus, this->ike_sa);
+}
+
METHOD(task_manager_t, queue_ike_reauth, void,
private_task_manager_t *this)
{
+ if (this->make_before_break)
+ {
+ return trigger_mbb_reauth(this);
+ }
queue_task(this, (task_t*)ike_reauth_create(this->ike_sa));
}
@@ -1773,6 +1854,8 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
.retransmit_base = lib->settings->get_double(lib->settings,
"%s.retransmit_base", RETRANSMIT_BASE, lib->ns),
+ .make_before_break = lib->settings->get_bool(lib->settings,
+ "%s.make_before_break", FALSE, lib->ns),
);
return &this->public;
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c
index a1f01c276..6d9132a68 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.c
+++ b/src/libcharon/sa/ikev2/tasks/child_create.c
@@ -105,6 +105,11 @@ struct private_child_create_t {
diffie_hellman_t *dh;
/**
+ * Applying DH public value failed?
+ */
+ bool dh_failed;
+
+ /**
* group used for DH exchange
*/
diffie_hellman_group_t dh_group;
@@ -160,6 +165,16 @@ struct private_child_create_t {
u_int32_t reqid;
/**
+ * Explicit inbound mark value
+ */
+ u_int mark_in;
+
+ /**
+ * Explicit outbound mark value
+ */
+ u_int mark_out;
+
+ /**
* CHILD_SA which gets established
*/
child_sa_t *child_sa;
@@ -286,7 +301,7 @@ static bool allocate_spi(private_child_create_t *this)
*/
static void schedule_inactivity_timeout(private_child_create_t *this)
{
- u_int32_t timeout;
+ u_int32_t timeout, id;
bool close_ike;
timeout = this->config->get_inactivity(this->config);
@@ -294,9 +309,9 @@ static void schedule_inactivity_timeout(private_child_create_t *this)
{
close_ike = lib->settings->get_bool(lib->settings,
"%s.inactivity_close_ike", FALSE, lib->ns);
+ id = this->child_sa->get_unique_id(this->child_sa);
lib->scheduler->schedule_job(lib->scheduler, (job_t*)
- inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
- timeout, close_ike), timeout);
+ inactivity_job_create(id, timeout, close_ike), timeout);
}
}
@@ -683,10 +698,7 @@ static status_t select_and_install(private_child_create_t *this,
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
this->established = TRUE;
- if (!this->rekey)
- { /* a rekeyed SA uses the same reqid, no need for a new job */
- schedule_inactivity_timeout(this);
- }
+ schedule_inactivity_timeout(this);
my_ts = linked_list_create_from_enumerator(
this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
@@ -696,7 +708,7 @@ static status_t select_and_install(private_child_create_t *this,
DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
"with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
this->child_sa->get_name(this->child_sa),
- this->child_sa->get_reqid(this->child_sa),
+ this->child_sa->get_unique_id(this->child_sa),
ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts);
@@ -709,7 +721,7 @@ static status_t select_and_install(private_child_create_t *this,
/**
* build the payloads for the message
*/
-static void build_payloads(private_child_create_t *this, message_t *message)
+static bool build_payloads(private_child_create_t *this, message_t *message)
{
sa_payload_t *sa_payload;
nonce_payload_t *nonce_payload;
@@ -741,6 +753,11 @@ static void build_payloads(private_child_create_t *this, message_t *message)
{
ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
this->dh);
+ if (!ke_payload)
+ {
+ DBG1(DBG_IKE, "creating KE payload failed");
+ return FALSE;
+ }
message->add_payload(message, (payload_t*)ke_payload);
}
@@ -769,6 +786,7 @@ static void build_payloads(private_child_create_t *this, message_t *message)
message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED,
chunk_empty);
}
+ return TRUE;
}
/**
@@ -880,7 +898,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
}
if (this->dh)
{
- this->dh->set_other_public_value(this->dh,
+ this->dh_failed = !this->dh->set_other_public_value(this->dh,
ke_payload->get_key_exchange_data(ke_payload));
}
break;
@@ -996,7 +1014,8 @@ METHOD(task_t, build_i, status_t,
this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
- this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
+ this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
+ this->mark_in, this->mark_out);
if (!allocate_spi(this))
{
@@ -1027,7 +1046,10 @@ METHOD(task_t, build_i, status_t,
NARROW_INITIATOR_PRE_AUTH, this->tsi, this->tsr);
}
- build_payloads(this, message);
+ if (!build_payloads(this, message))
+ {
+ return FAILED;
+ }
this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
@@ -1168,12 +1190,19 @@ METHOD(task_t, build_r, status_t,
case IKE_SA_INIT:
return get_nonce(message, &this->my_nonce);
case CREATE_CHILD_SA:
- if (generate_nonce(this) != SUCCESS)
+ if (generate_nonce(this) != SUCCESS )
{
message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
chunk_empty);
return SUCCESS;
}
+ if (this->dh_failed)
+ {
+ DBG1(DBG_IKE, "applying DH public value failed");
+ message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
+ chunk_empty);
+ return SUCCESS;
+ }
no_dh = FALSE;
break;
case IKE_AUTH:
@@ -1241,7 +1270,8 @@ METHOD(task_t, build_r, status_t,
this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
- this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
+ this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
+ this->mark_in, this->mark_out);
if (this->ipcomp_received != IPCOMP_NONE)
{
@@ -1279,7 +1309,12 @@ METHOD(task_t, build_r, status_t,
return SUCCESS;
}
- build_payloads(this, message);
+ if (!build_payloads(this, message))
+ {
+ message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
+ handle_child_sa_failure(this, message);
+ return SUCCESS;
+ }
if (!this->rekey)
{ /* invoke the child_up() hook if we are not rekeying */
@@ -1408,6 +1443,7 @@ METHOD(task_t, process_i, status_t,
this->dh_group, diffie_hellman_group_names, group);
this->retry = TRUE;
this->dh_group = group;
+ this->child_sa->set_state(this->child_sa, CHILD_RETRYING);
this->public.task.migrate(&this->public.task, this->ike_sa);
enumerator->destroy(enumerator);
return NEED_MORE;
@@ -1456,6 +1492,13 @@ METHOD(task_t, process_i, status_t,
return delete_failed_sa(this);
}
+ if (this->dh_failed)
+ {
+ DBG1(DBG_IKE, "applying DH public value failed");
+ handle_child_sa_failure(this, message);
+ return delete_failed_sa(this);
+ }
+
if (select_and_install(this, no_dh, ike_auth) == SUCCESS)
{
if (!this->rekey)
@@ -1477,6 +1520,13 @@ METHOD(child_create_t, use_reqid, void,
this->reqid = reqid;
}
+METHOD(child_create_t, use_marks, void,
+ private_child_create_t *this, u_int in, u_int out)
+{
+ this->mark_in = in;
+ this->mark_out = out;
+}
+
METHOD(child_create_t, get_child, child_sa_t*,
private_child_create_t *this)
{
@@ -1526,6 +1576,7 @@ METHOD(task_t, migrate, void,
DESTROY_IF(this->child_sa);
DESTROY_IF(this->proposal);
DESTROY_IF(this->dh);
+ this->dh_failed = FALSE;
if (this->proposals)
{
this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
@@ -1544,6 +1595,8 @@ METHOD(task_t, migrate, void,
this->ipcomp_received = IPCOMP_NONE;
this->other_cpi = 0;
this->reqid = 0;
+ this->mark_in = 0;
+ this->mark_out = 0;
this->established = FALSE;
}
@@ -1592,6 +1645,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa,
.set_config = _set_config,
.get_lower_nonce = _get_lower_nonce,
.use_reqid = _use_reqid,
+ .use_marks = _use_marks,
.task = {
.get_type = _get_type,
.migrate = _migrate,
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.h b/src/libcharon/sa/ikev2/tasks/child_create.h
index d29ba3d98..46d9403ee 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.h
+++ b/src/libcharon/sa/ikev2/tasks/child_create.h
@@ -52,6 +52,14 @@ struct child_create_t {
void (*use_reqid) (child_create_t *this, u_int32_t reqid);
/**
+ * Use specific mark values to override configuration.
+ *
+ * @param in inbound mark value
+ * @param out outbound mark value
+ */
+ void (*use_marks)(child_create_t *this, u_int in, u_int out);
+
+ /**
* Get the lower of the two nonces, used for rekey collisions.
*
* @return lower nonce
diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c
index 2b1697423..f0b11e291 100644
--- a/src/libcharon/sa/ikev2/tasks/child_delete.c
+++ b/src/libcharon/sa/ikev2/tasks/child_delete.c
@@ -267,7 +267,7 @@ static void log_children(private_child_delete_t *this)
{
DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} "
"with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
ntohl(child_sa->get_spi(child_sa, TRUE)),
ntohl(child_sa->get_spi(child_sa, FALSE)), my_ts, other_ts);
}
@@ -278,7 +278,7 @@ static void log_children(private_child_delete_t *this)
DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs %.8x_i "
"(%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
- child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+ child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in,
ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out,
my_ts, other_ts);
diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c
index db872827d..c806e19ca 100644
--- a/src/libcharon/sa/ikev2/tasks/child_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c
@@ -96,9 +96,9 @@ static void schedule_delayed_rekey(private_child_rekey_t *this)
retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
job = (job_t*)rekey_child_sa_job_create(
- this->child_sa->get_reqid(this->child_sa),
this->child_sa->get_protocol(this->child_sa),
- this->child_sa->get_spi(this->child_sa, TRUE));
+ this->child_sa->get_spi(this->child_sa, TRUE),
+ this->ike_sa->get_my_host(this->ike_sa));
DBG1(DBG_IKE, "CHILD_SA rekeying failed, trying again in %d seconds", retry);
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
lib->scheduler->schedule_job(lib->scheduler, job, retry);
@@ -184,6 +184,9 @@ METHOD(task_t, build_i, status_t,
}
reqid = this->child_sa->get_reqid(this->child_sa);
this->child_create->use_reqid(this->child_create, reqid);
+ this->child_create->use_marks(this->child_create,
+ this->child_sa->get_mark(this->child_sa, TRUE).value,
+ this->child_sa->get_mark(this->child_sa, FALSE).value);
if (this->child_create->task.build(&this->child_create->task,
message) != NEED_MORE)
@@ -224,6 +227,9 @@ METHOD(task_t, build_r, status_t,
/* let the CHILD_CREATE task build the response */
reqid = this->child_sa->get_reqid(this->child_sa);
this->child_create->use_reqid(this->child_create, reqid);
+ this->child_create->use_marks(this->child_create,
+ this->child_sa->get_mark(this->child_sa, TRUE).value,
+ this->child_sa->get_mark(this->child_sa, FALSE).value);
config = this->child_sa->get_config(this->child_sa);
this->child_create->set_config(this->child_create, config->get_ref(config));
this->child_create->task.build(&this->child_create->task, message);
diff --git a/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c b/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c
index 0dac975e7..ca17494de 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c
@@ -229,12 +229,12 @@ static void process_x509(cert_payload_t *payload, auth_cfg_t *auth,
return;
}
url = strdup(url);
- if (first)
+ if (*first)
{ /* first URL is for an end entity certificate */
DBG1(DBG_IKE, "received hash-and-url for end entity cert \"%s\"",
url);
auth->add(auth, AUTH_HELPER_SUBJECT_HASH_URL, url);
- first = FALSE;
+ *first = FALSE;
}
else
{
diff --git a/src/libcharon/sa/ikev2/tasks/ike_config.c b/src/libcharon/sa/ikev2/tasks/ike_config.c
index da06e2a36..646f20c61 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_config.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_config.c
@@ -17,7 +17,6 @@
#include "ike_config.h"
#include <daemon.h>
-#include <hydra.h>
#include <encoding/payloads/cp_payload.h>
typedef struct private_ike_config_t private_ike_config_t;
@@ -127,9 +126,8 @@ static void handle_attribute(private_ike_config_t *this,
enumerator->destroy(enumerator);
/* and pass it to the handle function */
- handler = hydra->attributes->handle(hydra->attributes,
- this->ike_sa->get_other_id(this->ike_sa), handler,
- ca->get_type(ca), ca->get_chunk(ca));
+ handler = charon->attributes->handle(charon->attributes,
+ this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca));
this->ike_sa->add_configuration_attribute(this->ike_sa,
handler, ca->get_type(ca), ca->get_chunk(ca));
}
@@ -274,9 +272,8 @@ METHOD(task_t, build_i, status_t,
enumerator->destroy(enumerator);
}
- enumerator = hydra->attributes->create_initiator_enumerator(
- hydra->attributes,
- this->ike_sa->get_other_id(this->ike_sa), vips);
+ enumerator = charon->attributes->create_initiator_enumerator(
+ charon->attributes, this->ike_sa, vips);
while (enumerator->enumerate(enumerator, &handler, &type, &data))
{
configuration_attribute_t *ca;
@@ -352,8 +349,8 @@ METHOD(task_t, build_r, status_t,
/* query all pools until we get an address */
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
- found = hydra->attributes->acquire_address(hydra->attributes,
- pools, id, requested);
+ found = charon->attributes->acquire_address(charon->attributes,
+ pools, this->ike_sa, requested);
if (found)
{
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
@@ -398,8 +395,8 @@ METHOD(task_t, build_r, status_t,
}
/* query registered providers for additional attributes to include */
- enumerator = hydra->attributes->create_responder_enumerator(
- hydra->attributes, pools, id, vips);
+ enumerator = charon->attributes->create_responder_enumerator(
+ charon->attributes, pools, this->ike_sa, vips);
while (enumerator->enumerate(enumerator, &type, &value))
{
if (!cp)
diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c
index 71c5f22fa..0d5700ef2 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_init.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -20,8 +20,11 @@
#include <string.h>
#include <daemon.h>
+#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
#include <sa/ikev2/keymat_v2.h>
#include <crypto/diffie_hellman.h>
+#include <crypto/hashers/hash_algorithm_set.h>
#include <encoding/payloads/sa_payload.h>
#include <encoding/payloads/ke_payload.h>
#include <encoding/payloads/nonce_payload.h>
@@ -67,6 +70,11 @@ struct private_ike_init_t {
diffie_hellman_t *dh;
/**
+ * Applying DH public value failed?
+ */
+ bool dh_failed;
+
+ /**
* Keymat derivation (from IKE_SA)
*/
keymat_v2_t *keymat;
@@ -100,12 +108,114 @@ struct private_ike_init_t {
* retries done so far after failure (cookie or bad dh group)
*/
u_int retry;
+
+ /**
+ * Whether to use Signature Authentication as per RFC 7427
+ */
+ bool signature_authentication;
};
/**
+ * Notify the peer about the hash algorithms we support or expect,
+ * as per RFC 7427
+ */
+static void send_supported_hash_algorithms(private_ike_init_t *this,
+ message_t *message)
+{
+ hash_algorithm_set_t *algos;
+ enumerator_t *enumerator, *rounds;
+ bio_writer_t *writer;
+ hash_algorithm_t hash;
+ peer_cfg_t *peer;
+ auth_cfg_t *auth;
+ auth_rule_t rule;
+ uintptr_t config;
+ char *plugin_name;
+
+ algos = hash_algorithm_set_create();
+ peer = this->ike_sa->get_peer_cfg(this->ike_sa);
+ if (peer)
+ {
+ rounds = peer->create_auth_cfg_enumerator(peer, FALSE);
+ while (rounds->enumerate(rounds, &auth))
+ {
+ enumerator = auth->create_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &rule, &config))
+ {
+ if (rule == AUTH_RULE_SIGNATURE_SCHEME)
+ {
+ hash = hasher_from_signature_scheme(config);
+ if (hasher_algorithm_for_ikev2(hash))
+ {
+ algos->add(algos, hash);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ rounds->destroy(rounds);
+ }
+
+ if (!algos->count(algos))
+ {
+ enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &hash, &plugin_name))
+ {
+ if (hasher_algorithm_for_ikev2(hash))
+ {
+ algos->add(algos, hash);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ if (algos->count(algos))
+ {
+ writer = bio_writer_create(0);
+ enumerator = algos->create_enumerator(algos);
+ while (enumerator->enumerate(enumerator, &hash))
+ {
+ writer->write_uint16(writer, hash);
+ }
+ enumerator->destroy(enumerator);
+ message->add_notify(message, FALSE, SIGNATURE_HASH_ALGORITHMS,
+ writer->get_buf(writer));
+ writer->destroy(writer);
+ }
+ algos->destroy(algos);
+}
+
+/**
+ * Store algorithms supported by other peer
+ */
+static void handle_supported_hash_algorithms(private_ike_init_t *this,
+ notify_payload_t *notify)
+{
+ bio_reader_t *reader;
+ u_int16_t algo;
+ bool added = FALSE;
+
+ reader = bio_reader_create(notify->get_notification_data(notify));
+ while (reader->remaining(reader) >= 2 && reader->read_uint16(reader, &algo))
+ {
+ if (hasher_algorithm_for_ikev2(algo))
+ {
+ this->keymat->add_hash_algorithm(this->keymat, algo);
+ added = TRUE;
+ }
+ }
+ reader->destroy(reader);
+
+ if (added)
+ {
+ this->ike_sa->enable_extension(this->ike_sa, EXT_SIGNATURE_AUTH);
+ }
+}
+
+/**
* build the payloads for the message
*/
-static void build_payloads(private_ike_init_t *this, message_t *message)
+static bool build_payloads(private_ike_init_t *this, message_t *message)
{
sa_payload_t *sa_payload;
ke_payload_t *ke_payload;
@@ -149,7 +259,13 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
nonce_payload = nonce_payload_create(PLV2_NONCE);
nonce_payload->set_nonce(nonce_payload, this->my_nonce);
- ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE, this->dh);
+ ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
+ this->dh);
+ if (!ke_payload)
+ {
+ DBG1(DBG_IKE, "creating KE payload failed");
+ return FALSE;
+ }
if (this->old_sa)
{ /* payload order differs if we are rekeying */
@@ -174,6 +290,17 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
chunk_empty);
}
}
+ /* submit supported hash algorithms for signature authentication */
+ if (!this->old_sa && this->signature_authentication)
+ {
+ if (this->initiator ||
+ this->ike_sa->supports_extension(this->ike_sa,
+ EXT_SIGNATURE_AUTH))
+ {
+ send_supported_hash_algorithms(this, message);
+ }
+ }
+ return TRUE;
}
/**
@@ -183,6 +310,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
{
enumerator_t *enumerator;
payload_t *payload;
+ ke_payload_t *ke_payload = NULL;
enumerator = message->create_payload_enumerator(message);
while (enumerator->enumerate(enumerator, &payload))
@@ -211,19 +339,9 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
}
case PLV2_KEY_EXCHANGE:
{
- ke_payload_t *ke_payload = (ke_payload_t*)payload;
+ ke_payload = (ke_payload_t*)payload;
this->dh_group = ke_payload->get_dh_group_number(ke_payload);
- if (!this->initiator)
- {
- this->dh = this->keymat->keymat.create_dh(
- &this->keymat->keymat, this->dh_group);
- }
- if (this->dh)
- {
- this->dh->set_other_public_value(this->dh,
- ke_payload->get_key_exchange_data(ke_payload));
- }
break;
}
case PLV2_NONCE:
@@ -237,17 +355,44 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
{
notify_payload_t *notify = (notify_payload_t*)payload;
- if (notify->get_notify_type(notify) == FRAGMENTATION_SUPPORTED)
+ switch (notify->get_notify_type(notify))
{
- this->ike_sa->enable_extension(this->ike_sa,
- EXT_IKE_FRAGMENTATION);
+ case FRAGMENTATION_SUPPORTED:
+ this->ike_sa->enable_extension(this->ike_sa,
+ EXT_IKE_FRAGMENTATION);
+ break;
+ case SIGNATURE_HASH_ALGORITHMS:
+ if (this->signature_authentication)
+ {
+ handle_supported_hash_algorithms(this, notify);
+ }
+ break;
+ default:
+ /* other notifies are handled elsewhere */
+ break;
}
+
}
default:
break;
}
}
enumerator->destroy(enumerator);
+
+ if (ke_payload && this->proposal &&
+ this->proposal->has_dh_group(this->proposal, this->dh_group))
+ {
+ if (!this->initiator)
+ {
+ this->dh = this->keymat->keymat.create_dh(
+ &this->keymat->keymat, this->dh_group);
+ }
+ if (this->dh)
+ {
+ this->dh_failed = !this->dh->set_other_public_value(this->dh,
+ ke_payload->get_key_exchange_data(ke_payload));
+ }
+ }
}
METHOD(task_t, build_i, status_t,
@@ -305,7 +450,10 @@ METHOD(task_t, build_i, status_t,
message->add_notify(message, FALSE, COOKIE, this->cookie);
}
- build_payloads(this, message);
+ if (!build_payloads(this, message))
+ {
+ return FAILED;
+ }
#ifdef ME
{
@@ -433,13 +581,24 @@ METHOD(task_t, build_r, status_t,
return FAILED;
}
+ if (this->dh_failed)
+ {
+ DBG1(DBG_IKE, "applying DH public value failed");
+ message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
+ return FAILED;
+ }
+
if (!derive_keys(this, this->other_nonce, this->my_nonce))
{
DBG1(DBG_IKE, "key derivation failed");
message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
return FAILED;
}
- build_payloads(this, message);
+ if (!build_payloads(this, message))
+ {
+ message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
+ return FAILED;
+ }
return SUCCESS;
}
@@ -554,6 +713,12 @@ METHOD(task_t, process_i, status_t,
return FAILED;
}
+ if (this->dh_failed)
+ {
+ DBG1(DBG_IKE, "applying DH public value failed");
+ return FAILED;
+ }
+
if (!derive_keys(this, this->my_nonce, this->other_nonce))
{
DBG1(DBG_IKE, "key derivation failed");
@@ -577,6 +742,7 @@ METHOD(task_t, migrate, void,
this->ike_sa = ike_sa;
this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
this->proposal = NULL;
+ this->dh_failed = FALSE;
if (this->dh && this->dh->get_dh_group(this->dh) != this->dh_group)
{ /* reset DH value only if group changed (INVALID_KE_PAYLOAD) */
this->dh->destroy(this->dh);
@@ -631,6 +797,8 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa)
.dh_group = MODP_NONE,
.keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa),
.old_sa = old_sa,
+ .signature_authentication = lib->settings->get_bool(lib->settings,
+ "%s.signature_authentication", TRUE, lib->ns),
);
if (initiator)
diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c
index d91fa5862..6295d7960 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c
@@ -256,6 +256,7 @@ static void update_children(private_ike_mobike_t *this)
enumerator_t *enumerator;
child_sa_t *child_sa;
linked_list_t *vips;
+ status_t status;
host_t *host;
vips = linked_list_create();
@@ -270,15 +271,25 @@ static void update_children(private_ike_mobike_t *this)
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
- if (child_sa->update(child_sa,
- this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa), vips,
- this->ike_sa->has_condition(this->ike_sa,
- COND_NAT_ANY)) == NOT_SUPPORTED)
+ status = child_sa->update(child_sa,
+ this->ike_sa->get_my_host(this->ike_sa),
+ this->ike_sa->get_other_host(this->ike_sa), vips,
+ this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
+ switch (status)
{
- this->ike_sa->rekey_child_sa(this->ike_sa,
- child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE));
+ case NOT_SUPPORTED:
+ this->ike_sa->rekey_child_sa(this->ike_sa,
+ child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE));
+ break;
+ case SUCCESS:
+ charon->child_sa_manager->remove(charon->child_sa_manager,
+ child_sa);
+ charon->child_sa_manager->add(charon->child_sa_manager,
+ child_sa, this->ike_sa);
+ break;
+ default:
+ break;
}
}
enumerator->destroy(enumerator);
diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth.h b/src/libcharon/sa/ikev2/tasks/ike_reauth.h
index 781b463a7..e2e48f0d4 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_reauth.h
+++ b/src/libcharon/sa/ikev2/tasks/ike_reauth.h
@@ -29,6 +29,8 @@ typedef struct ike_reauth_t ike_reauth_t;
/**
* Task of type ike_reauth, reestablishes an IKE_SA.
+ *
+ * This task implements break-before-make reauthentication.
*/
struct ike_reauth_t {
diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c
new file mode 100644
index 000000000..a01489c03
--- /dev/null
+++ b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c
@@ -0,0 +1,102 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ike_reauth_complete.h"
+
+#include <daemon.h>
+#include <processing/jobs/delete_ike_sa_job.h>
+
+
+typedef struct private_ike_reauth_complete_t private_ike_reauth_complete_t;
+
+/**
+ * Private members of a ike_reauth_complete_t task.
+ */
+struct private_ike_reauth_complete_t {
+
+ /**
+ * Public methods and task_t interface.
+ */
+ ike_reauth_complete_t public;
+
+ /**
+ * Assigned IKE_SA.
+ */
+ ike_sa_t *ike_sa;
+
+ /**
+ * Reauthenticated IKE_SA identifier
+ */
+ ike_sa_id_t *id;
+};
+
+METHOD(task_t, build_i, status_t,
+ private_ike_reauth_complete_t *this, message_t *message)
+{
+ message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED);
+ lib->processor->queue_job(lib->processor,
+ (job_t*)delete_ike_sa_job_create(this->id, TRUE));
+ return SUCCESS;
+}
+
+METHOD(task_t, process_i, status_t,
+ private_ike_reauth_complete_t *this, message_t *message)
+{
+ return DESTROY_ME;
+}
+
+METHOD(task_t, get_type, task_type_t,
+ private_ike_reauth_complete_t *this)
+{
+ return TASK_IKE_REAUTH_COMPLETE;
+}
+
+METHOD(task_t, migrate, void,
+ private_ike_reauth_complete_t *this, ike_sa_t *ike_sa)
+{
+ this->ike_sa = ike_sa;
+}
+
+METHOD(task_t, destroy, void,
+ private_ike_reauth_complete_t *this)
+{
+ this->id->destroy(this->id);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ike_reauth_complete_t *ike_reauth_complete_create(ike_sa_t *ike_sa,
+ ike_sa_id_t *id)
+{
+ private_ike_reauth_complete_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .build = _build_i,
+ .process = _process_i,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ .id = id->clone(id),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h
new file mode 100644
index 000000000..cc3d3b713
--- /dev/null
+++ b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h
@@ -0,0 +1,56 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ike_reauth_complete ike_reauth_complete
+ * @{ @ingroup tasks_v2
+ */
+
+#ifndef IKE_REAUTH_COMPLETE_H_
+#define IKE_REAUTH_COMPLETE_H_
+
+typedef struct ike_reauth_complete_t ike_reauth_complete_t;
+
+#include <library.h>
+#include <sa/ike_sa.h>
+#include <sa/task.h>
+
+/**
+ * Task of type IKE_REAUTH_COMPLETE, removes reauthenticated SA after reauth.
+ *
+ * This task completes make-before-break reauthentication by deleting the
+ * old, reauthenticated IKE_SA after the new one established.
+ */
+struct ike_reauth_complete_t {
+
+ /**
+ * Implements the task_t interface
+ */
+ task_t task;
+};
+
+/**
+ * Create a new ike_reauth_complete task.
+ *
+ * This task is initiator only.
+ *
+ * @param ike_sa IKE_SA this task works for
+ * @param id old, reauthenticated IKE_SA
+ * @return ike_reauth_complete task to handle by the task_manager
+ */
+ike_reauth_complete_t *ike_reauth_complete_create(ike_sa_t *ike_sa,
+ ike_sa_id_t *id);
+
+#endif /** IKE_REAUTH_COMPLETE_H_ @}*/
diff --git a/src/libcharon/sa/ikev2/tasks/ike_rekey.c b/src/libcharon/sa/ikev2/tasks/ike_rekey.c
index 444ac6ade..1855517ce 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_rekey.c
@@ -22,6 +22,7 @@
#include <sa/ikev2/tasks/ike_delete.h>
#include <processing/jobs/delete_ike_sa_job.h>
#include <processing/jobs/rekey_ike_sa_job.h>
+#include <processing/jobs/initiate_tasks_job.h>
typedef struct private_ike_rekey_t private_ike_rekey_t;
@@ -68,12 +69,33 @@ struct private_ike_rekey_t {
};
/**
+ * Check if an IKE_SA has any queued tasks, return initiation job
+ */
+static job_t* check_queued_tasks(ike_sa_t *ike_sa)
+{
+ enumerator_t *enumerator;
+ task_t *task;
+ job_t *job = NULL;
+
+ enumerator = ike_sa->create_task_enumerator(ike_sa, TASK_QUEUE_QUEUED);
+ if (enumerator->enumerate(enumerator, &task))
+ {
+ job = (job_t*)initiate_tasks_job_create(ike_sa->get_id(ike_sa));
+ }
+ enumerator->destroy(enumerator);
+
+ return job;
+}
+
+/**
* Establish the new replacement IKE_SA
*/
static void establish_new(private_ike_rekey_t *this)
{
if (this->new_sa)
{
+ job_t *job;
+
this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED);
DBG0(DBG_IKE, "IKE_SA %s[%d] rekeyed between %H[%Y]...%H[%Y]",
this->new_sa->get_name(this->new_sa),
@@ -85,7 +107,14 @@ static void establish_new(private_ike_rekey_t *this)
this->new_sa->inherit_post(this->new_sa, this->ike_sa);
charon->bus->ike_rekey(charon->bus, this->ike_sa, this->new_sa);
+ job = check_queued_tasks(this->new_sa);
+ /* don't queue job before checkin(), as the IKE_SA is not yet
+ * registered at the manager */
charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa);
+ if (job)
+ {
+ lib->processor->queue_job(lib->processor, job);
+ }
this->new_sa = NULL;
/* set threads active IKE_SA after checkin */
charon->bus->set_sa(charon->bus, this->ike_sa);
@@ -163,6 +192,7 @@ METHOD(task_t, process_r, status_t,
{
case CHILD_CREATED:
case CHILD_REKEYING:
+ case CHILD_RETRYING:
case CHILD_DELETING:
/* we do not allow rekeying while we have children in-progress */
DBG1(DBG_IKE, "peer initiated rekeying, but a child is half-open");
@@ -209,6 +239,12 @@ METHOD(task_t, build_r, status_t,
this->public.task.build = _build_r_delete;
this->public.task.process = _process_r_delete;
+ /* the peer does have to delete the IKE_SA. If it does not, we get a
+ * unusable IKE_SA in REKEYING state without a replacement. We consider
+ * this a timeout condition by the peer, and trigger a delete actively. */
+ lib->scheduler->schedule_job(lib->scheduler, (job_t*)
+ delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE), 90);
+
return NEED_MORE;
}
diff --git a/src/libcharon/sa/task.c b/src/libcharon/sa/task.c
index 4336b23ff..b35b58185 100644
--- a/src/libcharon/sa/task.c
+++ b/src/libcharon/sa/task.c
@@ -27,6 +27,7 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_ISAKMP_CERT_POST,
"IKE_CONFIG",
"IKE_REKEY",
"IKE_REAUTH",
+ "IKE_REAUTH_COMPLETE",
"IKE_DELETE",
"IKE_DPD",
"IKE_VENDOR",
diff --git a/src/libcharon/sa/task.h b/src/libcharon/sa/task.h
index f2c4299cc..7bd3da1fe 100644
--- a/src/libcharon/sa/task.h
+++ b/src/libcharon/sa/task.h
@@ -22,6 +22,8 @@
#ifndef TASK_H_
#define TASK_H_
+#include <utils/utils.h>
+
typedef enum task_type_t task_type_t;
typedef struct task_t task_t;
@@ -51,8 +53,10 @@ enum task_type_t {
TASK_IKE_CONFIG,
/** rekey an IKE_SA */
TASK_IKE_REKEY,
- /** reestablish a complete IKE_SA */
+ /** reestablish a complete IKE_SA, break-before-make */
TASK_IKE_REAUTH,
+ /** completion task for make-before-break IKE_SA re-authentication */
+ TASK_IKE_REAUTH_COMPLETE,
/** delete an IKE_SA */
TASK_IKE_DELETE,
/** liveness check */
diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c
index 7e55d6b0f..d6ff3c8c5 100644
--- a/src/libcharon/sa/trap_manager.c
+++ b/src/libcharon/sa/trap_manager.c
@@ -65,6 +65,11 @@ struct private_trap_manager_t {
* listener to track acquiring IKE_SAs
*/
trap_listener_t listener;
+
+ /**
+ * Whether to ignore traffic selectors from acquires
+ */
+ bool ignore_acquire_ts;
};
/**
@@ -171,7 +176,7 @@ METHOD(trap_manager_t, install, u_int32_t,
this->lock->unlock(this->lock);
/* create and route CHILD_SA */
- child_sa = child_sa_create(me, other, child, reqid, FALSE);
+ child_sa = child_sa_create(me, other, child, reqid, FALSE, 0, 0);
list = linked_list_create_with_items(me, NULL);
my_ts = child->get_traffic_selectors(child, TRUE, NULL, list);
@@ -353,7 +358,7 @@ METHOD(trap_manager_t, acquire, void,
{
ike_sa->set_peer_cfg(ike_sa, peer);
}
- if (ike_sa->get_version(ike_sa) == IKEV1)
+ if (this->ignore_acquire_ts || ike_sa->get_version(ike_sa) == IKEV1)
{ /* in IKEv1, don't prepend the acquiring packet TS, as we only
* have a single TS that we can establish in a Quick Mode. */
src = dst = NULL;
@@ -484,6 +489,8 @@ trap_manager_t *trap_manager_create(void)
},
.traps = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .ignore_acquire_ts = lib->settings->get_bool(lib->settings,
+ "%s.ignore_acquire_ts", FALSE, lib->ns),
);
charon->bus->add_listener(charon->bus, &this->listener.listener);
diff --git a/src/libcharon/tests/Makefile.am b/src/libcharon/tests/Makefile.am
new file mode 100644
index 000000000..c8be28594
--- /dev/null
+++ b/src/libcharon/tests/Makefile.am
@@ -0,0 +1,21 @@
+TESTS = libcharon_tests
+
+check_PROGRAMS = $(TESTS)
+
+libcharon_tests_SOURCES = \
+ suites/test_mem_pool.c \
+ libcharon_tests.h libcharon_tests.c
+
+libcharon_tests_CFLAGS = \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ @COVERAGE_CFLAGS@
+
+libcharon_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+libcharon_tests_LDADD = \
+ $(top_builddir)/src/libcharon/libcharon.la \
+ $(top_builddir)/src/libhydra/libhydra.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
diff --git a/src/libcharon/tests/Makefile.in b/src/libcharon/tests/Makefile.in
new file mode 100644
index 000000000..7f4f4b24e
--- /dev/null
+++ b/src/libcharon/tests/Makefile.in
@@ -0,0 +1,874 @@
+# 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 = libcharon_tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = src/libcharon/tests
+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__EXEEXT_1 = libcharon_tests$(EXEEXT)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_libcharon_tests_OBJECTS = \
+ suites/libcharon_tests-test_mem_pool.$(OBJEXT) \
+ libcharon_tests-libcharon_tests.$(OBJEXT)
+libcharon_tests_OBJECTS = $(am_libcharon_tests_OBJECTS)
+libcharon_tests_DEPENDENCIES = \
+ $(top_builddir)/src/libcharon/libcharon.la \
+ $(top_builddir)/src/libhydra/libhydra.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
+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 =
+libcharon_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libcharon_tests_CFLAGS) $(CFLAGS) $(libcharon_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 = $(libcharon_tests_SOURCES)
+DIST_SOURCES = $(libcharon_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_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@
+libcharon_tests_SOURCES = \
+ suites/test_mem_pool.c \
+ libcharon_tests.h libcharon_tests.c
+
+libcharon_tests_CFLAGS = \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ @COVERAGE_CFLAGS@
+
+libcharon_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+libcharon_tests_LDADD = \
+ $(top_builddir)/src/libcharon/libcharon.la \
+ $(top_builddir)/src/libhydra/libhydra.la \
+ $(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/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/tests/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-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/libcharon_tests-test_mem_pool.$(OBJEXT): \
+ suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+
+libcharon_tests$(EXEEXT): $(libcharon_tests_OBJECTS) $(libcharon_tests_DEPENDENCIES) $(EXTRA_libcharon_tests_DEPENDENCIES)
+ @rm -f libcharon_tests$(EXEEXT)
+ $(AM_V_CCLD)$(libcharon_tests_LINK) $(libcharon_tests_OBJECTS) $(libcharon_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)/libcharon_tests-libcharon_tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libcharon_tests-test_mem_pool.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 $@ $<
+
+suites/libcharon_tests-test_mem_pool.o: suites/test_mem_pool.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT suites/libcharon_tests-test_mem_pool.o -MD -MP -MF suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo -c -o suites/libcharon_tests-test_mem_pool.o `test -f 'suites/test_mem_pool.c' || echo '$(srcdir)/'`suites/test_mem_pool.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_mem_pool.c' object='suites/libcharon_tests-test_mem_pool.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) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o suites/libcharon_tests-test_mem_pool.o `test -f 'suites/test_mem_pool.c' || echo '$(srcdir)/'`suites/test_mem_pool.c
+
+suites/libcharon_tests-test_mem_pool.obj: suites/test_mem_pool.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT suites/libcharon_tests-test_mem_pool.obj -MD -MP -MF suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo -c -o suites/libcharon_tests-test_mem_pool.obj `if test -f 'suites/test_mem_pool.c'; then $(CYGPATH_W) 'suites/test_mem_pool.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mem_pool.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_mem_pool.c' object='suites/libcharon_tests-test_mem_pool.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) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o suites/libcharon_tests-test_mem_pool.obj `if test -f 'suites/test_mem_pool.c'; then $(CYGPATH_W) 'suites/test_mem_pool.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mem_pool.c'; fi`
+
+libcharon_tests-libcharon_tests.o: libcharon_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT libcharon_tests-libcharon_tests.o -MD -MP -MF $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo -c -o libcharon_tests-libcharon_tests.o `test -f 'libcharon_tests.c' || echo '$(srcdir)/'`libcharon_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo $(DEPDIR)/libcharon_tests-libcharon_tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libcharon_tests.c' object='libcharon_tests-libcharon_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) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o libcharon_tests-libcharon_tests.o `test -f 'libcharon_tests.c' || echo '$(srcdir)/'`libcharon_tests.c
+
+libcharon_tests-libcharon_tests.obj: libcharon_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT libcharon_tests-libcharon_tests.obj -MD -MP -MF $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo -c -o libcharon_tests-libcharon_tests.obj `if test -f 'libcharon_tests.c'; then $(CYGPATH_W) 'libcharon_tests.c'; else $(CYGPATH_W) '$(srcdir)/libcharon_tests.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo $(DEPDIR)/libcharon_tests-libcharon_tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libcharon_tests.c' object='libcharon_tests-libcharon_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) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o libcharon_tests-libcharon_tests.obj `if test -f 'libcharon_tests.c'; then $(CYGPATH_W) 'libcharon_tests.c'; else $(CYGPATH_W) '$(srcdir)/libcharon_tests.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
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -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 \
+ 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-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:
+
+.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 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-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
+
+
+# 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/tests/libcharon_tests.c b/src/libcharon/tests/libcharon_tests.c
new file mode 100644
index 000000000..1ed0f0c95
--- /dev/null
+++ b/src/libcharon/tests/libcharon_tests.c
@@ -0,0 +1,56 @@
+/*
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <test_runner.h>
+#include <hydra.h>
+#include <daemon.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#define TEST_SUITE_DEPEND(x, ...) TEST_SUITE(x)
+#include "libcharon_tests.h"
+#undef TEST_SUITE
+#undef TEST_SUITE_DEPEND
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+ { .suite = x, },
+#define TEST_SUITE_DEPEND(x, type, args) \
+ { .suite = x, .feature = PLUGIN_DEPENDS(type, args) },
+#include "libcharon_tests.h"
+ { .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+ if (init)
+ {
+ libhydra_init();
+ libcharon_init();
+ }
+ else
+ {
+ lib->processor->set_threads(lib->processor, 0);
+ lib->processor->cancel(lib->processor);
+ libcharon_deinit();
+ libhydra_deinit();
+ }
+ return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_runner_run("libcharon", tests, test_runner_init);
+}
diff --git a/src/libcharon/tests/libcharon_tests.h b/src/libcharon/tests/libcharon_tests.h
new file mode 100644
index 000000000..dc9681aeb
--- /dev/null
+++ b/src/libcharon/tests/libcharon_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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+TEST_SUITE(mem_pool_suite_create)
diff --git a/src/libcharon/tests/suites/test_mem_pool.c b/src/libcharon/tests/suites/test_mem_pool.c
new file mode 100644
index 000000000..4204d4bab
--- /dev/null
+++ b/src/libcharon/tests/suites/test_mem_pool.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <attributes/mem_pool.h>
+
+static void assert_host(char *expected, host_t *host)
+{
+ if (!expected)
+ {
+ ck_assert_msg(!host, "not epxecting IP != %+H", host);
+ }
+ else
+ {
+ host_t *verifier;
+ verifier = host_create_from_string(expected, 0);
+ ck_assert_msg(host, "expected IP %+H != NULL", verifier);
+ ck_assert_msg(verifier->ip_equals(verifier, host), "expected IP %+H != "
+ "%+H", verifier, host);;
+ verifier->destroy(verifier);
+ }
+}
+
+static void assert_acquire(mem_pool_t *pool, char *requested, char *expected,
+ mem_pool_op_t operation)
+{
+ identification_t *id;
+ host_t *req, *acquired;
+
+ id = identification_create_from_string("tester");
+ req = host_create_from_string(requested, 0);
+
+ acquired = pool->acquire_address(pool, id, req, operation, NULL);
+ assert_host(expected, acquired);
+ DESTROY_IF(acquired);
+
+ req->destroy(req);
+ id->destroy(id);
+}
+
+static void assert_acquires_new(mem_pool_t *pool, char *pattern, int first)
+{
+ char expected[16];
+ int i;
+
+ for (i = 0; i < pool->get_size(pool); i++)
+ {
+ snprintf(expected, sizeof(expected), pattern, first + i);
+ assert_acquire(pool, "0.0.0.0", expected, MEM_POOL_NEW);
+ ck_assert_int_eq(i + 1, pool->get_online(pool));
+ }
+ assert_acquire(pool, "0.0.0.0", NULL, MEM_POOL_NEW);
+}
+
+START_TEST(test_config)
+{
+ mem_pool_t *pool;
+
+ pool = mem_pool_create("test", NULL, 0);
+ ck_assert_int_eq(0, pool->get_size(pool));
+ assert_acquire(pool, "192.168.0.1", "192.168.0.1", MEM_POOL_NEW);
+ assert_acquire(pool, "10.0.1.1", "10.0.1.1", MEM_POOL_NEW);
+ assert_acquire(pool, "0.0.0.0", "0.0.0.0", MEM_POOL_NEW);
+ assert_acquire(pool, "255.255.255.255", "255.255.255.255", MEM_POOL_NEW);
+ ck_assert_int_eq(0, pool->get_online(pool));
+ pool->destroy(pool);
+}
+END_TEST
+
+START_TEST(test_cidr)
+{
+ mem_pool_t *pool;
+ host_t *base;
+
+ base = host_create_from_string("192.168.0.0", 0);
+
+ pool = mem_pool_create("test", base, 32);
+ ck_assert_int_eq(1, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 0);
+ pool->destroy(pool);
+
+ pool = mem_pool_create("test", base, 31);
+ ck_assert_int_eq(2, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 0);
+ pool->destroy(pool);
+
+ pool = mem_pool_create("test", base, 30);
+ ck_assert_int_eq(2, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 1);
+ pool->destroy(pool);
+
+ pool = mem_pool_create("test", base, 29);
+ ck_assert_int_eq(6, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 1);
+ pool->destroy(pool);
+
+ pool = mem_pool_create("test", base, 24);
+ ck_assert_int_eq(254, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 1);
+ pool->destroy(pool);
+
+ base->destroy(base);
+}
+END_TEST
+
+START_TEST(test_cidr_offset)
+{
+ mem_pool_t *pool;
+ host_t *base;
+
+ base = host_create_from_string("192.168.0.1", 0);
+ pool = mem_pool_create("test", base, 31);
+ ck_assert_int_eq(1, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 1);
+ pool->destroy(pool);
+
+ pool = mem_pool_create("test", base, 30);
+ ck_assert_int_eq(2, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 1);
+ pool->destroy(pool);
+ base->destroy(base);
+
+ base = host_create_from_string("192.168.0.2", 0);
+ pool = mem_pool_create("test", base, 30);
+ ck_assert_int_eq(1, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 2);
+ pool->destroy(pool);
+
+ pool = mem_pool_create("test", base, 24);
+ ck_assert_int_eq(253, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 2);
+ pool->destroy(pool);
+ base->destroy(base);
+
+ base = host_create_from_string("192.168.0.254", 0);
+ pool = mem_pool_create("test", base, 24);
+ ck_assert_int_eq(1, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 254);
+ pool->destroy(pool);
+ base->destroy(base);
+
+ /* due to size == 0 we get the requested IP back */
+ base = host_create_from_string("192.168.0.255", 0);
+ pool = mem_pool_create("test", base, 24);
+ ck_assert_int_eq(0, pool->get_size(pool));
+ assert_acquire(pool, "192.168.0.1", "192.168.0.1", MEM_POOL_NEW);
+ pool->destroy(pool);
+
+ base->destroy(base);
+}
+END_TEST
+
+START_TEST(test_range)
+{
+ mem_pool_t *pool;
+ host_t *from, *to;
+
+ from = host_create_from_string("192.168.0.0", 0);
+ to = host_create_from_string("192.168.0.0", 0);
+ pool = mem_pool_create_range("test", from, to);
+ ck_assert_int_eq(1, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 0);
+ pool->destroy(pool);
+
+ to->destroy(to);
+ to = host_create_from_string("192.168.0.1", 0);
+ pool = mem_pool_create_range("test", from, to);
+ ck_assert_int_eq(2, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 0);
+ pool->destroy(pool);
+
+ from->destroy(from);
+ from = host_create_from_string("192.168.0.10", 0);
+ pool = mem_pool_create_range("test", from, to);
+ ck_assert(!pool);
+
+ to->destroy(to);
+ to = host_create_from_string("192.168.0.20", 0);
+ pool = mem_pool_create_range("test", from, to);
+ ck_assert_int_eq(11, pool->get_size(pool));
+ assert_acquires_new(pool, "192.168.0.%d", 10);
+ pool->destroy(pool);
+
+ from->destroy(from);
+ from = host_create_from_string("fec::1", 0);
+ to->destroy(to);
+ to = host_create_from_string("fed::1", 0);
+ pool = mem_pool_create_range("test", from, to);
+ ck_assert(!pool);
+
+ from->destroy(from);
+ to->destroy(to);
+}
+END_TEST
+
+Suite *mem_pool_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("mem_pool");
+
+ tc = tcase_create("%config-like pool");
+ tcase_add_test(tc, test_config);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("cidr constructor");
+ tcase_add_test(tc, test_cidr);
+ tcase_add_test(tc, test_cidr_offset);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("range constructor");
+ tcase_add_test(tc, test_range);
+ suite_add_tcase(s, tc);
+
+ return s;
+}